用C++实现的简单单纯形解法
使用单纯型法来求解线性规划,输入单纯型法的松弛形式,是一个大矩阵,第一行为目标函数的系数,且最后一个数字为当前轴值下的 z 值。下面每一行代表一个约束,数字代表系数每行最后一个数字代表 b 值。
算法和使用单纯性表求解线性规划相同。
对于线性规划问题:
Max x1 + 14* x2 + 6*x3
s . t . x1 + x2 + x3 <= 4
x1<= 2
x3 <= 3
3*x2 + x3 <= 6
x1,x2,x3 >= 0
我们可以得到其松弛形式:
Maxx1 + 14*x2 + 6*x3
s.t. x1 + x2 + x3 + x4 = 4
x1 + x5 = 2
x3 + x6 = 3
3*x2 + x3 + x7 = 6
x1 , x2 , x3 , x4 , x5 , x6 , x7 ≥ 0
我们可以构造单纯性表,其中最后一行打星的列为轴值。
x1 | x2 | x3 | x4 | x5 | x6 | x7 | b |
c1=1 | c2=14 | c3=6 | c4=0 | c5=0 | c6=0 | c7=0 | -z=0 |
1 | 1 | 1 | 1 | 0 | 0 | 0 | 4 |
1 | 0 | 0 | 0 | 1 | 0 | 0 | 2 |
0 | 0 | 1 | 0 | 0 | 1 | 0 | 3 |
0 | 3 | 1 | 0 | 0 | 0 | 1 | 6 |
* | * | * | * |
在单纯性表中,我们发现非轴值的x上的系数大于零,因此可以通过增加这些个x的值,来使目标函数增加。我们可以贪心的选择最大的c,再上面的例子中我们选择c2作为新的轴,加入轴集合中,那么谁该出轴呢?
其实我们由于每个x都大于零,对于x2它的增加是有所限制的,如果x2过大,由于其他的限制条件,就会使得其他的x小于零,于是我们应该让x2一直增大,直到有一个其他的x刚好等于0为止,那么这个x就被换出轴。
我们可以发现,对于约束方程1,即第一行约束,x2最大可以为4(4/1),对于约束方程4,x2最大可以为3(6/3),因此x2最大只能为他们之间最小的那个,这样才能保证每个x都大于零。因此使用第4行,来对各行进行高斯行变换,使得二列第四行中的每个x都变成零,也包括c2。这样我们就完成了把x2入轴,x7出轴的过程。变换后的单纯性表为:
x1 | x2 | x3 | x4 | x5 | x6 | x7 | b |
c1=1 | c2=0 | c3=1.33 | c4=0 | c5=0 | c6=0 | c7=-4.67 | -z=-28 |
1 | 0 | 0.67 | 1 | 0 | 0 | -0.33 | 2 |
1 | 0 | 0 | 0 | 1 | 0 | 0 | 2 |
0 | 0 | 1 | 0 | 0 | 1 | 0 | 3 |
0 | 1 | 0.33 | 0 | 0 | 0 | 0.33 | 2 |
* | * | * | * |
继续计算,我们得到:
x1 | x2 | x3 | x4 | x5 | x6 | x7 | b |
c1=-1 |
上一篇: 用C++编程实现对偶单纯形解题法