首先不得不感叹一句学科的交叉性,上个星期刚刚从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
这里用到一个函数
[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))
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;
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)
罚函数的介绍:
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))
结尾祝我生快~~