线性规划的单纯形法常见问题及详细的解决方法
线性规划简介线性规划(Linear Programming, LP),是运筹学中研究较早、发展较快、应用广泛、方法较成熟的一个重要分支,它是辅助人们进行科学管理的一种数学方法。研究线性约束条件下线性目标函数的极值问题的数学理论和方法。英文缩写LP。它是运筹学的一个重要分支,广泛应用于军事作战、经济分析、经营管理和工程技术等方面。为合理地利用有限的人力、物力、财力等资源作出的最优决策,提供科学的依据。(来自百度百科)
线性规划问题:
在一般的线性规划问题中,我们希望优化一个满足一组线性不等式约束的线性函数。一直一组实数 http://latex.codecogs.com/gif.latex?%20%28a_%7b1%7d,%20a_%7b2%7d...,a_%7bn%7d%29 ,对应的一组变量http://latex.codecogs.com/gif.latex?%20%28x_%7b1%7d,%20x_%7b2%7d...,x_%7bn%7d%29。定义关于这些变量的一个线性函数:http://latex.codecogs.com/gif.latex?%20f%28x_%7b1%7d,%20x_%7b2%7d...,x_%7bn%7d%29%20=%20a_%7b1%7dx_%7b1%7d%20+%20%20a_%7b2%7dx_%7b2%7d%20+%20...%20+%20a_%7bn%7dx_%7bn%7d%20=%20\sum_%7bi=1%7d^%7bn%7da_%7bi%7dx_%7bi%7d
那么等式http://latex.codecogs.com/gif.latex?%20f%28x_%7b1%7d,%20x_%7b2%7d...,x_%7bn%7d%29%20=%20b和不等式 http://latex.codecogs.com/gif.latex?%20f%28x_%7b1%7d,%20x_%7b2%7d...,x_%7bn%7d%29%20\le%20b 以及http://latex.codecogs.com/gif.latex?%20f%28x_%7b1%7d,%20x_%7b2%7d...,x_%7bn%7d%29%20\ge%20b 都称为”线性约束”。并且不久之后我们即将看到,我们可以把两种不等式的约束形式统一为http://latex.codecogs.com/gif.latex?%20f%28x_%7b1%7d,%20x_%7b2%7d...,x_%7bn%7d%29%20\le%20b%27 这种形式,然而之后在运行解决线性规划的单纯形法时又会将它变成等价的http://latex.codecogs.com/gif.latex?%20f%28x_%7b1%7d,%20x_%7b2%7d...,x_%7bn%7d%29%20=%20b_%7b0%7d 形式。
描述线性规划问题:
线性规划问题的标准型:
如果我们已知n个实数http://latex.codecogs.com/gif.latex?%20c_%7b1%7d,%20c_%7b2%7d...,%20c_%7bn%7d与m个实数http://latex.codecogs.com/gif.latex?%20b_%7b1%7d,%20b_%7b2%7d...,%20b_%7bm%7d,以及n*m个实数http://latex.codecogs.com/gif.latex?%20a_%7bij%7d,%20i%20=%201,2,...,m,%20j=1,2,..,n,我们希望找到n个实数http://latex.codecogs.com/gif.latex?%20x_%7b1%7d,%20x_%7b2%7d,...,x_%7bn%7d
最大化 http://latex.codecogs.com/gif.latex?%20\sum_%7bj=1%7d^%7bn%7dc_%7bj%7dx_%7bj%7d
满足约束http://latex.codecogs.com/gif.latex?%20\sum_%7bj=1%7d^%7bn%7da_%7bij%7dx_%7bj%7d%20\le%20b_%7bi%7d,%20i%20=%201,%202...,m
http://latex.codecogs.com/gif.latex?%20x_%7bj%7d%20\ge%200,%20j%20=%201,%202,...,%20nhttp://latex.codecogs.com/gif.latex?%20x_%7bj%7d%20\ge%200,%20j%20=%201,%202,...,%20n
或者将分别将http://latex.codecogs.com/gif.latex?%20b_%7b1%7d,%20b_%7b2%7d,...,b_%7bm%7d和http://latex.codecogs.com/gif.latex?%20c_%7b1%7d,%20c_%7b2%7d,%20...,%20c_%7bn%7d和http://latex.codecogs.com/gif.latex?%20x_%7b1%7d,%20x_%7b2%7d,%20...,%20x_%7bn%7d表示成向量b, c, x,构造m行n列矩阵http://latex.codecogs.com/gif.latex?%20A%20=%20%28a_%7bij%7d%29。那么标准型也可以写作:
最大化 http://latex.codecogs.com/gif.latex?%20c^Tx
满足约束http://latex.codecogs.com/gif.latex?%20Ax%20\le%20b
http://latex.codecogs.com/gif.latex?%20x%20\ge%200
注意到,标准型里面目标函数的目标是最大化,所有变量都具有非负约束,除了非负约束外的约束都是具有 <= 符号的非严格不等式。对于不满足标准型形式的线性规划,我们可以想办法将它转化为标准型:
问题1:目标函数的目标并非最大化,而是最小化。
取负即可。也就是最小化 http://latex.codecogs.com/gif.latex?%20c^Tx 等价于最大化 http://latex.codecogs.com/gif.latex?%20-c^Tx
问题2:一些变量不具有非负约束
对于不具有非负约束的变量http://latex.codecogs.com/gif.latex?%20x_%7bj%7d,把http://latex.codecogs.com/gif.latex?%20x_%7bj%7d每次出现的地方都替换为适当的
问题3:大于等于约束和等式约束
大于等于约束两边同时取负即可。即http://latex.codecogs.com/gif.latex?%20\sum_%7bj=1%7d^%7bn%7da_%7bij%7d%20\ge%20b_%7bi%7d 等价于http://latex.codecogs.com/gif.latex?%20\sum_%7bj=1%7d^%7bn%7d-a_%7bij%7d%20\le%20-b_%7bi%7d
等式约束拆成两个不等式约束。对于 http://latex.codecogs.com/gif.latex?%20\sum_%7bj=1%7d^%7bn%7da_%7bij%7d%20=%20b_%7bi%7d等价于http://latex.codecogs.com/gif.latex?%20\sum_%7bj=1%7d^%7bn%7da_%7bij%7d%20\le%20b_%7bi%7d 且 http://latex.codecogs.com/gif.latex?%20\sum_%7bj=1%7d^%7bn%7d-a_%7bij%7d%20\le%20-b_%7bi%7d
描述线性规划问题的松弛型
为了利用单纯形算法高效地求解线性规划,我们更喜欢把其中的除非负约束外的约束转换成等式约束。
对于一个约束http://latex.codecogs.com/gif.latex?%20\sum_%7bj=1%7d^%7bn%7da_%7bij%7d%20\le%20b_%7bi%7d 引入一个松弛变量s,约束即可写作:http://latex.codecogs.com/gif.latex?%20s%20=%20b_%7bi%7d%20-%20\sum_%7bj=1%7d^%7bn%7da_%7bij%7d,%20s%20\ge%200
一般地,为了方便常会用 http://latex.codecogs.com/gif.latex?%20x_%7bn+i%7d作为第i个约束条件的松弛变量。因此第i约束条件就可以写作:http://latex.codecogs.com/gif.latex?%20x_%7bn+i%7d%20=%20b_%7bi%7d%20-%20\sum_%7bj=1%7d^%7bn%7da_%7bij%7dx_%7bj%7d,%20x_%7bn+i%7d%20\ge%200
用一个例子来说明上述描述线性规划问题的方法:
最小化 http://latex.codecogs.com/gif.latex?-2x_%7b1%7d%20+%203x_%7b2%7d
满足约束条件http://latex.codecogs.com/gif.latex?x_%7b1%7d%20+%20x_%7b2%7d%20=%207
http://latex.codecogs.com/gif.latex?x_%7b1%7d%20-%202x_%7b2%7d%20\le%204
http://latex.codecogs.com/gif.latex?x_%7b1%7d%20\ge%200
最小化目标转变成最大化:http://latex.codecogs.com/gif.latex?2x_%7b1%7d%20-%203x_%7b2%7d
最大化
满足约束条件http://latex.codecogs.com/gif.latex?x_%7b1%7d%20+%20x_%7b2%7d%20=%207
http://latex.codecogs.com/gif.latex?x_%7b1%7d%20-%202x_%7b2%7d%20\le%204
http://latex.codecogs.com/gif.latex?x_%7b1%7d%20\ge%200
等式约束
拆开等式约束:http://latex.codecogs.com/gif.latex?2x_%7b1%7d%20-%203x_%7b2%7d
最大化
满足约束条件http://latex.codecogs.com/gif.latex?x_%7b1%7d%20+%20x_%7b2%7d%20\le%207
http://latex.codecogs.com/gif.latex?-x_%7b1%7d%20-%20x_%7b2%7d%20\le%20-7
http://latex.codecogs.com/gif.latex?x_%7b1%7d%20-%202x_%7b2%7d%20\le%204
http://latex.codecogs.com/gif.latex?x_%7b1%7d%20\ge%200
增加非负约束
http://latex.codecogs.com/gif.latex?x_%7b2%7d替换为http://latex.codecogs.com/gif.latex?x_%7b2%7d-x_%7b3%7d,添加对http://latex.codecogs.com/gif.latex?x_%7b2%7d,x_%7b3%7d的非负约束,得到http://latex.codecogs.com/gif.latex?2x_%7b1%7d%20-%203x_%7b2%7d+3x_%7b3%7d
最大化
满足约束条件 http://latex.codecogs.com/gif.latex?x_%7b1%7d%20+%20x_%7b2%7d%20-%20x_%7b3%7d\le%207
http://latex.codecogs.com/gif.latex?-x_%7b1%7d%20-%20x_%7b2%7d+x_%7b3%7d%20\le%20-7
http://latex.codecogs.com/gif.latex?x_%7b1%7d%20-%202x_%7b2%7d%20+%202x_%7b3%7d\le%204
http://latex.codecogs.com/gif.latex?x_%7b1%7d%20\ge%200,%20x_%7b2%7d%20\ge%200%20,x_%7b3%7d%20\ge%200
标准型到松弛型
除了非负约束外,有3个约束条件,于是增加松弛变量http://latex.codecogs.com/gif.latex?x_%7b4%7d%20,%20x_%7b5%7d%20%20,x_%7b6%7d
最大化 http://latex.codecogs.com/gif.latex?2x_%7b1%7d%20-%203x_%7b2%7d+3x_%7b3%7d
满足约束条件 http://latex.codecogs.com/gif.latex?x_%7b4%7d%20=%207%20-%20x_%7b1%7d%20-%20x_%7b2%7d%20+%20x_%7b3%7d
http://latex.codecogs.com/gif.latex?x_%7b5%7d%20=%20-7%20+%20x_%7b1%7d%20+%20x_%7b2%7d%20-%20x_%7b3%7d
http://latex.codecogs.com/gif.latex?x_%7b6%7d%20=%204%20-%20x_%7b1%7d%20+%202x_%7b2%7d%20-%202x_%7b3%7d
http://latex.codecogs.com/gif.latex?x_%7b1%7d%20\ge%200,%20x_%7b2%7d%20\ge%200%20,x_%7b3%7d%20\ge%200,x_%7b4%7d%20\ge%200,x_%7b5%7d%20\ge%200,x_%7b6%7d%20\ge%200
思考:如果原先有一个等式约束,直接把它写到松弛型里面,与将它转变成标准型,再变成松弛型(这样就比前者多了一个约束条件),问题是否等价?(提示:考虑后者引入的松弛变量s1 = s2 = 0)
解决线性规划问题的单纯形法:
单纯形算法是求解线性规划的经典算法,它再最坏情况瞎执行时间并不是多项式级别的,但是在实际的应用中,它总是相当快速。
个人理解:
单纯形法接受一个松弛型的输入,每轮迭代尝试将松弛型L转变为一个等价的松弛型L’,直到转变成一种”易于求解的松弛型”,得到结果。这就类似化三角法求行列式值。
什么是”易于求解的松弛型”呢?如果目标函数具有 http://latex.codecogs.com/gif.latex?z%20=%20C%20+%20\sum_%7bi=1%7d^%7bn%27%7dc%27_%7bi%7dx%27_%7bi%7d,%20c%27_%7bi%7d%20%3C=%200
这样的形式,由于变量具有非负约束,因此z的最大值即为常数C。如果我们能把一般的松弛型转变为这样”易于求解的松弛型”的松弛型即可得解。
具体的方法 换个便于演示的例子:
考虑下面这个松弛型:
最大化 http://latex.codecogs.com/gif.latex?z%20=%203x_%7b1%7d%20+%20x_%7b2%7d%20+%202x_%7b3%7d
满足约束条件 http://latex.codecogs.com/gif.latex?x_%7b4%7d%20=%2030%20-%20x_%7b1%7d%20-%20x_%7b2%7d%20-%203x_%7b3%7d
http://latex.codecogs.com/gif.latex?x_%7b5%7d%20=%2024%20-2%20x_%7b1%7d%20-%202x_%7b2%7d%20-%205x_%7b3%7d
http://latex.codecogs.com/gif.latex?x_%7b6%7d%20=%2036%20-4%20x_%7b1%7d%20-%20x_%7b2%7d%20-%202x_%7b3%7d
http://latex.codecogs.com/gif.latex?x_%7b1%7d%20\ge%200,%20x_%7b2%7d%20\ge%200%20,x_%7b3%7d%20\ge%200,x_%7b4%7d%20\ge%200,x_%7b5%7d%20\ge%200,x_%7b6%7d%20\ge%200
术语:我们把松弛型约束条件等号左边的变量称为基本变量,右边的称为非基本变量。
我们会选取目标函数里面某个系数为正的非基本变量http://latex.codecogs.com/gif.latex?x_%7be%7d,并尽可能增大http://latex.codecogs.com/gif.latex?x_%7be%7d的取值且不违反任何约束条件。由于http://latex.codecogs.com/gif.latex?x_%7be%7d的增大可能会导致其它变量值缩小,但是其它变量也存在非负约束,这样就约束了http://latex.codecogs.com/gif.latex?x_%7be%7d的取值的上界,我们选出对http://latex.codecogs.com/gif.latex?x_%7be%7d约束最紧的变量http://latex.codecogs.com/gif.latex?x_%7bl%7d,令http://latex.codecogs.com/gif.latex?x_%7be%7d 与 http://latex.codecogs.com/gif.latex?x_%7bl%7d 互换(代入法)得到一个新的等价的松弛型。具体对于我们这个例子就是:
首先看变量http://latex.codecogs.com/gif.latex?x_%7b1%7d,对它约束最紧的是第三个约束,约束了http://latex.codecogs.com/gif.latex?%20x_%7b1%7d\le9。是http://latex.codecogs.com/gif.latex?%20x_%7b6%7d约束了http://latex.codecogs.com/gif.latex?x_%7b1%7d。于是互换http://latex.codecogs.com/gif.latex?x_%7b6%7d 与http://latex.codecogs.com/gif.latex?x_%7b1%7d,把http://latex.codecogs.com/gif.latex?x_%7b1%7d放到 http://latex.codecogs.com/gif.latex?x_%7b6%7d的位置,得到http://latex.codecogs.com/gif.latex?x_%7b1%7d%20=%209%20-%20\frac%7bx_%7b2%7d%7d%7b4%7d%20-%20\frac%7bx_%7b3%7d%7d%7b2%7d%20-%20\frac%7bx_%7b6%7d%7d%7b4%7d
将约束条件不等式右边的所有http://latex.codecogs.com/gif.latex?x_%7b1%7d用这个式子替换掉,即可得到 http://latex.codecogs.com/gif.latex?z%20=%2027+\frac%7bx_%7b2%7d%7d%7b4%7d%20+%20\frac%7bx_%7b3%7d%7d%7b2%7d%20-%20\frac%7b3x_%7b6%7d%7d%7b4%7d
最大化
满足约束条件 http://latex.codecogs.com/gif.latex?x_%7b1%7d%20=%209%20-%20\frac%7bx_%7b2%7d%7d%7b4%7d%20-%20\frac%7bx_%7b3%7d%7d%7b2%7d%20-%20\frac%7bx_%7b6%7d%7d%7b4%7d
http://latex.codecogs.com/gif.latex?x_%7b4%7d%20=%2021%20-%20\frac%7b3x_%7b2%7d%7d%7b4%7d%20-%20\frac%7b5x_%7b3%7d%7d%7b2%7d%20+%20\frac%7bx_%7b6%7d%7d%7b4%7d
http://latex.codecogs.com/gif.latex?x_%7b5%7d%20=%206%20-%20\frac%7b3x_%7b2%7d%7d%7b2%7d%20-%204x_%7b3%7d+\frac%7bx_%7b6%7d%7d%7b2%7d
http://latex.codecogs.com/gif.latex?x_%7b1%7d%20\ge%200,%20x_%7b2%7d%20\ge%200%20,x_%7b3%7d%20\ge%200,x_%7b4%7d%20\ge%200,x_%7b5%7d%20\ge%200,x_%7b6%7d%20\ge%200
这样的一次操作叫做转动(pivot)
(结合例子请思考:选择约束最紧的变量做互换的原因。提示:如果换的不是最紧的约束看看会违反什么性质)
然后选择变量http://latex.codecogs.com/gif.latex?x_%7b2%7d或者http://latex.codecogs.com/gif.latex?x_%7b3%7d,不选http://latex.codecogs.com/gif.latex?x_%7b6%7d是因为增大http://latex.codecogs.com/gif.latex?x_%7b6%7d会导致目标z减小。
如果选择 http://latex.codecogs.com/gif.latex?x_%7b3%7d,同样的方法,互换http://latex.codecogs.com/gif.latex?x_%7b3%7d与http://latex.codecogs.com/gif.latex?x_%7b5%7d可以得到新的但等价的约束系统:
最大化 http://latex.codecogs.com/gif.latex?z%20=%20\frac%7b111%7d%7b4%7d+\frac%7bx_%7b2%7d%7d%7b16%7d-\frac%7bx_%7b5%7d%7d%7b8%7d-\frac%7b11x_%7b6%7d%7d%7b16%7d
满足约束条件 http://latex.codecogs.com/gif.latex?x_%7b1%7d%20=%20\frac%7b33%7d%7b4%7d-\frac%7bx_%7b2%7d%7d%7b16%7d+\frac%7bx_%7b5%7d%7d%7b8%7d-\frac%7b5x_%7b6%7d%7d%7b16%7d
http://latex.codecogs.com/gif.latex?x_%7b3%7d%20=%20\frac%7b3%7d%7b2%7d-\frac%7b3x_%7b2%7d%7d%7b8%7d-\frac%7bx_%7b5%7d%7d%7b4%7d+\frac%7bx_%7b6%7d%7d%7b8%7d
http://latex.codecogs.com/gif.latex?x_%7b4%7d%20=%20\frac%7b69%7d%7b4%7d+\frac%7b3x_%7b2%7d%7d%7b16%7d+\frac%7b5x_%7b5%7d%7d%7b8%7d-\frac%7bx_%7b6%7d%7d%7b16%7d
http://latex.codecogs.com/gif.latex?x_%7b1%7d%20\ge%200,%20x_%7b2%7d%20\ge%200%20,x_%7b3%7d%20\ge%200,x_%7b4%7d%20\ge%200,x_%7b5%7d%20\ge%200,x_%7b6%7d%20\ge%200
接下来也只剩下http://latex.codecogs.com/gif.latex?x_%7b2%7d这个变量可选了,与http://latex.codecogs.com/gif.latex?x_%7b3%7d互换,得到
最大化 http://latex.codecogs.com/gif.latex?z%20=%2028%20-%20\frac%7bx_%7b3%7d%7d%7b6%7d-\frac%7bx_%7b5%7d%7d%7b6%7d-\frac%7b2x_%7b6%7d%7d%7b3%7d
满足约束条件 http://latex.codecogs.com/gif.latex?x_%7b1%7d%20=%208+\frac%7bx_%7b3%7d%7d%7b6%7d%20+%20\frac%7bx_%7b5%7d%7d%7b6%7d-\frac%7bx_%7b6%7d%7d%7b3%7d
http://latex.codecogs.com/gif.latex?x_%7b2%7d%20=%204-\frac%7b8x_%7b3%7d%7d%7b3%7d-\frac%7b2x_%7b5%7d%7d%7b3%7d+\frac%7bx_%7b6%7d%7d%7b3%7d
http://latex.codecogs.com/gif.latex?x_%7b4%7d%20=%2018-\frac%7bx_%7b3%7d%7d%7b2%7d+\frac%7bx_%7b5%7d%7d%7b2%7d
http://latex.codecogs.com/gif.latex?x_%7b1%7d%20\ge%200,%20x_%7b2%7d%20\ge%200%20,x_%7b3%7d%20\ge%200,x_%7b4%7d%20\ge%200,x_%7b5%7d%20\ge%200,x_%7b6%7d%20\ge%200
此时目标函数右边变量系数全部为负数,且变量具有非负约束,显然这时候能得到的z的最大值为28。当且仅当http://latex.codecogs.com/gif.latex?x_%7b3%7d%20=%20x_%7b5%7d%20=%20x_%7b6%7d%20=%200。带入解得http://latex.codecogs.com/gif.latex?x_%7b1%7d%20=%208,%20x_%7b2%7d%20=%204,%20x_%7b4%7d%20=%2018。除去附加的松弛变量,最终这个线性规划最优解为
http://latex.codecogs.com/gif.latex?x_%7b1%7d%20=%208,%20x_%7b2%7d%20=%204,%20x_%7b3%7d%20=%200,%20z%20=%2028
思考:每次转动操作交换的两个变量对单纯形法的运行时间有着怎样的影响?如何选择可以使单纯形法尽快结束?(提示:每次pivot尽可能让目标函数增大得多)
单纯形算法代码实现
伪代码:
simplex:
检查是否无解
loop:
找出目标函数中前面系数为正数的一个变量x
如果找不到x
返回目标函数的常数项(已找到目标函数最大值)
找到对x的增长约束最紧的变量y
如果找不到y
返回Inf
互换变量x,y(pivot(x,y),操作后问题与原来等价)
非标准型转换为标准型魔法码(github上给出的参考代码要求输入的是标准型)
输出目标函数达到最大值时自变量的取值
思考:会不会存在一种情况:虽然一个线性规划问题有解,但是单纯形算法仍会无休止迭代下去。
思考:如果判断出这样一种无解的情况:
http://latex.codecogs.com/gif.latex?-x_%7b1%7d+x_%7b2%7d%20=%204
http://latex.codecogs.com/gif.latex?x_%7b2%7d%20=%202
http://latex.codecogs.com/gif.latex?x_%7b1%7d%20\ge%200,%20x_%7b2%7d%20\ge%200
请关注数学中国微信公众号和数学中国网微博号 联系QQ数学中国浅夏3243710560
页:
[1]