我一直在做线性规划问题,在我的班级通过以图表他们,但我想知道如何编写一个程序来解决这个问题对我来说是特别的问题。 如果有太多的变量或限制,我不可能通过以图表形式做到这一点。
实施例的问题,最大化5X + 3Y与约束:
- 5倍 - 2Y> = 0
- X + Y <= 7
- X <= 5
- X> = 0
- Y> = 0
我绘制这一点,得到了明显的区域有3角。 X = 5 Y = 2是最佳点。
我怎么变成这个代码? 我知道单纯形法。 而且很重要的是,将全部LP问题,在相同结构的编码? 将蛮力的工作?
我一直在做线性规划问题,在我的班级通过以图表他们,但我想知道如何编写一个程序来解决这个问题对我来说是特别的问题。 如果有太多的变量或限制,我不可能通过以图表形式做到这一点。
实施例的问题,最大化5X + 3Y与约束:
我绘制这一点,得到了明显的区域有3角。 X = 5 Y = 2是最佳点。
我怎么变成这个代码? 我知道单纯形法。 而且很重要的是,将全部LP问题,在相同结构的编码? 将蛮力的工作?
有相当数量的单纯实现的,如果你搜索,你会发现。
除了在注释(数字食谱在C)提到的,你还可以发现:
为了解决您的另外两个问题:
将所有的LP进行编码以同样的方式? 是的,一个普通的LP求解器可以被写入装载和解决任何LP。 (有行业标准格式读取LP的像mps
和.lp
将蛮力的工作? 请记住,许多公司和大机构花微调求解很长一段时间。 有LP的有有趣的特性,很多求解器将尝试利用。 另外,某些计算可并行地解决。 该算法是指数,因此在一些大量的变量/约束,蛮力将无法正常工作。
希望帮助。
这个是我写的matlab昨天,这可以很容易地转录成C ++,如果您使用本征库或使用STD的一个std ::向量写自己的矩阵类::矢量
function [x, fval] = mySimplex(fun, A, B, lb, up)
%Examples paramters to show that the function actually works
% sample set 1 (works for this data set)
% fun = [8 10 7];
% A = [1 3 2; 1 5 1];
% B = [10; 8];
% lb = [0; 0; 0];
% ub = [inf; inf; inf];
% sample set 2 (works for this data set)
fun = [7 8 10];
A = [2 3 2; 1 1 2];
B = [1000; 800];
lb = [0; 0; 0];
ub = [inf; inf; inf];
% generate a new slack variable for every row of A
numSlackVars = size(A,1); % need a new slack variables for every row of A
% Set up tableau to store algorithm data
tableau = [A; -fun];
tableau = [tableau, eye(numSlackVars + 1)];
lastCol = [B;0];
tableau = [tableau, lastCol];
% for convienience sake, assign the following:
numRows = size(tableau,1);
numCols = size(tableau,2);
% do simplex algorithm
% step 0: find num of negative entries in bottom row of tableau
numNeg = 0; % the number of negative entries in bottom row
for i=1:numCols
if(tableau(numRows,i) < 0)
numNeg = numNeg + 1;
end
end
% Remark: the number of negatives is exactly the number of iterations needed in the
% simplex algorithm
for iterations = 1:numNeg
% step 1: find minimum value in last row
minVal = 10000; % some big number
minCol = 1; % start by assuming min value is the first element
for i=1:numCols
if(tableau(numRows, i) < minVal)
minVal = tableau(size(tableau,1), i);
minCol = i; % update the index corresponding to the min element
end
end
% step 2: Find corresponding ratio vector in pivot column
vectorRatio = zeros(numRows -1, 1);
for i=1:(numRows-1) % the size of ratio vector is numCols - 1
vectorRatio(i, 1) = tableau(i, numCols) ./ tableau(i, minCol);
end
% step 3: Determine pivot element by finding minimum element in vector
% ratio
minVal = 10000; % some big number
minRatio = 1; % holds the element with the minimum ratio
for i=1:numRows-1
if(vectorRatio(i,1) < minVal)
minVal = vectorRatio(i,1);
minRatio = i;
end
end
% step 4: assign pivot element
pivotElement = tableau(minRatio, minCol);
% step 5: perform pivot operation on tableau around the pivot element
tableau(minRatio, :) = tableau(minRatio, :) * (1/pivotElement);
% step 6: perform pivot operation on rows (not including last row)
for i=1:size(vectorRatio,1)+1 % do last row last
if(i ~= minRatio) % we skip over the minRatio'th element of the tableau here
tableau(i, :) = -tableau(i,minCol)*tableau(minRatio, :) + tableau(i,:);
end
end
end
% Now we can interpret the algo tableau
numVars = size(A,2); % the number of cols of A is the number of variables
x = zeros(size(size(tableau,1), 1)); % for efficiency
% Check for basicity
for col=1:numVars
count_zero = 0;
count_one = 0;
for row = 1:size(tableau,1)
if(tableau(row,col) < 1e-2)
count_zero = count_zero + 1;
elseif(tableau(row,col) - 1 < 1e-2)
count_one = count_one + 1;
stored_row = row; % we store this (like in memory) column for later use
end
end
if(count_zero == (size(tableau,1) -1) && count_one == 1) % this is the case where it is basic
x(col,1) = tableau(stored_row, numCols);
else
x(col,1) = 0; % this is the base where it is not basic
end
end
% find function optimal value at optimal solution
fval = x(1,1) * fun(1,1); % just needed for logic to work here
for i=2:numVars
fval = fval + x(i,1) * fun(1,i);
end
end