简单易懂的单纯形法理解

简单易懂的单纯形法理解


\qquad 从学线性规划开始一直觉得单纯形是一种奇奇怪怪不知所云的方法 (居然还好意思叫simplex,我觉得叫complex才对), 上课老师讲到的一大堆性质定理的证明也让人晕头转向,最后还是死记硬背下了单纯形表的解法勉强应付过了作业。直到今天小班课助教讲了他学到的对于单纯形的理解,才觉得豁然开朗,原来单纯形的确是这么“单纯”。和图解法结合起来也更加清晰直观地看到了单纯形法的工作过程,分享出来希望也能够帮助大家更好地理解。我们 不需要任何定理公式

推荐阅读本文方法:自己在纸上把文中单纯形表和图像画出来,对照着进行学习。

\qquad 需要读者关于线性规划标准形的一些最基本的概念,如基变量,基本可行解等,如果不了解可先学习一下标准形,在此不对概念做赘述。以及知道单纯形的大概思路(先确定一组基本可行解,然后通过各种操作使得目标函数的值不断下降,最终得到最优解

\qquad 我们以《算法设计与分析(第2版)》上的例子来进行讲解

m a x z = 12 x + 15 y s . t . 0.25 x + 0.50 y   ≤ 120    0.50 x + 0.50 y   ≤ 150 0.25 x ≤ 50 x ≥ 0 , y ≥ 0 max \qquad z=12x+15y\\ s.t.\quad 0.25x+0.50y\ \leq120\\ \qquad \;0.50x+0.50y\ \leq150\\\qquad0.25x\qquad\qquad\leq50\\x\geq0,\quad y\geq0 maxz=12x+15ys.t.0.25x+0.50y 1200.50x+0.50y 1500.25x50x0,y0
画出的图像如图所示
简单易懂的单纯形法理解_第1张图片
\qquad 这是最简单的情形,所有的约束条件都为小于等于,我们可以直接通过引入松弛变量来化为标准形,即:
m i n − z = − 12 x 1 − 15 x 2 s . t . 0.25 x 1 + 0.50 x 2 + x 3   = 120    0.50 x 1 + 0.50 x 2 + x 4   = 150 0.25 x 1    + x 5 = 50 x j ≥ 0 , j = 1 , 2 , . . . , 5 min \qquad -z=-12x_{1}-15x_{2}\\ s.t.\quad 0.25x_{1}+0.50x_{2}+x_{3}\ =120\\ \qquad \;0.50x_{1}+0.50x_{2}+x_{4}\ =150\\\qquad0.25x_{1}\qquad\quad\quad\;+x_{5}=50\\x_{j}\geq0,\quad j=1,2,...,5 minz=12x115x2s.t.0.25x1+0.50x2+x3 =1200.50x1+0.50x2+x4 =1500.25x1+x5=50xj0,j=1,2,...,5

\qquad 单纯形的第一步是找出一组初始可行基,对于我们题目中这种约束条件全为小于等于的版本,我们只需取三个松弛变量作为初始可行基即可。

我们画出单纯形表(简化版)如下所示

x B x_{B} xB b b b x 1 x 2 x 3 x 4 x 5 x_{1}\qquad\qquad x_{2}\qquad\qquad x_{3}\qquad\qquad x_{4}\qquad\qquad x_{5} x1x2x3x4x5 θ \theta θ
x 3 x_{3} x3 120 0.25 0.50 1 0 0 0.25 \qquad \qquad0.50\qquad\qquad1\qquad\qquad0\qquad\qquad0\quad 0.250.50100 240
x 4 x_{4} x4 150 0.50 0.50 0 1 0 0.50 \qquad \qquad0.50\qquad\qquad0\qquad\qquad1\qquad\qquad0\quad 0.500.50010 300
x 5 x_{5} x5 50 0.25 0 0 0 1 0.25 \qquad \qquad0\qquad\qquad\quad0\qquad\qquad0\qquad\qquad1\quad 0.250001
− z -z z 0 − 12    − 15    0 0 0 -12 \qquad \ \ \quad-15\ \ \qquad\qquad0\qquad\qquad0\qquad\qquad0\quad 12  15  000

\qquad 让我们首先理解这个单纯形表表示的是什么意思。先抛开   θ    \ \theta\;  θ列不看,只看前面的几列。 x B x_{B} xB列表示的是我们当前选取的基变量,而    b    \;b\; b列和    x    \;x\; x列合起来就是我们目前线性规划的约束条件,最下面一行是我们当前的目标函数,由于我们目前选择的初始可行解为{0,0,120,150,50},所以初始目标函数值为0。相信到这里大家都是能够理解的。

\qquad 接下来就开始我们的优化,我们的目的是想让目标函数的值降低,而现在影响目标函数的变量有 x 1 和 x 2 x_{1} 和 x_{2} x1x2两个变量增大均能够使得目标函数减小,我们先选择其中的一个来达成我们的第一步。注意到, x 1 x_{1} x1每增加1会使得    − z    \;-z\; z减小12,而 x 2 x_{2} x2每增加1会使得    − z    \;-z\; z减小15。我们希望目标函数减小的越快越好,所以这里我们选择 x 2 x_{2} x2进行增大,用单纯形的术语来说就是让 x 2 x_{2} x2作为换入变量,使它成为可行基。

\qquad 我们当然希望目标函数越小越好,那么我们的 x 2 x_{2} x2自然是越大越好,但是它不能无限制地增大下去,因为我们有约束条件(三个等式,以及非负条件)。那么我们考察一下 x 2 x_{2} x2最多能增大多少呢?含有 x 2 x_{2} x2的等式限制是前两个: 0.25 x 1 + 0.50 x 2 + x 3   = 120    0.50 x 1 + 0.50 x 2 + x 4   = 150 \qquad 0.25x_{1}+0.50x_{2}+x_{3}\ =120\\ \qquad \;0.50x_{1}+0.50x_{2}+x_{4}\ =150 0.25x1+0.50x2+x3 =1200.50x1+0.50x2+x4 =150由于它们是等式条件,所以如果想要 x 2 x_{2} x2增大,必须有相应变量减小来维持等式条件成立,由于非负条件的限制,两式中能减小的只能分别是 x 3 x_{3} x3 x 4 x_{4} x4了( x 1 = 0 x_{1}=0 x1=0)。
\qquad 现在 x 3 x_{3} x3 x 4 x_{4} x4的值均为1,要让 x 2 x_{2} x2增加到最大就要让它们减小到0。让 x 3 x_{3} x3减小到0可以使 x 2 x_{2} x2增大到 1 ∗ 120 / 0.50 = 240 1*120/0.50=240 1120/0.50=240,而让 x 4 x_{4} x4减小到0可以使 x 2 x_{2} x2增大到 1 ∗ 150 / 0.50 = 300 1*150/0.50=300 1150/0.50=300。有没有发现,这就是我们的    θ    \;\theta\; θ那一列的值?注意这里有一个比较容易迷惑的点。 有些同学可能会想,我们想让 x 2 x_{2} x2越大越好,那这里300更大是不是能增大到300?这样思考是不对的。要知道,这两个等式是约束条件,是需要都满足的,如果我们选取了300那么第一个等式就不能满足了。从这个角度思考,这里我们其实应该选择的是    θ    \;\theta\; θ的最小值,也即让 x 3 x_{3} x3减小到0,用单纯形的术语来讲就是选择 x 3 x_{3} x3作为换出变量

\qquad 现在,我们尽管没有提到变量替换这样的概念,但我们已经选好了所谓的换入变量换出变量。这时候,我们的解向量变成了{0,240,0,1,0},并且 − z -z z的值变成了 − 15 ∗ 240 = − 3600 -15*240=-3600 15240=3600(根据之前说的 x 2 x_{2} x2每增大1就会让 − z -z z减小15)。因为 x 2 x_{2} x2此时已经不能再增加了,我们也在约束条件中想办法把它的影响减到最小,即只保留用到的等式约束中的 x 2 x_{2} x2并把它单位化,把其余的等式约束中消去 x 2 x_{2} x2。这一步通过行列变换可以很容易得到,化简后的等式约束变为:
   0.50 x 1 + x 2 + 2 x 3   = 240 0.50 x 1 − x 3 + x 4   = 30    0.25 x 1    + x 5 = 50 \quad\; 0.50x_{1}+x_{2}+2x_{3}\ =240\\ \quad0.50x_{1}-x_{3}+x_{4}\ =30\\\qquad\;0.25x_{1}\qquad\quad\quad\;+x_{5}=50 0.50x1+x2+2x3 =2400.50x1x3+x4 =300.25x1+x5=50

同时,由于约束条件的改变,我们目标函数的形式也应该相应地进行改变。此时 − z -z z的初值为-3600,解向量为{0,240,0,1,0}。考察现在各变量对于目标函数的影响。当 x 1 x_{1} x1增大1,目标函数会减小12;但同时,为了满足第一个等式约束, x 2 x_{2} x2的值也需要发生相应变化,即当 x 1 x_{1} x1增大1, x 2 x_{2} x2的值需要减小0.5,从而使目标函数增大 − 15 ∗ 0.5 ∗ ( − 1 ) = 7.5 -15*0.5*(-1)=7.5 150.5(1)=7.5。综合来看引起的变化可以得到,当 x 1 x_{1} x1增加1,会使得目标函数的值改变 − 12 + 7.5 = − 4.5 -12+7.5=-4.5 12+7.5=4.5 x 1 x_{1} x1新的系数为-4.5。同理对于 x 3 x_{3} x3,当 x 3 x_{3} x3增大时本来对目标函数影响是0,但是每当 x 3 x_{3} x3增大1,为了满足第一个等式,需要让 x 2 x_{2} x2减小2,从而使目标函数改变 − 15 ∗ 2 ∗ ( − 1 ) = 30 -15*2*(-1)=30 152(1)=30,即 x 3 x_{3} x3系数为30。即 − z = − 3600 − 4.5 x 1 + 30 x 3 -z=-3600-4.5x_{1}+30x_{3} z=36004.5x1+30x3。如果仔细观察,我们可以惊奇地发现,这几个系数在表中的得出过程与上面改变约束时的行列变换做法 完 全 一 致,即把对应列( x 2 x_{2} x2)消成0,这样我们得到一个更加简便的计算“新目标函数”的方法。

\qquad 到这里,有些同学可能会提出疑问:为什么 x 2 x_{2} x2 x 4 x_{4} x4 x 5 x_{5} x5的系数是0呢?或者是:为什么我们考虑 x 1 x_{1} x1增大时只考虑了对 x 2 x_{2} x2的影响而没有考虑对 x 3 x_{3} x3 x 4 x_{4} x4 x 5 x_{5} x5的影响呢?这就涉及到我们对于换出的理解了。事实上,从一开始的目标函数中, x 1 x_{1} x1的系数-12就不只是增大1个单位 x 1 x_{1} x1的影响,而是增大1个 x 1 x_{1} x1,减小0.25个 x 3 x_{3} x3,减小0.5个 x 4 x_{4} x4,减小0.25个 x 5 x_{5} x5收益,这才是我们系数的真正含义,其他变量的系数也是同理。当我们进行完第一步的单纯形变换后,由于我们的消元,后两个等式中都没有 x 2 x_{2} x2,故换入换出的比例关系不受到影响,所以我们只需要考虑第一个等式中的关系。同时,我们系数的含义是“增加1单位的 x j x_{j} xj,同时加上对其他变量的影响,一共对目标函数结果的影响”,而 x 2 x_{2} x2此时已经不能再增大了,自然也就没有系数了。这样我们就完全解释了所有系数的来历,也体会出了我们行列变换消元的重要性所在。

现在,我们已经基本完成了下一步的单纯形表的求解(除    θ    \;\theta\; θ列以外),如下:

x B x_{B} xB b b b x 1 x 2 x 3 x 4 x 5 x_{1}\qquad\qquad x_{2}\qquad\qquad x_{3}\qquad\qquad x_{4}\qquad\qquad x_{5} x1x2x3x4x5 θ \theta θ
x 2 x_{2} x2 240 0.50 1 2 0 0 0.50 \qquad \qquad1\qquad\qquad2\qquad\qquad0\qquad\qquad0\quad 0.501200 480
x 4 x_{4} x4 30 0.25 0 − 1 1 0 0.25 \qquad \qquad0\quad\qquad-1\qquad\qquad1\qquad\qquad0\quad 0.250110 120
x 5 x_{5} x5 50 0.25 0 0 0 1 0.25 \qquad \qquad0\quad\qquad\quad0\qquad\qquad0\qquad\qquad1\quad 0.250001 200
− z -z z 3600 − 4.5    0    30 0 0 -4.5 \qquad \ \ \quad0\ \ \qquad\qquad30\qquad\qquad0\qquad\qquad0\quad 4.5  0  3000

总结一下变换的大体思路:先找出能让目标函数减小的变量(换入变量),然后找出对应的最严格的约束条件(换出变量),替换后将原变量约束的影响降到最低(单位化,消元),最后得到新的目标函数。

从图像上来看,我们让 x 2 x_{2} x2变到了可能的最大值,即目标函数如图所示:
简单易懂的单纯形法理解_第2张图片
\qquad 从图上我们显然可以看到这并不是最优解,最优解应当经过B点,即让直线向右移,即让 x 1 x_{1} x1增大,那么我们从单纯形表中是不是也能得出同样的结论呢?让我们一起继续来看。

\qquad 有了第一次单纯形变换的经验,我们很容易同样地进行第二步。首先选择能让目标函数减小的变量,这里只有 x 1 x_{1} x1可以了,即为换入变量。然后算出 x 1 x_{1} x1在约束的情况下能变化多少,即 b b b列除以 x 1 x_{1} x1列算出    θ    \;\theta\; θ,选取其中最小的一个(必要的约束条件),这里是第二行120,则第二行对应的 x B x_{B} xB x 4 x_{4} x4换出变量。然后我们对于 x 1 x_{1} x1列,把第二个等式单位化,第一三个等式对应行和下面的目标函数行列变换消元,得到新的单纯形表:

x B x_{B} xB b b b x 1 x 2 x 3 x 4 x 5 x_{1}\qquad\qquad x_{2}\qquad\qquad x_{3}\qquad\qquad x_{4}\qquad\qquad x_{5} x1x2x3x4x5 θ \theta θ
x 2 x_{2} x2 240 0 1 4 − 2 0 0 \qquad \qquad1\qquad\qquad4\qquad\qquad-2\qquad\qquad0\quad 01420
x 1 x_{1} x1 30 1 0 − 4 4 0 1 \qquad \qquad0\quad\qquad\quad-4\qquad\qquad4\qquad\qquad0\quad 10440
x 5 x_{5} x5 50 0 0 1 − 1 1 0 \qquad \qquad0\quad\qquad\quad1\qquad\qquad-1\qquad\qquad1\quad 00111
− z -z z 4140 0    0    12 18 0 0 \qquad \ \ \quad0\ \ \qquad\qquad12\qquad\qquad18\qquad\qquad0\quad 0  0  12180

对应的图像为:
简单易懂的单纯形法理解_第3张图片
可以观察到图像和单纯形表完全对应,图像的虚线向右移动,即 x 1 x_{1} x1增大了。从图像可以看到,我们已经得到了最优解,那么从单纯形表中看如何呢?

我们在最后一行看现在的“新目标函数”, − z = − 4140 + 12 x 3 + 18 x 4 -z=-4140+12x_{3}+18x_{4} z=4140+12x3+18x4,此时两个变量的增大均会使 − z -z z减小,即术语所说的所有的检验数都大于等于零,达到了最优解。与图像完全符合!

总结

通过上面的详细分析,原来单纯形法并不只是课堂上一大堆让人听见就犯困的定理的证明,其实它的本质是选择某一个未达到最优的方向(即所谓非基变量),让它增大到这个变量的最优(图像上另一个顶点),通过这样不断地变换自然可以最终达到最优的那个顶点。抛开数学的部分,它其实还是很朴素的一样方法。一点感悟就是从设计者的思想来学习(从算法思路到概念引入到正确性证明)要比一上来就给出一大堆不知所云的定理要强得多,对于我们不专门搞理论算法的人来说也完全够用了 (够期末考试用了)
最后特别感谢我的算分小班助教GAREN,之前虽然不是完全死记方法但也只有很浅薄的理解,因为他的讲解让我有了对整个算法系统性的理解。希望大家也能从此文获益!

你可能感兴趣的:(算法设计与分析,线性规划,单纯形)