简单易懂的单纯形法理解

简单易懂的单纯形法理解简单易懂的单纯形法理解 uad 从学线性规划开始一直觉得单纯形是一种奇奇怪怪不知所云的方法 居然还叫 simplex 我觉得叫 complex 才对 上课老师讲到的一大堆性质的证明也让人晕头转向 最后还是死记硬背下了单纯形表的解法勉强应付过了作业 直到今天小班课助教讲了他学到的对于单纯形的理解 才觉得豁然开朗 原来单纯形的确是这么 单纯 和图解法结合起来也更加清晰直观地看到了单纯形法的工作过

简单易懂的单纯形法理解

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

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

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

\uad 我们以《算法设计与分析(第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 \uad z=12x+15y\\ s.t.\quad 0.25x+0.50y\ \leq120\\ \uad \;0.50x+0.50y\ \leq150\\\uad0.25x\uad\uad\leq50\\x\geq0,\quad y\geq0 maxz=12x+15ys.t.0.25x+0.50y 1200.50x+0.50y 1500.25x50x0,y0
画出的图像如图所示
在这里插入图片描述
\uad 这是最简单的情形,所有的约束条件都为小于等于,我们可以直接通过引入松弛变量来化为标准形,即:
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 \uad -z=-12x_{1}-15x_{2}\\ s.t.\quad 0.25x_{1}+0.50x_{2}+x_{3}\ =120\\ \uad \;0.50x_{1}+0.50x_{2}+x_{4}\ =150\\\uad0.25x_{1}\uad\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



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

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

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

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

\uad 接下来就开始我们的优化,我们的目的是想让目标函数的值降低,而现在影响目标函数的变量有 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作为换入变量,使它成为可行基。

\uad 我们当然希望目标函数越小越好,那么我们的 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 \uad 0.25x_{1}+0.50x_{2}+x_{3}\ =120\\ \uad \;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)。
\uad 现在 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作为换出变量

\uad 现在,我们尽管没有提到变量替换这样的概念,但我们已经选好了所谓的换入变量换出变量。这时候,我们的解向量变成了{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\\\uad\;0.25x_{1}\uad\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,这样我们得到一个更加简便的计算“新目标函数”的方法。

\uad 到这里,有些同学可能会提出疑问:为什么 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}\uad\uad x_{2}\uad\uad x_{3}\uad\uad x_{4}\uad\uad x_{5} x1x2x3x4x5 θ \theta θ
x 2 x_{2} x2 240 0.50 1 2 0 0 0.50 \uad \uad1\uad\uad2\uad\uad0\uad\uad0\quad 0.501200 480
x 4 x_{4} x4 30 0.25 0 − 1 1 0 0.25 \uad \uad0\quad\uad-1\uad\uad1\uad\uad0\quad 0.250110 120
x 5 x_{5} x5 50 0.25 0 0 0 1 0.25 \uad \uad0\quad\uad\quad0\uad\uad0\uad\uad1\quad 0.250001 200
− z -z z 3600 − 4.5    0    30 0 0 -4.5 \uad \ \ \quad0\ \ \uad\uad30\uad\uad0\uad\uad0\quad 4.5  0  3000

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

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

\uad 有了第一次单纯形变换的经验,我们很容易同样地进行第二步。首先选择能让目标函数减小的变量,这里只有 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}\uad\uad x_{2}\uad\uad x_{3}\uad\uad x_{4}\uad\uad x_{5} x1x2x3x4x5 θ \theta θ
x 2 x_{2} x2 240 0 1 4 − 2 0 0 \uad \uad1\uad\uad4\uad\uad-2\uad\uad0\quad 01420
x 1 x_{1} x1 30 1 0 − 4 4 0 1 \uad \uad0\quad\uad\quad-4\uad\uad4\uad\uad0\quad 10440
x 5 x_{5} x5 50 0 0 1 − 1 1 0 \uad \uad0\quad\uad\quad1\uad\uad-1\uad\uad1\quad 00111
− z -z z 4140 0    0    12 18 0 0 \uad \ \ \quad0\ \ \uad\uad12\uad\uad18\uad\uad0\quad 0  0  12180

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

