【运筹优化 OR】 单纯形法 思想与代码实现 Simplex Method

【运筹优化 OR】单纯形法 Simplex Method

 

更多运筹学相关:https://github.com/Amoiensis/Operational-Research

                         运筹优化 - Operational Research - Github

注意未经允许,请勿转载!

           转载请标明出处~

适用课程:运筹学

 

   代码1: 调用部分

(文件名:Simplex_method_main.m)

%测试 Simplex_Method 函数
%%
% Author: Amoiensis
% Email: [email protected]
% Data: 2019.10.01
clear;clc;
%%
% Import Data %
%无穷多最优解%
% A = [...
%     1	1	1	1   0	0	0;
%     -2	1	-1	0	-1	1	0;
%     0	3	1	0	0	0	1;...
%     ];
% b = [4  1   9]';
% C = [-3	0	1	0	0	-100  -1];

A = [...
    1	1	1	1	0	0	0
    1	0	0	0	1	0	0
    0	0	1	0	0	1	0
    0	3	1	0	0	0	1;...
    ];
b = [4 2 3 6]';
C = [1 14 6 0 0 0 0];

% %可行解无界%
% A = [...
%     4	0	1....
%     ];
% b = [16]';
% C = [2 3 0];

[~,~,RESULT] = Simplex_method_f(A,b,C);

代码2:主体实现部分 (函数文件)

(文件名:Simplex_method_f.m)

function [max_value,result,PRINT] = Simplex_method_f(A,b,C)
% Simplex Method 单纯形法求解标准线性规划模型
%   传入变量A、b、C 求解最优决策/最优值/最终单纯形表
%%
% Author: Amoiensis
% Email: [email protected]
% Data: 2019.10.01
%%
% Structure(Program Simplex_Method)%
%    max CX
% s.t. AX = b
%      X >= 0
% Program to solve the liner-program atomatically
%%
% 数据基础操作 %
Size_A = size(A);
deta = zeros(1,Size_A(2));    %最优性判别
sita_arry = zeros(1,Size_A(1));    
sita = 0;   %sita值
Coef = zeros(1,Size_A(1));    %系数值
Base = zeros(1,Size_A(1));  %选择的基
Decsion = b;%zeros(1,Size_A(1));%决策取值

END_deta = ones(1,Size_A(2));   %使用deta值标定程序结束
ZEROS_ceofA = zeros(Size_A(1),1);   %用来判断所求解,无界

FLAG = 0;   %用于跳出循环;0-正常//1-唯一解(11)or无穷多解(12)//2-无界解//3-无可行解
Step = 1;
PUTOUT_R = "<>C_B   //  基   //  b  //   x_1~x_n";
PUTOUT_C = " <> x_1~x_m   //  deta";
%%
%Operation
%STEP 1 单纯形表实现%
 while 1
    %找到单位矩阵
    if Size_A(1) == 1
        Position(find(A == 1)) = 1;
    else
        Position = ((sum(A) == 1)&(min(A) == 0));
    end
    index_I = zeros(1,Size_A(1));
    for i=1:Size_A(2)
       if  Position(i) 
           [~,temp] = max(A(:,i));
           index_I(temp) = i;
       end
    end

    Base = index_I;
    Coef = C(index_I);

    %寻找,最大检验数/deta值 和 sita值
    % 这一步是先deta最大,再sita最大?这里是否有优化空间?
    %deta
    for i=1:Size_A(2)
        deta(i) = C(i) - (Coef)*A(:,i);
    end
    [temp_deta,Position_in] = max(deta);    %找到换入位置
    
    %%%%%%%%%%%%%%
    %打印单纯形表%
    PRINT = zeros(1+Size_A(1),3+Size_A(2));
    PRINT(1,1:3+Size_A(2)) =  [nan(1,3),C];
    PRINT(2:end,1) =  Coef';
    PRINT(2:end,2) =  Base';
    PRINT(2:end,3) =  Decsion;
    PRINT(2:end,4:3+Size_A(2)) = A;
    PRINT(end+1,4:3+Size_A(2)) = deta;
    PRINT(end,1:3) = [nan nan nan];
    disp(strcat("步骤:",num2str(Step)));
    disp(PUTOUT_C);
    disp(PUTOUT_R);
    disp(PRINT);
    %%%%%%%%%%%%%%
    Step = Step+1;
    %%%%%%%%%%%%%%
    %sita
    sita_arry = Decsion./A(:,Position_in);
    Size_sita_arry = size(sita_arry);
    for i=1:Size_sita_arry(1)
        if sita_arry(i)<=0
            sita_arry(i) = nan;
        end
    end
    % 这里需要注意,先挑选出人工变量;
    [sita,Position_out] = min(sita_arry);
    
    for i=1:Size_sita_arry(1)
        if sita_arry(i) == sita
               Base(Position_out) < Base(i);
               Position_out = i;
        end
    end

    %程序结束条件%
    

    %无界解

        if sita == inf
            FLAG = 2;
            break;
        end
    
    %正常求解-唯一解or无穷多解%
    if isequal(deta<=0,END_deta)
        FLAG = 1;
        break;
    end

    %行初等变换
    Decsion(Position_out) = Decsion(Position_out)/temp_num;
    A(Position_out,:) = A(Position_out,:)/temp_num;
    for i=1:Size_A(1)
       if i~=Position_out
            Decsion(i) = Decsion(i)- A(i,Position_in)*Decsion(Position_out);
            A(i,:) = A(i,:)- A(i,Position_in)*A(Position_out,:);
       end
    end
end

%STEP 2 结果检验%
%分为:唯一最优解、无穷多最优解、无界解、无可行解
Result = zeros(1,Size_A(2));
Result(Base) = Coef;
if FLAG == 1
    temp_tell = deta == 0;
    for i=1:Size_A(2)
        if deta(i)==0 && sum((sita>0))
             FLAG = 12;   %无穷多
             break;
        end
    end
    if FLAG ==12
        disp("该线性规划问题,存在“无穷多”最优解.");
        disp("其中一个,最优解决策为:(x1~xn)");
        disp(Result);
        disp("最优目标函数值为:");
        disp(Coef*Decsion);
    else
        disp("该线性规划问题,存在唯一最优解.");
        disp("最优解决策为:(x1~xn)");
        disp(Result);
        disp("最优目标函数值为:");
        disp(Coef*Decsion);
    end
   
else
    if FLAG == 2
        disp("该线性规划问题,其解无界(无限大).");
    else
        if FLAG == 3
            disp("该线性规划问题,无可行解.");
        end
    end
end
%%
% 结果返回 %
result = Result;
max_value = Coef*Decsion;
end

 

你可能感兴趣的:(运筹优化,OR)