运筹学——matlab实现单纯形法

引言

这个代码较为简单易懂,并且每一步几乎都有详细的注释,适合初学者,请放心阅读。
该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

如果觉得还不错的话,请给博主点个赞再走,谢谢~

  • 27
    点赞
  • 85
    收藏
    觉得还不错? 一键收藏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值