线性规划:单纯形算法之处理退化
上一篇文章介绍了单纯形算法(《线性规划:单纯形算法》),但是还有一些遗留问题没有解决,比如退化情形(Degeneracy)。
本文介绍如何处理退化情形。
退化情形
从几何上看上看,造成退化情形的原因是顶点重合。下图是三维空间中非退化情形下的多面体,每个顶点由三个面交汇。
当我们把线段 a b ab ab缩短至一点,于是得到退化情形。
如上图所示, a a a和 b b b重合时四个面交于一点,于是迭代过程可能在 a a a 和 b b b 之间转圈(Cycling)。
处理方法
回顾单纯形算法, 根据 Minimum Ratio Test 计算入基变量 x j x_j xj 的值。
x j : = min { b ~ i a ~ j i and a ~ j i > 0 , i = 1 , 2 , … , m } . x_j := \min \left\{ \frac{\tilde{b}_i}{\tilde{a}_{j_i}} \text{ and } \tilde{a}_{j_i}>0, \quad i=1,2,\ldots, m\right\}. xj:=min{a~jib~i and a~ji>0,i=1,2,…,m}.
其中 b ~ = B − 1 b \tilde{b} = B^{-1}b b~=B−1b, a ~ j = B − 1 a j \tilde{a}_j = B^{-1}a_j a~j=B−1aj, a j a_j aj 代表矩阵 A A A 的列向量。
令 I 0 I_0 I0 代表上式达到最小值的下标集合。
I 0 = { r : b ~ r a ~ j r = min [ b ~ i a ~ j i and a ~ j i > 0 , i = 1 , 2 , … , m ] } . I_0 = \left\{r:\frac{\tilde{b}_r}{\tilde{a}_{j_r}} = \min \left[ \frac{\tilde{b}_i}{\tilde{a}_{j_i}} \text{ and } \tilde{a}_{j_i}>0, \quad i=1,2,\ldots, m\right]\right\}. I0={r:a~jrb~r=min[a~jib~i and a~ji>0,i=1,2,…,m]}.
如果 I 0 I_0 I0 只包含一个元素 r r r,那么出基变量为 x B r x_{B_r} xBr,不会出现退化情形。否则可能出现退化情形,即变量 x B r x_{B_r} xBr 先出基,迭代数次又入基,这样一直循环下去导致算法死循环。
解决思路是防止同一个变量反复出基和入基。当 Minimum Ratio Test 发现 I 0 I_0 I0 包含多个出基变量时,用一些规则防止它们反复出基和入基。
下面介绍 Lexicographic Minimum Ratio Test。
在退化的情形下, I 0 I_0 I0 包含了多个元素,这此时我们定义新的下标集合 I 1 I_1 I1:
I 1 = { r : a ~ 1 r a ~ j r = min [ a ~ 1 i a ~ j i : i ∈ I 0 ] } . I_1 =\left\{r:\frac{\tilde{a}_{1_r}}{\tilde{a}_{j_r}} = \min \left[ \frac{\tilde{a}_{1_i}}{\tilde{a}_{j_i}}: i \in I_0\right]\right\}. I1={r:a~jra~1r=min[a~jia~1i:i∈I0]}.
注意:上述分式中的分子 a ~ 1 = B − 1 a 1 \tilde{a}_{1} = B^{-1} a_1 a~1=B−1a1,而 a ~ 1 i \tilde{a}_{1_i} a~1i 代表 a ~ 1 \tilde{a}_{1} a~1 中下标为 i i i 的分量。
如果 I 1 I_1 I1 只包含一个元素 r r r,那么交换 x j x_j xj 与 x B r x_{B_r} xBr 从而得到新的基。否则,我们定义类似的集合 I 2 , I 3 I_2, I_3 I2,I3,直到 I k I_k Ik,使得 I k I_k Ik 只包含一个元素。
I k = { r : a ~ k r a ~ j r = min [ a ~ k i a ~ j i : i ∈ I k − 1 ] } . I_k =\left\{r:\frac{\tilde{a}_{k_r}}{\tilde{a}_{j_r}} = \min \left[ \frac{\tilde{a}_{k_i}}{\tilde{a}_{j_i}}: i \in I_{k-1}\right]\right\}. Ik={r:a~jra~kr=min[a~jia~ki:i∈Ik−1]}.
可以证明,这样的 I k I_k Ik 始终存在。
设 r r r 是 I k I_k Ik 中唯一的元素,那么交换 x j x_j xj 与 x B r x_{B_r} xBr 从而得到新的基。
通过这种方式,单纯形算法可以在有限步内返回最优解(证明略)。
算法实现
下面用Python实现 Lexicographic Minimum Ratio Test。
单纯形算法的实现这里不重复展示,可以参考上一篇文章。只需要继承之前的类SimplexA
,然后重写方法 _minimum_ratio_test(self, j)
即可。
class SimplexAD(SimplexA):"""单纯形算法:处理退化情形。"""def _minimum_ratio_test(self, j):""" Lexicographically minimum ratio test.:param j: 入基变量 x_j 的下标 j:return: 出基变量 x_i 的下标 i"""a_in = np.dot(self._B_inv, self._A[:, j])d0 = self._get_d0(a_in) # 计算 I_0 的数组下标if d0 is None:return None# The index of "basic_vars".# The associated basic variable will be moved out.i_ind = self._get_out_ind(d0, 0, a_in)return self._basic_vars[i_ind]def _get_d0(self, a_in):""" 根据 Minimum Ratio Test 计算 I_0.实际上计算 d0 即可(定义如下):1、计算 ratios = [r_1, r_2, ..., r_m].2、计算 d0 = arg min(ratios),即 ratios 中最小值的下标3、I_0 = [self._basic_vars[i] for i in d0]"""b_bar = np.dot(self._B_inv, self._b)ratios = list(map(lambda b, a: b / a if a > 1e-6 else np.infty, b_bar, a_in))d0 = arg_min(ratios)if ratios[d0[0]] == np.infty:# a_in 的分量 <= 0# 最优目标函数值无界return Nonereturn d0def _get_out_ind(self, d0, it, a_in):""" 用递归的方法计算出基变量(在self._basic_vars[]中的index).:param d0: I_0 (在self._basic_vars[]的indices).:param it: iteration number, equals 0 at the beginning.:param a_in: B_inv * A[:, j]:return: the index to "basic_vars" (to be moved out)"""if len(d0) == 1:return d0[0]a_it = np.dot(self._B_inv, self._A[:, it])ratios = [a_it[k] / a_in[k] for k in d0]indices = arg_min(ratios)d1 = [d0[k] for k in indices]return self._get_out_ind(d1, it + 1, a_in)
完整代码
参考文献
[1] Christopher Griffin. Linear Programming: Penn State Math 484 Lecture Notes. Version 1.8.3. Chapter 7.(点此下载)
线性规划:单纯形算法之处理退化相关推荐
- 线性规划-单纯形算法详解
本文作者: hrwhisper 本文链接: https://www.hrwhisper.me/introduction-to-simplex-algorithm/ 版权声明: 本博客所有文章除特别声明 ...
- 0050算法笔记——【线性规划】单纯形算法(未完全实现)
题外话:王晓东的<算法设计与分析>看到现在,终于遇到自己琢磨不透的代码了.这里粘出来,求大神指点迷津,将代码补充完整~ 1.线性规划问题及其表示 线性规划问题可表示为如下形式: 变量满足约 ...
- 线性规划之二 —— 单纯形算法(详解)
鸣谢dalao的教导 单纯形算法是求解线性规划的经典方法 虽然ta的执行时间在最坏的情况下并不是多项式,然而在实际中这个算法通常是相当快速的 实际上也非常简单,主要就三个步骤: 找到一个初始的基本可行 ...
- 一般线性规划问题的2阶段单纯形算法
5.一般线性规划问题的2阶段单纯形算法 引入人工变量后的线性规划问题与原问题并不等价,除非所有zi都是0 . 为了解决这个问题,在求解时必须分2个阶段进行. 第一阶段用一个辅助目标函数 ...
- 简单理解线性规划的单纯形算法
自己写的,csdn的markdown不怎么会用,所以在知乎写的. 文章-理解线性规划的单纯形算法
- 线性规划专题——SIMPLEX 单纯形算法(三)图解——示例、注意点
线性规划专题--SIMPLEX 单纯形算法(一) 线性规划专题--SIMPLEX 单纯形算法(二) 前面两篇博文已经把单纯形算法里面的核心思想给解释清楚了,主要是要认识到在线性规划里面的以下几点: 目 ...
- 线性规划问题的单纯形算法求解
关于线性规划问题是什么已经有很多人早就说明过了,我也小抄一波给大家预热预热,线性规划问题是运筹学中研究较早.发展较快.应用广泛.方法较成熟的一个重要分支,它是辅助人们进行科学管理的一种数学方法. 在一 ...
- 单纯形算法 Simplex Algorithm (二)
为了真正理解单纯形算法的具体步骤,我查阅了许多文章,不过大部分文章会直接叙述单纯形表的操作,对理解算法帮助有限:也有一些文章直接从线性代数上的原理开始叙述,对于非专业人士又太难了.所幸我找到了一个挺不 ...
- Nelder-Mead(simplex,“单纯形”)算法
求多维函数极值的一种算法,由Nelder和Mead提出,又叫单纯形算法,但和线性规划中的单纯形算法是不同的,由于未利用任何求导运算,算法比较简单,但收敛速度较慢,适合变元数不是很多的方程求极值,算法的 ...
最新文章
- eyoucms range 范围判断标签
- “新一代城市大脑建设与发展“专家研讨会
- 第80节:Java中的MVC设计模式
- 在VS2008中DataGridView控件里DataGridViewComboBoxColumn列的Bug
- 1分钟深入了解CSS3的动画属性animation
- SAP 电商云 UI 服务器端渲染的建议架构
- linux查看当前用户终端,Linux----基本命令的使用(vi命令,查看文件内容,显示进程,切换用户等)...
- python文字游戏源代码妈妈和我年纪_Python实现猜年龄游戏代码实例
- 【微型计算机原理与接口技术】80X86微处理器发展与内部结构
- 使用UIWebView中html标签显示富文本
- java 向量点乘_向量的点乘与叉乘学习笔记
- linux ubuntu用哪个版本,Ubuntu到底哪个版本最好用?
- 人体如何区分阴虚和阳虚?
- 天空之城简谱用计算机,原神天空之城琴谱 数字版简谱分享
- C++计算某天是该年的第几天
- CPU使用率查看方法
- 林轩田之机器学习课程笔记( embedding numerous feature之support vector regression)(32之22)
- AVI文件数据流操作
- 酷派大观4 8970 刷android 4.4,极速达百兆! 移动4G版酷派大观4网络体验
- Jupyter notebook 配置无问题 但就是无法远程访问,解决方法