为了真正理解单纯形算法的具体步骤,我查阅了许多文章,不过大部分文章会直接叙述单纯形表的操作,对理解算法帮助有限;也有一些文章直接从线性代数上的原理开始叙述,对于非专业人士又太难了。所幸我找到了一个挺不错的在线课程,感觉是我看过叙述单纯形算法最明了直观的资料了,下面的内容主要就是对这个课程的翻译
初始可行解
我们直接就用个例子来叙述算法。还是上一篇的例子:
m a x Z = 40 x 1 + 50 x 2 s . t . x 1 + 2 x 2 ≤ 40 4 x 1 + 3 x 2 ≤ 120 x 1 , x 2 ≥ 0 \begin{aligned} max\quad& Z=40x_1+50x_2\\ s.t.\quad& x_1+2x_2\leq40 \\ & 4x_1+3x_2\leq120 \\ & x_1,x_2\geq0 \end{aligned} maxs.t.Z=40x1+50x2x1+2x2≤404x1+3x2≤120x1,x2≥0
把它松弛化:
m a x Z = 40 x 1 + 50 x 2 s . t . x 1 + 2 x 2 + s 1 = 40 4 x 1 + 3 x 2 + s 2 = 120 x 1 , x 2 , s 1 , s 2 ≥ 0 \begin{aligned} max\quad& Z=40x_1+50x_2\\ s.t.\quad& x_1+2x_2+s_1=40 \\ & 4x_1+3x_2+s_2=120 \\ & x_1,x_2,s_1,s_2\geq0 \end{aligned} maxs.t.Z=40x1+50x2x1+2x2+s1=404x1+3x2+s2=120x1,x2,s1,s2≥0
在上一篇文章中我是以分块矩阵的形式来表现基变量和非基变量,这里我们有更加直观和简单的方法:把约束方程组中的基变量统一移到等式左侧,非基变量统一移到等式右侧,而目标则通过消元操作用非基变量表示:
m a x Z = 40 x 1 + 50 x 2 s . t . s 1 = 40 − x 1 − 2 x 2 s 2 = 120 − 4 x 1 − 3 x 2 x 1 , x 2 , s 1 , s 2 ≥ 0 \begin{aligned} max\quad& Z=40x_1+50x_2\\ s.t.\quad& s_1=40-x_1-2x_2 \\ & s_2=120-4x_1-3x_2 \\ & x_1,x_2,s_1,s_2\geq0 \end{aligned} maxs.t.Z=40x1+50x2s1=40−x1−2x2s2=120−4x1−3x2x1,x2,s1,s2≥0
然后令非基变量 x 1 = x 2 = 0 x_1=x_2=0 x1=x2=0,则各个基变量则等于各个约束中的常数项,即 s 1 = 40 , s 2 = 120 s_1=40,s_2=120 s1=40,s2=120,目标值 Z = 0 Z=0 Z=0,我们得到一个初始的可行解
x = [ x 1 x 2 s 1 s 2 ] = [ 0 0 40 120 ] \boldsymbol{x}= \begin{bmatrix} x_1\\ x_2\\ s_1\\ s_2 \end{bmatrix}= \begin{bmatrix} 0\\ 0\\ 40\\ 120 \end{bmatrix} x=⎣⎢⎢⎡x1x2s1s2⎦⎥⎥⎤=⎣⎢⎢⎡0040120⎦⎥⎥⎤
解的转移
有了初始可行解,就可以开始整个算法的迭代过程,每次迭代需要有基变量的出基和非基变量的入基。
首先需要选择一个要变成基变量的非基变量,这里我们必须要选择在约束中系数为负数的变量,在这个例子中,我们可以选择变量 x 1 x_1 x1,它在两个约束等式中的系数都是负数:
为什么一定要系数为负数? 因为如果是正数,把它移到等式左侧进行规整时等式两边就需要除以一个负数,那么最终约束等式中将存在负数常数项,无法得到可行解。
我们选择了 x 1 x_1 x