本文主要介绍采用单纯形表解决线性规划问题(LP),将单纯形表中的数据看作矩阵,并将多个矩阵合并找到进基变量和离基变量,从而得到主元,并利用主元做初等行变换,并通过检验数判断是否达到最优解。
matlab用户定义的函数:
1、B=RowChange(A,m,n)
2、C=check_num(A,c,X)
3、[xo,yo]=SimpleForm(A,B,C,c,X)
1、从可行域的一个顶点(基本可行解)开始,转移到另一个顶点(另一个基本可行解);
2、转移的条件是使得目标函数值得到改善;
3、当目标函数达到最优时,也就得到了最优解。
为方便运算,采用的是单纯形表的方式去解决线性规划问题。
如上图所示,需对红蓝两个矩阵以主元②做初等行变换,使得:
1、主元所在行归一化
2、主元所在列其他对应元素为0
即可得到下一个顶点(基本可行解)对应的矩阵。
本文利用matlab可以轻易对矩阵做初等行变换的特点设计的单纯形法算法。
1、将主元所在行归一化
2、除主元所在行将外的其他行利用主元行,做初等行变换,使得主元所在列的其他元素为0。
function B=RowChange(A,m,n)
%关于矩阵行初等变换的函数
% A 是初始矩阵,[m,n] 是主元的位置
% B 是变换后的矩阵
a=A(m,n); % a 是主元
D=double(A(m,:)/a);
[M,N]=size(A);
for k=1:M
A(k,:)=A(k,:)-A(k,n)*D;%通过初等变换使主元同列的元素为0
end
A(m,:)=D;%主元同一行归一化
B=A;
具体实例:
取A(2,2)为主元
A=[1 2 3;4 5 6;7 8 9]
B=RowChange(A,2,2)
function C=check_num(A,c,X)
%该函数用于获取检验数C
% A 为约束方程系数;c 为价值系数;X 为存放基变量下标的矩阵
[M,N]=size(A);
C=zeros(1,N);
CB=[c(X(1))];
B=[A(:,X(1))];
for k=2:M
CB=[CB,c(X(k))];
B=[B,A(:,X(k))];
end
for k=1:N
C(1,k)=CB*inv(B)*A(:,k)-c(1,k);
end
for k=1:M
C(1,X(k))=0;
end
具体实例:
A=[-1,1,-1;-1,-1,-1]
c=[2,2,0]
X=[1;2]
C=check_num(A,c,X)
注意单纯形法的性质:基本可行解与可行域的顶点一一对应,至多有
故在设立标志位flag,并运用到matlab中排列组合函数nchoosek(N,M)
function [xo,yo]=SimpleForm(A,B,C,c,X)
%关于单纯形法的函数
% A 是约束方程的系数矩阵,大小为 [M,N];B 为约束方程右端的常数,大小为 [M,1];
% C 是检验数,大小为 [1,N];X 为存放基变量下标的矩阵,c 为价值系数.
[M,N]=size(A);
xo=zeros(N,1);
flag=1
while flag<=nchoosek(N,M)
A=[A,B];
C=[C,0];
D=[A;C];
[num1,n]=max(C);
in=n
theta=B./A(:,n);
for k=1:M
if theta(k,1)<0 |(theta==0 & A(:,n)<0)
theta(k,1)=theta(k,1)+Inf;
end
end
[num2,m]=min(theta);
out=X(m,1)
X(m,1)=n;
D=RowChange(D,m,n)
A=D(1:M,1:N);
B=D(1:M,N+1);
C=D(M+1,1:N);
[num1,n]=max(C);
if num1<=0
break;
end
flag=flag+1
end
if flag==nchoosek(N,M)+1
fprintf('该规划问题无界')
xo=Inf;
yo=Inf;
else
for k=1:M
xo(X(k,1))=B(k,1);
end
yo=c*xo;
end
end
具体实例1:
%test1
A=[1,4,1,0;2,3,0,1];
B=[80;90];
c=[-9,-16,0,0];
C=[9,16,0,0];
X=[3;4];
[xo,yo]=SimpleForm(A,B,C,c,X)
由上运行结果可知:迭代次数flag=2。第一次迭代进基变量为x2,离基变量为x3.第二次迭代进基变量为x1,离基变量为x4。当x=xo时,达到最优解yo。
具体实例2:
A=[1,1,1,0,1,0,0;4,-1,1,2,0,1,0;-1,1,2,3,0,0,1];
B=[4;6;12];
c=[3,-5,-2,-1,0,0,0];
X=[5;6;7];
C=check_num(A,c,X);
[xo,yo]=SimpleForm(A,B,C,c,X)
由上运行结果可知:迭代次数flag=2。第一次迭代进基变量为x2,离基变量为x5.第二次迭代进基变量为x4,离基变量为x7。当x=xo时,达到最优解yo。
具体实例3:
A=[-1,1,-1;-1,-1,-1];
B=[1;2];
c=[2,2,0];
X=[1;2];
C=check_num(A,c,X);
[xo,yo]=SimpleForm(A,B,C,c,X)