【最优化理论与算法】单纯形法(matlab)

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

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值