单纯形算法 matlab 代码实现
Posted 向日葵吃了你的脑子
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了单纯形算法 matlab 代码实现相关的知识,希望对你有一定的参考价值。
单纯形算法思路:
从一个基础可行解开始,迭代搜索下一个基础可行解,直到找到最优解
单纯形算法函数
function [xValue, fValue, iterNum] = simplex_method(A, b, c, isMinValue)
% 输出参数:
% xValue : 最优解向量
% fValue : 最优解
% iterNum : 迭代次数
% 输入参数:
% A : 限制条件的系数
% b : 限制条件的常数项
% c : 目标函数的系数
% isMinValue : 目标函数是否是求最小值 0(求最大值) 1(求最小值)
iterNum = 0;
flag = 0;
xValue = [];
fValue = inf;
if isMinValue == 0
c = -c; % 如果是求函数最大值,则系数取反
end
[m, n] = size(A);
% 获取基底, 并计算对应的基本解
r = nchoosek(1:n, m);
for ii = 1 : size(r, 1)
B = A(:, r(ii, :));
bIdx = r(ii, :);
if rank(B) == m
xB = B\\b;
if min(xB(:)) < 0
flag = 2;
continue;
else
flag = 0;
break;
end
end
end
if flag == 2
disp('无基本可行解');
return;
end
x = zeros(n, 1);
x(bIdx) = xB;
while true
iterNum = iterNum + 1;
B = A(:, bIdx);
cB = c(bIdx);
r = c' - cB' * (B \\ A);
if all(r >= 0)
xValue = x;
fValue = c' * x;
if isMinValue == 0
fValue = -fValue;
end
disp('迭代结束,找到最优解');
break;
end
% 计算进基分量下标
rMin = min(r(:));
rMinIdx = find(r == rMin);
% 计算迭代方向
d = zeros(n, 1);
d(rMinIdx) = 1;
d(bIdx) = -B\\A(:, rMinIdx);
% 计算步长和离基分量下标
if all(d(bIdx) >= 0)
disp('当前问题无界, 无最优解');
break;
else
stepVector = -x(bIdx)' ./ d(bIdx);
step = min(stepVector(d(bIdx) < 0));
offBaseIdx = bIdx(stepVector == step); % 离基分量下标
end
bIdx(bIdx == offBaseIdx) = rMinIdx;
% nIdx(nIdx == rMinIdx) = offBaseIdx;
x = x + step .* d;
if iterNum > 100000
disp('出错,请检查输出参数后重试');
break;
end
end
end
测试程序main
A = [1 1 1 -1; -1 2 -4 1];
c = [1 -3 2 1]';
b = [6, 9]';
[x, f, iter] = simplex_method(A, b, c, 1);
总结
花了两个小时,总算写完了,算法思想很简单,代码也不复杂,希望 100 天之后再看能够知道这是个怎么一回事;
以上是关于单纯形算法 matlab 代码实现的主要内容,如果未能解决你的问题,请参考以下文章
优化求解基于matlab单纯形表算法求解线性规划(LP)问题含Matlab源码 1540期