单纯形学习笔记
线性规划是很多最优化问题可以归约到的模型,而单纯形是解决之的一个较为简单的算法。虽然复杂度不优,但通常而言和无优化的网络流效率相当,而且比较玄学。很多时候可以作为乱搞做法获得一定分数。
1.线性规划标准型
我们定义 线性规划标准型 为如下形式的线性规划问题:
其中包含 \(n\) 个变量和 \(m\) 条约束(\(n \geq m\),否则必然存在无用的约束或者整体无解)。注意到其中所有约束皆是等式。对于 \(\leq\) 约束,可以在加入一个新的变量,在等式右侧加上之,即可改为等式,\(\geq\) 同理。
为什么要引入标准型呢?因为在可以把约束写成矩阵的形式 \(A\vec X=\vec B\),非常方便我们对约束进行变换。
2.基准变量与pivot操作
单纯形算法基于如下观察:在一个线性规划标准型的解中,会有很多变量的值为0. 因此可以将对于解的贡献为正且相互线性独立的变量设为 基准变量,可以发现这样的变量数不会超过 \(m\)。注意到这些基准变量可以由其他变量完全确定,因此如果我们找到了正确的基准变量,将其他变量设为 \(0\) 即可得到答案。设通过常数项和非基准变量确定基准变量和结果的系数矩阵为 \(M\)。
通过 pivot操作,我们可以将一个基准变量与非基准变量互换。具体而言,如果将基准变量 \(x_u\) 与非基准变量 \(x_v\) 互换,首先将 \(M_u\) 一行进行修改,使得其表示由新的非基准变量转移到 \(x_v\) 的系数,然后对于所有非 \(M_u\) 的行,求得其新的转移。这里有个小 trick:对 \(M\) 矩阵对于非基准变量的系数取负,可以使代码简洁许多,具体而言,新的变换如下:
变换后:
其他值的变换中的 \(x_v\) 直接分解成上述式子即可,类似初等行变换。
3.具体求法和初始化
我们现在可以通过 pivot 操作改变基准变量,但是如何得到最优值还是存在问题。首先,我们必须保证得到的结果是合法的,即 \(M_{i,0}\) 对于所有基准变量 \(x_i\) 都是非负的(因为所有的变量必须非负).为了保证这一点,每次我们 随机 选取一个不符合上述条件的基准变量 \(x_u\)(即矩阵行),然后选取一个对其贡献系数为正的非基准变量 \(x_v\)(即 \(M_{u,v} \lt 0\),因为 trick),然后 pivot(u,v) 即可。若找不到这样的 \(x_u\),说明初始化成功了;如果找到了\(x_u\)却找不到 \(x_v\) 说明无解。
考虑最后找到结果的条件:当且仅当表示答案的非基准变量的系数皆非正才是正确的,毕竟我们需要将其他变量设为 \(0\)。因此,我们每次找到一个对于答案贡献为正的非基准变量 \(x_v\)(即矩阵列),找到使得 \(M_{u,0}/M_{u,v}\) 最小且非负的 \(x_u\),然后 pivot(u,v) 即可。若找不到这样的 \(x_v\),说明求解成功了;如果找到了\(x_v\)却找不到 \(x_u\) 说明无解。
为什么要找 \(M_{u,0}/M_{u,v}\) 最小且非负的 \(x_u\) 呢?这是为了防止初始化的结果付之东流。考虑一次 pivot(u,v) 对于一个 \(M_{w,0}\) 的贡献,可以发现其为:
注意到必须保持 \(M_{w,0}\) 非负,因此上值必须小于 \(M_{w,0}\),若 \(M_{w,v} \leq 0\) 则上值非正,否则变换后有:
因此必须找到符合上述条件的 \(x_u\)。
最后的结果在所有非基准变量设为0时取得。注意到在整个过程中 \(M_0\) 一列求和结果保持不变为 \(0\),因此可以发现结果为 \(-M_{0,0}\)。
4.小技巧
注意到很多时候题目给出的线性规划形如这样:
通用的解决方法是加入 \(m\) 个虚变量,将其变为标准型(见1),在这里选取最开始的基准变量时可以偷个懒,直接选取这些虚变量,初始的 \(M\) 矩阵也就可以直接设置为上述系数。

浙公网安备 33010602011771号