规划问题(单纯形法,非线性规划,以及罚函数的引入)

首先不得不感叹一句学科的交叉性,上个星期刚刚从vrp问题中了解到单纯形法和罚函数,最近就在数学建模的书上看到规划问题的求解(早点看到就好啦....)

   规划问题分为线性规划问题和非线性规划问题,线性规划问题目前用单纯形法可以很好的解决,而非线性规划问题则没有很好的解法,根据实际问题具体分析(从编程的角度我采用过动态规划,搜索,分支限定法,以及计算智能中的相关算法)。

  什么是线性规划问题,例:

maxz=60x+20y                       目标函数

4x+2y<=16                          约束条件

0.5x+y>=3.5                        约束条件 

x,y>0                     约束条件


注意到其中的目标函数和约束条件皆为线性函数(次方为1,一条直线),这种问题称为线性规划问题。

单纯形法的步骤:

 1,首先将不等式转化为等式。

  2,建立初始单纯形表。

 3,找出主元(先计算检验数,找到最大的检验数,再以这一列为主列,用b/主列的元素,得到的最小值的那一行为主行,主列与主行的交接处为主元)

 4,主行除以主元,同时ci为检验数,将xi变为主列所对应的那个xj

 5,进行相应的初等行变换(目的是是使每一行只有一个1就是那个xi的解)

 6, 计算检验数,当检验数有大于0的就返回第3步

下面提供一个迭代次数较少的题目:

maxz=3x1+4x2

2x1+x2<=40

x1+3x2<=30

x1,x2>=0

题目及答案链接:点击打开链接

答案是x1=18,x2=4


相信算完这道题的人会感觉到数学深深的恶意~~

让我们看看用matlab怎么处理这道题

>> c=[3;4];
>> a=[2,1;1,3];
>> b=[40;30];
>> [x,y]=linprog(-c,a,b,[],[],zeros(2,1))

 结果:

x =

   18.0000
    4.0000


y =

  -70.0000

注意x1=18,x2=4,而y的值应该是取相反数的(接下来会说明为什么)

这里用到一个函数

[x,fval]=linprog(c,A,b,Aeq,beq,LB,UB,X0,OPTIONS) 其中fval返回目标函数的值,Aeq是等式约束的左边,beq是等式的右边,LB和UB是变量x的上下界(可为[]),X0是x的初始值

同时注意matlab默认的形式是

minz=....

...<...

....<....

所以一旦目标函数不是求最大值,有两种办法:1,系数直接全部为负数2,函数的c为负数(注意两个只能选一个.....)

就好比上文中的

[x,y]=linprog(-c,a,b,[],[],zeros(2,1))

这里c就是因为最大值

所以也可以这样写

>> c=[-3;-4];
>> a=[2,1;1,3];
>> b=[40,30];
>> [x,y]=linprog(c,a,b,[],[],zeros(2,1))

另外约束条件为大于等于则两边取负数也同样有两种方法1,系数全部为负数2,函数相应的为负数(这里倒是推荐第一种,因为a是左边的所有不等式,只有所有不等式为大于等于才能为取负号)

minz=2x1+3x2+x3

x1+4x2+2x3>=8

3x1+2x2>=6

x1,x2,x3>=0

>> c=[2;3;1];
>> a=[-1,-4,-2;-3,-2,0];
>> b=[-8;-6];
>> [x,y]=linprog(c,a,b,[],[],zeros(3,1))%这里zeros(3,1)就是代表lb=(0;0;0)也就是下界
注意a是代表左边的系数的行列式,所以要补齐0

而如果约束条件中有等式,也有两种方法1,分别写成》=和《=2,用Aeq和beq

maxz=2x1+3x2-5x3

x1+x2+x3=7

2x1-5x2+x3>=10

x1,x2,x3>=0

第一种:

>> c=[-2;-3;5];
>> a=[1,1,1;-1,-1,-1;-2,5,-1];
>>  b=[7;-7;-10];
>> [x,y]=linprog(c,a,b,[],[],zeros(3,1))

第二种:

>> c=[2;3;-5];
>> a=[-2,5,-1];
>> b=-10;
>> aeq=[1,1,1];
>> beq=7;
>> x=linprog(-c,a,b,aeq,beq,zeros(3,1))
>> value=c'*x


非线性规划

minz=x1^2+x2^2+8

x1^2-x2>=0

-x1-x2^2+2=0

x1,x2>=0

fun1.m

function f=fun1(x);
f=x(1)^2+x(2)^2+8;

fun2.m

function[g,h]=fun2(x);
g=-x(1)^2+x(2);
h=-x(1)-x(2)^2+2;

在窗口输入:

>> options=optimset;
>>  [x,y]=fmincon('fun1',rand(2,1),[],[],[],[],zeros(2,1),[],'fun2',options)

结果为x1=1,x2=1最小值为10

罚函数的介绍:

M为足够大的正数, 起"惩罚"作用, 称之为罚因子, F(x, M )称为罚函数.

简单来说就是在函数中一旦发现不可行解,就将其估值调节的特别差,直接被丢弃,比如在遗传算法中一旦发现染色体不合格,就标记该条染色体,在评估时加入较大的因子使其被淘汰。

例如:

minz=x1^2+x2^2+8

x1^2-x2>=0

-x1-x2^2+2=0

x1,x2>=0

test.m

function g=test(x);
M=50000;
f=x(1)^2+x(2)^2+8;
g=f-M*min(x(1),0)-M*min(x(2),0)-M*min(x(1)^2-x(2),0)+M*abs(-x(1)-x(2)^2+2);

命令行输入:

 [x,y]=fminunc('test',rand(2,1))


结尾祝我生快~~


                                           








你可能感兴趣的:(规划问题(单纯形法,非线性规划,以及罚函数的引入))