引言
这个代码较为简单易懂,并且每一步几乎都有详细的注释,适合初学者,请放心阅读。
该matlab代码解决的是标准线性规划下的极大值问题,当然,如果你要解决的是极小值问题,稍加修改就ok了。
完整代码
function [x_opt,fx_opt,iter] = simplex(A,b,c)
% 单纯形法求解标准形线性规划问题: max cx s.t. Ax=b x>=0
% x_opt,fx_opt,iter(最优解、最优函数值、迭代次数)
format rat %元素使用分数表示
[m,n] = size(A); %m约束条件个数, n决策变量数
v=nchoosek(1:n,m);
for i=1:size(v,1)
if A(:,v(i,:))==eye(m)
ind_B=v(i,:);
end
end %这几步主要是为了在系数矩阵中随机选取几列,每一次都判断是否为单位矩阵(基矩阵),并得到基矩阵的列索引
ind_N = setdiff(1:n, ind_B); %非基变量的索引,原理是返回在1:n中出现而不在ind_B即基变量索引中出现的元素,并从小到大排序
ST = [];
iter=0; %记录迭代次数
% 循环求解
while true
x0 = zeros(n,1);
x0(ind_B) = b; %初始基可行解,令基变量的位置为方程组右边系数,非基变量取值为0
cB = c(ind_B); %计算cB,即目标函数在基变量处对应的系数
Sigma = zeros(1,n); %Sigma为检验数向量
Sigma(ind_N) = c(ind_N) - cB*A(:,ind_N); %计算检验数(非基变量),因为基变量对应的初始检验数一定为0
[~, k] = max(Sigma); %选出最大检验数, 确定进基变量索引k;~表示忽略第一个参数(即最大值),k是索引
Theta = b ./ A(:,k); %计算θ(点除,即矩阵中对应元素相除,得到一个新的矩阵)
Theta(Theta<=0) = 10000;
[~, q] = min(Theta); %选出最小θ
el = ind_B(q); %确定出基变量在系数矩阵中的列索引el, 主元为A(q,k)
vals = [cB',ind_B',b,A,Theta];
vals = [vals; NaN, NaN, NaN, Sigma, NaN];
ST = [ST; vals];
disp(ST);
if ~any(Sigma > 0) %所有检验数都小于0,此基可行解为最优解, any表示存在某个检验数>0
x_opt = x0;
fx_opt = c * x_opt; %算出最优解
return
end
if all(A(:,k) <= 0) %表示检验数这一列每个数都<=0,有无界解
x_opt = [];
break
end
% 换基
ind_B(ind_B == el) = k; %新的基变量索引
ind_N = setdiff(1:n, ind_B); %非基变量索引
% 更新A和b
A(:,ind_N) = A(:,ind_B) \ A(:,ind_N); %基矩阵的逆乘以非基矩阵
b = A(:,ind_B) \ b; %基矩阵的逆乘以b
A(:,ind_B) = eye(m,m); %基矩阵更新为单位矩阵
iter=iter+1;
end
end
如果觉得还不错的话,请给博主点个赞再走,谢谢~