prompt="请输入矩阵A:"; %约束矩阵A min cx
A=input(prompt); % s.t. Ax≦b
prompt="请输入矩阵B(形式为1×n列矩阵):"; %矩阵b
B=input(prompt);
prompt="请输入矩阵C:"; %系数矩阵c
C=input(prompt);
[~,n]=size(C); %获得变量个数n
[m,~]=size(A); %获得松弛变量个数m
D=eye(m); %松弛变量单位矩阵
A=[A,D]; %原A矩阵拼接松弛变量矩阵得到可变换运算的矩阵A
D=zeros(1,m);
C=[C,D]; %原C矩阵拼接零矩阵得到可变换运算的矩阵C
[k1,k2,key]=simplex(A,B,C); %k1为最优解基变量,k2为最优解矩阵B,key为最优值
f=zeros(1,n); %以下为规范输出形式部分
[~,k]=size(k1);
for i=1:k
f(1,k1(i))=k2(i);
end
fprintf('此时已是最优,最优解为:( ');
for i=1:n
fprintf('%.3f',f(1,i));
if(i~=n)
fprintf(' , ')
end
end
fprintf(' ),最优值f(min)=%.3f\n',key);
function [Base_var,B,key] = simplex(A,B,C) % Base_var为基矩阵
T=[A,B]; %将矩阵A与C合并 便于计算
[row,col]=size(T); %获得合并后矩阵的行数与列数
Base_var=col-row:col-1; %获得基矩阵
C_b=C(Base_var); %计算w=C_b C_b为C与基矩阵的乘积
Z=C_b*T; %计算zj=w*pj
J_n=Z(1:1,1:col-1)-C; %计算判别数z-c 此判别数去掉末尾的函数值f(分裂矩阵Z)
Judge_num=J_n;
Judge_num(col)=C_b*B; %计算此时函数值f并加到判别数矩阵末尾 得到运算使用的判别数矩阵Judge_num
k=1; %记录变换次数k
while max(J_n)>0 %判断不含函数值f的判别数矩阵的最大值是否大于0,大于0进行基变换
fprintf('进行第%d轮变换\n',k);
k=k+1;
[~,col_swap]=max(J_n); %获得最大值的基变量下标col_swap
for i=1:row %计算B矩阵与col_swap列的比值矩阵merchant
if(T(i,col_swap)>0)
merchant(i)=T(i,col)/T(i,col_swap);
else
merchant(i)=10^6;
end
end
[~,row_swap]=min(merchant); %获得merchant最小值的下标,即需进行基变换的行row_swap
temp=T(row_swap,col_swap); %确定主元temp
fprintf('主元为 第%d行,第%d列 %.3f ,进行主元消去\n',row_swap,col_swap,T(row_swap,col_swap));
for i=1:col %进行主元消去 先对主元所在的行除以主元使主元变为1
T(row_swap,i)=T(row_swap,i)/temp;
end
for i=1:row %对主元所在的列进行消去
if(i~=row_swap)
temp=T(i,col_swap);
for j=1:col
T(i,j)=T(i,j)-temp*T(row_swap,j);
end
end
end
temp=Judge_num(col_swap); %对判别式矩阵进行主元消去
for i=1:col
Judge_num(i)=Judge_num(i)-temp*T(row_swap,i);
end
fprintf('新的单纯性表为:\n'); %输出新的单纯性表
for i=1:row
for j=1:col
fprintf('%.3f ',T(i,j));
end
fprintf('\n');
end
for i=1:col
fprintf('%.3f ',Judge_num(i));
end
fprintf('\n\n');
Base_var(row_swap)=col_swap; %更新基变量矩阵
J_n=Judge_num(1:1,1:col-1); %更新不含函数值f的判别式矩阵(对Judge_num进行分裂)
end
B=T(1:row,col:col); %分裂T获得最优解矩阵B
key=Judge_num(col); %获得最优值
end
【最优化理论与算法】单纯形法(matlab)
最新推荐文章于 2024-03-15 15:54:18 发布