总结

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

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/201284.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月20日 上午9:41
下一篇 2026年3月20日 上午9:41


相关推荐

  • eclipse运行java程序_如何在Eclipse中运行简单的Java程序?「建议收藏」

    eclipse运行java程序_如何在Eclipse中运行简单的Java程序?「建议收藏」正如您可能从问题本身可以理解的那样,我是Java的新手。我进行了一个练习,编写一个Java程序,该程序接收一个字符,将其打印并输出Unicode表中的下一个字符。现在,我有解决此问题的方法:publicstaticvoidmain(String[]args){charc=args[0].charAt(0);charc1=(char)(c+1);System.out.prin…

    2022年7月8日
    23
  • 实验报告:图书销售管理系统数据库SQL应用编程

    实验报告:图书销售管理系统数据库SQL应用编程实验目的针对图书销售管理数据库开发,了解SQL语言DDL、DML、DQL类型语句在数据库操作访问中的应用方法,培养数据库SQL编程访问能力。同时也掌握基本的数据库触发器、存储过程SQL编程方法,培养数据库后端编程能力。本实验完成图书销售管理系统数据库的SQL数据操作访问和后端数据处理功能。实验原理首先对图书销售管理系统进行数据需求分析,定义组成系统数据结构的实体、实体属性以及实体之间的关系。采用实体关系图(E-R模型图)方法来展示图书销售管理系统的概念数据模型与逻辑数据模型。利用PowerDes

    2022年6月1日
    51
  • bat批处理命令大全_文件批处理命令

    bat批处理命令大全_文件批处理命令批处理文件(batchfile)包含一系列DOS命令,通常用于自动执行重复性任务。用户只需双击批处理文件便可执行任务,而无需重复输入相同指令。编写批处理文件非常简单,但难点在于确保一切按顺序执行。编写严谨的批处理文件可以极大程度地节省时间,在应对重复性工作时尤其有效在Windows中善用批处理可以简化很多重复工作批处理? 批处理(Batch),也称为批处理脚本。顾名思义,批处理就是对某对象进行批量的处理。批处理文件的扩展名为bat 目前比较常见的批处理包含两类: DOS批

    2022年8月22日
    9
  • WinHex恢复GPT分区表时,如何处理分区丢失且MBR被覆盖的情况?

    WinHex恢复GPT分区表时,如何处理分区丢失且MBR被覆盖的情况?

    2026年3月16日
    1
  • idea202112激活码下载[最新免费获取]

    (idea202112激活码下载)好多小伙伴总是说激活码老是失效,太麻烦,关注/收藏全栈君太难教程,2021永久激活的方法等着你。IntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,下面是详细链接哦~https://javaforall.net/100143.htmlS32PGH0SQB-eyJsaWNlbnNlSWQi…

    2022年3月25日
    59
  • 简述Redis持久化机制RDB和AOF优缺点_redis的aof和rdb

    简述Redis持久化机制RDB和AOF优缺点_redis的aof和rdb先通过故事理解一下RDB和AOF,再来详细讲讲两者的区别RDB和AOF的故事我是Redis,一个叫Antirez的男人把我带到了这个世界上。“快醒醒!快醒醒!”,隐隐约约,我听到有人在叫我。慢慢睁开眼睛,原来旁边是MySQL大哥。“我怎么睡着了?”“嗨,你刚才是不是出现了错误,整个进程都崩溃了!害得一大堆查询请求都给我怼过来了!”,MySQL说到。刚刚醒来,脑子还有点懵,MySQL大哥扶我起来继续工作。“糟了!我之前缓存的数据全都不见了!”“WTF?你没有做持久化吗?”,MySQL大哥一

    2025年8月15日
    4

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号