单纯形方法(SimplexMethod)
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
单纯形⽅法(SimplexMethod)
最近在上最优理论这门课,刚开始是线性规划部分,主要的⽅法就是单纯形⽅法,学完之后做了⼀下⼤M算法和分段法的仿真,拿出来与⼤家分享⼀下。
单纯形⽅法是求解线性规划问题的⼀种基本⽅法。
线性规划就是在⼀系列不等式约束下求⽬标函数最⼤值或最⼩值的问题,要把数学中的线性规划问题⽤计算机来解决,⾸先要确定⼀个标准形式。
将所给的线性规划问题化为标准形式:
s.t.是英⽂subject to 的简写,意思是受约束,也就是说第⼀个⽅程受到后⾯两个⽅程的约束。
对于求最⼤值问题可以将⽬标函数加负号转换为最⼩值问题。
对于求最⼤值问题可以将⽬标函数加负号转换为最⼩值问题。
其他的问题就是将实际问题中的不等式约束改为等式约束,主要⽅法是引进松弛变量和剩余变量,以及将⾃有变量转换为⾮负变量。
①对于不等式,引⼊松弛变量将其变为等式形式如下:
②对于不等式,引⼊剩余变量将其变为等式形式如下:
③若变量为⾃有变量(可取正、负或零,符号⽆限制),则引⼊两个⾮负变量将其表⽰如下:
关于线性规划问题的解:
确定了标准形式,我们就针对这个标准形式讨论⼀下线性规划问题的解。
线性规划问题的解能满⾜标准形式中约束条件的向量X的值,但只有最优解才能使⽬标函数值最⼩。
对于上⽂中的标准形式,约束矩阵A是⼀个m*n维矩阵,且m<n,所以⼀定可以从A中找到⼀个满秩m*m矩阵。
这个矩阵就称作矩阵A的⼀个基阵,矩阵A就可以写作 [B N] , 相应的解 x 也可以写成 x=(xB,xN)’,那么 Ax=b 就变为,左式两端同乘B矩阵的逆,得到。
由此引出下列名词:
基阵:⾮奇异矩阵(满秩矩阵、可逆矩阵)B
基向量:基阵B由m个线性⽆关的向量组成,称之为基向量
基变量:向量xB各分量,与基向量对应的xB中的m个分量成为基变量
⾮基变量:向量xN各分量
基本解:令xN各分量为0,由得到的解称为基阵B对应的基本解
基本可⾏解:当成⽴时,称基本解为基本可⾏解,因为只有满⾜所有分量不⼩于0,才符合标准形式中的约束条件(最后⼀条)。
单纯形表
如上图所⽰,在做单纯形表时,我们要找到这么⼀个满秩矩阵B,⽽且要通过⾏变换把它化为单位阵,同时把这个单位阵上⽅对应的向量c中元素变为0。
也就是说,在标准的单纯形表中,在表的第⼀⾏中,基变量对应的元素全为0,⾮基变量对应的元素称之为检验数。
这时便找到了此问题的⼀个基本可⾏解,此时单纯形表最右边⼀列的各数从上到下为此基本解对应的⽬标函数值f和基本解的基变量的值b’(⾮基变量为0)。
举个例⼦:
S X1(⾮基变量)X2(⾮基变量)X3X4X5
f5(检验数)10(检验数)0000(⽬标函数值)
X31/141/71001(基变量X3值)
X41/71/120101(基变量X4值)
X5110018(基变量X5值)
这是⼀个已经变换好的单纯形表,红⾊部分是b’,也就是此时基本可⾏解中基变量分别为X3,X4,X5,他们的值分别为1,1,8,对应的基本可⾏解就是(0,0,1,1,8)。
可以看出,此时⽬标函数值为0。
单纯形⽅法基本步骤:
初始的单纯形表已经给出了线性规划问题的⼀个基本可⾏解,接下来要做的就是判断这个解是否是最优解,如果是的话不⽤继续找啦,如果不是的话就找⼀个⽐这个解更好的解,再进⾏判断,直到找到最优解。
但有的问题是没有最优解的,所以还要判定问题是否⽆解。
1)将所给的线性规划问题化为标准形式。
2)找出⼀个初始的基阵B,作出单纯形表,作为程序的输⼊(A,C,f,b’)。
否则转⾄4)。
3)测试所有的检验数,记录检验数中的正数,若全部⼩于等于0,则已经找到最优解,计算终⽌。
否则转⾄
否则转⾄5)。
4)测试所有为正的检验数,若在单纯性表中,其所在的列中其他元素全部⼩于等于0,则此问题⽆最优解,计算终⽌,否则转⾄
5)找出检验数中的最⼤值,此最⼤值元素所在列为A(i,:),令约束条件中约束向量b与A(i,:)的⽐值为向量r,向量r中为正的最⼩值为h,计算过程如下图。
S单纯形表X1X2X3X4X5
0000
f510(最⼤
值)
X31/141/71001
X41/71/120101
X5110018
表格中黄⾊部分组成的向量点除(对应元素相除)红⾊部分,得到向量(7,12,8),那么7就是我们要找的那个元素,此时记录元素⼤⼩h和坐标(i,j),注意是在S表中⾏号和列号,此处是2和2(如果有多个相等的最⼩值则任取⼀个即可)。
换基。
步骤如下:
这个元素1/7就是所谓的转轴元(或称基本元),找到他之后要围绕他进⾏⼀系列的⾏变换,称之为换基
①使转轴元变为1,⽅法很简单,就是让本⾏所有元素同时除以转轴元1/7。
②把转轴元所在列的其他元素都变为0,做法是通过⼀个循环,遍历每⼀个⾏(⾃⾝所在⾏除外),每⾏中与转轴元同列的元素为a,令每⾏
转⾄3)。
减去转轴元所在⾏的第a倍即可。
转⾄
理论部分到此为⽌,如有疏漏欢迎留⾔(参考书⽬为黄平的《最优化理论》)
matlab仿真程序编写:
Simplex.m
%Simplex Method
function [x,y]=Simplex(f,A,b)
%输⼊f是检验数的数组,1*n维
%输⼊A是约束矩阵, m*n维
%输⼊b是约束向量,1*m维
%输出x是解向量
%输出y是最优解
%判断输⼊维数是否相符
%做初始单纯形表
format rat %将结果以分数表⽰
S=[f 0;A b'];
[n,m]=size(S);
%判断检验数 r<=0
r=find(f>0);
len=length(r);
%有⼤于0的检验数则进⼊循环
while(len)
%检查⾮负检验数所对列向量元素是否都⼩于等于0
for k=1:length(r)
d=find(S(:,r(k))>0);
if(length(d)+1==2)
error('⽆最优解')
%break;
end
end
%找到检验数中最⼤值
[Rk,j]=max(S(1,1:m-1));
%b与最⼤值所在列的⽐值
rb=S(2:n,m)./S(2:n,j);
%把⽐值中的负数都变⽆穷
for p=1:length(rb)
if(rb(p)<0)
rb(p)=Inf;
end
end
[h,i]=min(rb);%列向量⽐值最⼩值
% i+1为转轴元⾏号(在S中),j为转轴元列号
i=i+1;
%进⾏换基,转轴元置1
S(i,:)=S(i,:)./S(i,j);
%转轴元所在列其他元素都置0
for k=1:n
if(k~=i)
S(k,:)=S(k,:)-S(i,:)*S(k,j);
end
end
%判断检验数 r<=0
r=find(S(1,1:m-1)>0);
len=length(r);
end
%检验数全部⾮正,找到最优解
%⾮基变量置0
x=zeros(1,m-1);
for i=1:m-1
%找到基变量
j=find(S(:,i)==1);%每列中1的个数
k=find(S(:,i)==0);%每列中0的个数if((length(j)+1==2)&&(length(k)+1==n)) %i为基本元列号,j是⾏号
x(i)=S(j,m);
end
end
y=S(1,m);%最优解
S
end
下⾯附带⼀个测试程序(test.m):clear all
clc
f=[43000];
A=[11100;
12010;
32001];
b=[5080140];
[x,y]=Simplex(f,A,b)
f=[1100];
A=[-2110;
1 -101];
b=[42];
[x,y]=Simplex(f,A,b)
仿真结果如下:。