1. 项目概述:从“硬凑”到“真解”的人工变量法实战
搞运筹学或者生产调度、资源优化的朋友,对线性规划肯定不陌生。单纯形法是咱们手里的核心武器,但它的启动有个前提:你得有一个现成的“可行基”,也就是一个初始的可行解。这就像开车,你得先打着火。可现实中很多问题,特别是“≥”或“=”约束条件一堆的时候,想直接找到一个起点(单位矩阵形式的基)特别费劲。这时候,“人工变量法”就派上用场了,它本质上是一种“无中生有”的启动技巧,通过引入一些额外的、成本极高的“人工变量”,强行构造出一个初始可行基,让单纯形法这个引擎先转起来,然后再想办法把这些“临时工”清退掉,找到原问题的真解。
今天咱们不聊枯燥的理论,直接上手拆解一个经典案例的第二次迭代全过程。为什么是第二次?因为第一次迭代往往是初始化,相对简单。第二次迭代开始,才是检验算法理解、计算功底和逻辑判断的关键。我们会一步步走过中心元变换、检验数计算、最优解判定,再到选择入基和出基变量。这个过程里,任何一个计算失误或者逻辑误判,都会导致后续全盘皆错。我结合自己多年教学和解决实际项目的心得,把容易踩坑的地方和提速技巧都揉进去讲清楚。
2. 案例回顾与第二次迭代的起始状态
为了后续讨论有个落脚点,我们先明确一下案例的初始模型。假设我们面对这样一个线性规划问题(标准化后):
目标函数:Max Z = 3x₁ + 5x₂ 约束条件:
- x₁ + x₃ = 4
- 2x₂ + x₄ = 12
- 3x₁ + 2x₂ + x₅ = 18
- x₁, x₂, x₃, x₄, x₅ ≥ 0
这里x₃, x₄, x₅是松弛变量,已经构成了一个单位矩阵的初始可行基,所以不需要人工变量。但为了演示人工变量法的迭代,我们假设一个更复杂的情况:假如第三个约束原来是3x₁ + 2x₂ ≥ 18,我们引入了剩余变量x₅(值为负,不可行)和人工变量R₁。经过第一次迭代(大M法或两阶段法),人工变量R₁已被替换出基,我们得到了一个不含人工变量的可行基,假设这个基是(x₃, x₄, x₂),对应的单纯形表如下(这是第二次迭代的起点):
| 基变量 | 系数 | x₁ | x₂ | x₃ | x₄ | x₅ | R₁ | 解 (b) |
|---|---|---|---|---|---|---|---|---|
| x₃ | 0 | 1 | 0 | 1 | 0 | -1/2 | ... | 1 |
| x₄ | 0 | 0 | 0 | 0 | 1 | 1 | ... | 6 |
| x₂ | 5 | 3/2 | 1 | 0 | 0 | 1/2 | ... | 9 |
| 检验数 σⱼ | -9/2 | 0 | 0 | 0 | 5/2 | ... | Z=45 |
注意:上表中
R₁列已被忽略,因为人工变量出基后,其列在后续计算中不再参与迭代,可以删除以避免干扰。...代表该列数据已无关紧要。解的值和系数是假设的,用于演示。
这个表就是我们的“战场”。Z=45是当前基可行解下的目标函数值。现在,我们要开始第二次迭代,目标是判断这个解是否最优,如果不是,就改进它。
2.1 理解当前表格的“格局”
在动手计算前,先花半分钟看清表格的格局,这能避免低级错误:
- 基变量列:当前在基中的是
x₃,x₄,x₂。它们的系数(目标函数中的系数C_B)分别是0, 0, 5。 - 解列 (b):给出了当前基变量的取值:
x₃=1,x₄=6,x₂=9。非基变量x₁和x₅取值为0。 - 检验数行 (σⱼ):这是判断是否最优的生命线。其计算公式为
σⱼ = Cⱼ - C_B * B⁻¹ * Pⱼ,在表格计算中体现为σⱼ = Cⱼ - (基变量系数与对应列向量内积)。
3. 最优解判定与入基变量选择
单纯形法的核心逻辑是:如果所有检验数 σⱼ ≤ 0(最大化问题),则当前解为最优解;否则,选择检验数最大的正数对应的变量进入基,以最快提升目标函数。
3.1 计算与判定
根据上表,非基变量x₁和x₅的检验数分别为:
σ₁ = -9/2 = -4.5σ₅ = 5/2 = 2.5
判定结果:存在正检验数σ₅ = 2.5 > 0,因此当前解不是最优解。目标函数值还有提升的空间。
选择入基变量:在所有正检验数中,σ₅是唯一的正数(σ₁为负),因此入基变量确定为x₅。选择最大正检验数变量入基,被称为“最速上升规则”,它通常能减少迭代次数。
实操心得:这里有个易错点。如果两个检验数都是正数,比如
σ₁=3,σ₅=2,那么选x₁入基。但有些教材或软件会采用“Bland规则”(选下标最小的变量)来防止循环,不过在非退化的普通案例中,用最速上升规则更直观高效。咱们手算时,认准“最大正数”就行。
4. 出基变量选择与中心元确定
确定了谁进来 (x₅),接下来就要决定谁出去。原则是可行性原则,即保证新的基解仍然所有变量≥0。
4.1 计算比值(θ规则)
我们需要查看入基变量x₅所在的列(常称“主元列”或“枢轴列”)中,对应于当前基变量行中正系数的那些行。计算每一行的比值θᵢ = 解 bᵢ / 主元列系数 aᵢ₅。
从表中提取数据:
- 对于基变量
x₃行:b₃ = 1,a₃₅ = -1/2。系数为负,忽略。因为如果用一个负系数去除正数,得到的比值是负的,这不符合“替换后变量非负”的几何意义(相当于沿可行域边界反向移动)。 - 对于基变量
x₄行:b₄ = 6,a₄₅ = 1。系数为正,θ₄ = 6 / 1 = 6。 - 对于基变量
x₂行:b₂ = 9,a₂₅ = 1/2。系数为正,θ₂ = 9 / (1/2) = 18。
比值集合:{θ₄=6, θ₂=18}。
4.2 确定出基变量
选择比值集合中最小的非负比值对应的基变量出基。这里最小比值是θ₄ = 6,它对应基变量x₄。
因此,出基变量是x₄。
注意事项:为什么选最小比值?这保证了将入基变量
x₅的值从0增加到这个最小比值时,出基变量x₄的值刚好降到0,而其他所有基变量仍保持非负。如果超过了这个最小比值,x₄将变为负值,解就不可行了。这是单纯形法能始终在可行域顶点间移动的关键。
4.3 确定中心元
入基列 (x₅) 与出基行 (x₄行) 交叉位置的元素,称为中心元或枢轴元素。 在这个案例中,中心元就是a₄₅ = 1。
5. 中心元变换:表格更新的核心操作
这是整个迭代中最需要细心和耐心的计算环节,目的是通过行初等变换,将中心元变为1,并将其所在列的其他元素(包括检验数行)变为0,从而让入基变量x₅替换出基变量x₄,形成新的单位矩阵基。
我们的目标是得到关于新基(x₃, x₅, x₂)的单纯形表。
5.1 变换步骤详解
设中心元位于第r行(出基行),第k列(入基列),其值为a_rk。变换规则如下:
更新出基行(第r行,即x₄行):将整个出基行除以中心元
a_rk,使中心元变为1。- 新
x₄行(即将被替换为x₅行):[0, 0, 0, 1, 1, ..., 6]÷ 1 =[0, 0, 0, 1, 1, ..., 6] - 实际上,因为中心元已经是1,这一行数值不变。但基变量需要改变:该行对应的基变量由
x₄替换为x₅,其系数C_B由原来的0变为x₅在目标函数中的系数。这里我们需要知道原问题中x₅的系数。假设x₅是剩余变量或松弛变量,其系数为0。所以新行的系数C_B变为0。
- 新
更新其他基变量行(第i行,i≠r)和检验数行:对于这些行,用该行减去(其主元列系数
a_ik乘以新的出基行)。- 公式:
新行 = 旧行 - (a_ik) * 新出基行
- 公式:
让我们一步步计算:
已知:
- 新出基行(即未来的
x₅行):L_r_new = [0, 0, 0, 1, 1, ..., 6](基变量为x₅, C_B=0) - 旧
x₃行:L₃_old = [1, 0, 1, 0, -1/2, ..., 1],a₃₅ = -1/2 - 旧
x₂行:L₂_old = [3/2, 1, 0, 0, 1/2, ..., 9],a₂₅ = 1/2 - 旧检验数行:
σ_old = [-9/2, 0, 0, 0, 5/2, ..., Z=45],a_σ₅ = 5/2
计算新x₃行:L₃_new = L₃_old - (-1/2) * L_r_new = L₃_old + (1/2) * L_r_new=[1, 0, 1, 0, -1/2, ..., 1] + (1/2)*[0, 0, 0, 1, 1, ..., 6]=[1, 0, 1, 0, -1/2, ..., 1] + [0, 0, 0, 1/2, 1/2, ..., 3]=[1, 0, 1, 1/2, 0, ..., 4]
计算新x₂行:L₂_new = L₂_old - (1/2) * L_r_new=[3/2, 1, 0, 0, 1/2, ..., 9] - (1/2)*[0, 0, 0, 1, 1, ..., 6]=[3/2, 1, 0, 0, 1/2, ..., 9] - [0, 0, 0, 1/2, 1/2, ..., 3]=[3/2, 1, 0, -1/2, 0, ..., 6]
计算新检验数行:σ_new = σ_old - (5/2) * L_r_new=[-9/2, 0, 0, 0, 5/2, ..., 45] - (5/2)*[0, 0, 0, 1, 1, ..., 6]=[-9/2, 0, 0, 0, 5/2, ..., 45] - [0, 0, 0, 5/2, 5/2, ..., 15]=[-9/2, 0, 0, -5/2, 0, ..., 30]
5.2 得到第二次迭代后的新表
将上述结果整理,并更新基变量和系数,得到第二次迭代完成后的单纯形表:
| 基变量 | 系数 | x₁ | x₂ | x₃ | x₄ | x₅ | 解 (b) |
|---|---|---|---|---|---|---|---|
| x₃ | 0 | 1 | 0 | 1 | 1/2 | 0 | 4 |
| x₅ | 0 | 0 | 0 | 0 | 1 | 1 | 6 |
| x₂ | 5 | 3/2 | 1 | 0 | -1/2 | 0 | 6 |
| 检验数 σⱼ | -9/2 | 0 | 0 | -5/2 | 0 | Z=30 |
核心技巧:中心元变换时,建议在草稿纸上严格按公式
新行 = 旧行 - 系数 * 新出基行一步步计算,并立即检查新表中:
- 入基列 (
x₅列) 是否已变为单位向量[0, 1, 0]^T?是的。- 基变量对应的列(
x₃,x₅,x₂)是否构成一个单位矩阵?检查:x₃列[1,0,0]^T,x₅列[0,1,0]^T,x₂列[0,0,1]^T。是的,说明行变换正确。- 解列
b是否全部非负?[4,6,6]^T≥0,解是可行的。
6. 第二次迭代结果分析与后续路径
现在,我们站在了一个新的顶点上。新基是(x₃=4, x₅=6, x₂=6),非基变量是x₁和x₄,目标函数值Z=30。
再次进行最优解判定:检查检验数行。
σ₁ = -9/2 = -4.5 < 0σ₄ = -5/2 = -2.5 < 0所有非基变量的检验数均为负数。
结论:对于这个最大化问题,当前解即为最优解。因为任何一个非基变量(x₁或x₄)的值从0增加,都会导致目标函数值下降(检验数为负)。
最优解解读:
x₁* = 0,x₂* = 6,x₃* = 4,x₄* = 0,x₅* = 6。- 最大化的目标函数值
Z* = 30。 - 其中
x₃和x₅是松弛/剩余变量,它们的值代表了对应约束资源的“剩余”或“不足”。在这个解中,第一个约束有4单位剩余 (x₃=4),第三个约束有6单位剩余 (x₅=6),而第二个约束资源被完全利用 (x₄=0)。
7. 人工变量法全流程中的关键陷阱与排查
虽然我们演示的案例在第二次迭代后就达到了最优,但在完整的人工变量法(尤其是大M法)中,从引入人工变量到最终得到原问题最优解,整个过程布满“坑点”。
7.1 陷阱一:大M法中M取值不当导致判断失误
问题:在目标函数中,人工变量系数为-M(最大化问题)或+M(最小化问题)。如果手算时M取值不够“大”,在检验数计算中,一个很小的正系数乘以M可能无法在数值上显著大于其他普通变量的系数,导致错误地选择入基变量,甚至误判最优解。
排查与解决:
- 心算比较法:在计算检验数
σⱼ = Cⱼ - Σ(C_B * a_ij)时,将含M的项单独列出。例如,如果检验数形如σ = 5 - (2M + 3),直接将其视为-2M + 2。比较不同检验数时,优先比较M的系数。系数更负(对最大化问题)的检验数更小。只有在M系数相同时,才比较常数项。 - 两阶段法优先:对于手算或编程初学,强烈推荐使用两阶段法代替大M法。第一阶段目标函数仅为“最小化人工变量之和”,完全避免了M这个抽象大数,计算更清晰,不易出错。
7.2 陷阱二:迭代过程中出现退化与循环
问题:在确定出基变量时,如果最小比值θ出现两个或更多相同的值,则新解中会有基变量取值为0,称为“退化”。在极端罕见情况下,可能导致单纯形法在几个基可行解之间无限循环,永远达不到最优。
排查与解决:
- 识别退化:当计算θ规则时,出现两个相同的、最小的非负比值。
- Bland规则:这是理论上避免循环的可靠方法。规则是:1) 选择入基变量时,在所有正检验数中选下标最小的变量;2) 选择出基变量时,在所有达到最小比值的行中,选下标最小的基变量。在实际的非退化问题中很少需要,但了解它能帮你理解算法完备性。
- 扰动法思想:可以想象给每个约束的右端常数b加上一个极其微小的、不同的正数ε,理论上可以消除退化。手算时若遇到退化,按Bland规则操作即可。
7.3 陷阱三:第一阶段结束时人工变量未全部出基
问题:在两阶段法中,第一阶段目标是消除所有人工变量。若第一阶段最终最优值(人工变量之和)> 0,说明原问题无可行解。
排查与解决:
- 明确结论:如果第一阶段结束时,即使目标值最小化了,但仍有人工变量 > 0(即还在基中且值为正),或人工变量虽为0但仍在基中(退化情况),而目标函数值>0,则直接判定原问题无可行解。无需进入第二阶段。
- 检查约束:此时应回头仔细检查原问题的约束条件是否互相矛盾。例如,是否同时要求
x1 + x2 ≤ 5和x1 + x2 ≥ 10。
7.4 陷阱四:中心元变换时的计算错误
这是最常出错的环节,错误会像滚雪球一样影响后续所有迭代。
系统性排查清单:
- 符号错误:
新行 = 旧行 - 系数 * 新出基行中的减号是否写成了加号?特别是当系数为负数时,容易混淆。 - 系数用错:用于相乘的系数
a_ik,必须是变换前旧表中该行在入基列的系数,而不是其他列的系数。 - 行覆盖顺序:建议先计算出所有新行(包括检验数行)写在草稿上,全部验算无误后,再誊写到新表中。避免在原表上直接修改导致数据混乱。
- 单位矩阵验证:变换后,立即检查新基变量对应的列是否构成单位矩阵。这是检验行变换是否正确的“金标准”。
8. 从理论到实践:算法思想与手工计算技巧
最后,我想分享一下超越这个具体案例的思考。人工变量法(包括大M法和两阶段法)的本质,是一种可行性搜索优先于最优性搜索的策略。它承认“找到一个起点可能比直接找最优点更难”,于是通过引入“惩罚项”或“辅助问题”来搭建一个通往可行域的桥梁。这种“分阶段解决”的思想在优化领域非常普遍。
对于手工计算,我有几个压箱底的技巧:
- 表格格式化:画表时上下左右对齐,每个格子只写一个数字。清晰的版面能极大降低看串行的概率。
- 分步检查点:每完成一次迭代,强制自己进行三个检查:1) 基列是单位阵吗?2) b列全非负吗?3) 基变量对应的检验数是0吗?这三个都满足,计算基本没问题。
- 利用对称性:在中心元变换时,出基行以外的行,其变换本质是“消去”入基列中该行的元素。你可以盯着目标,心算“需要乘以多少倍的出基行,才能把我这一行入基列的数变成0”,这个乘数就是
a_ik。
这个案例的第二次迭代,完整展示了单纯形法从一个可行基移动到另一个更优可行基的机械但精妙的步骤。掌握它,你不仅掌握了线性规划的一种计算方法,更理解了一种“迭代改进”的优化思想。无论是后续学习对偶理论、灵敏度分析,还是接触更复杂的整数规划、非线性规划,这种从局部信息(检验数)做出决策(入基/出基),通过局部操作(行变换)更新全局状态(单纯形表)的模式,都会反复出现。