最近发布到 sci.op-research 的一个问题让我从一些我不想去想而你也不想听到的乏味工作中得到了一个可喜的喘息机会。我们知道,贪心启发式求解连续背包问题最大化c′xs.ta′x≤bx≤ux∈ℜ+n(1)到最优。(证明,使用对偶理论,很容易。)假设我们添加一个我称之为计数约束的东西,产生 Maximizec′xs.ta′x≤be′x=b~x≤ux∈ℜ+n(2 ) 其中 e=(1,…,1) 。是否可以通过单纯形法以外的方法解决,例如贪心启发式的变体?
答案是肯定的,尽管我完全不确定我想出的方法是否比单纯形法更容易编程或更有效。就个人而言,我会链接到带有线性规划求解器的库并使用单纯形法,但找到替代方案很有趣,即使替代方案可能不是单纯形法的改进。
我将介绍的方法依赖于对偶,特别是一个众所周知的结果,如果一个线性规划的可行解和它的对偶的可行解满足互补松弛条件,那么两者在各自的问题中都是最优的。我将分别表示背包和计数约束 λ 和 μ 的对偶变量。请注意,λ≥0 但 μ 在符号上不受限制。本质上,下面所述的相同方法适用于不等式计数约束(e'x≤b~),实际上会稍微容易一些,因为我们会先验地知道 μ(非负)的符号。原始问题的海报指定了一个相等计数约束,所以这就是我将使用的。上限也有对偶变量(ρ≥0)。对偶问题是最小化bλ+b~μ+u′ρs.t.λa+μe+ρ≥cλ,ρ≥0.(3)
这是一篇博文而不是论文,我将假设 (2) 是可行的,所有参数都是严格正数,并且最优解是唯一的且不会退化。唯一性和简并性不会导致算法无效,但它们会使表示复杂化。在 (2) 的最优基本可行解决方案中,将有一个或两个基本变量——一个如果背包约束是非绑定的,两个如果它是绑定的——每个其他变量都是非基本变量的下限或上限。假设 (λ,μ,ρ) 是 (2) 的对偶的最优解。任何变量 xi 的降低成本是 ri=ci−λai−μ 。如果背包约束是非约束性的,则λ=0,最优解是xi=uiri>0b~-∑rj>0ujri=00ri<0。(4) 如果背包约束是约束性的,则有两个项目(j , k ),其变量是基本的, rj=rk=0 。(通过假设没有退化,我假设背包约束中的松弛变量是基本的值为0的可能性)。设 xi=uiri>00ri<0(5) 并令 b′=b−∑i∉{j,k}aixi 和 b~′=b~−∑i∉{j,k}xi 。两个基本变量由 xj=b′-akb~′aj-akxk=b′-ajb~′ak-aj 给出。 (6)
该算法将分两个阶段进行,首先寻找具有背包非绑定(一个基本 x 变量)的解决方案,然后寻找具有背包绑定(两个基本 x 变量)的解决方案。请注意,我们第一次找到服从互补松弛的可行原始和对偶解决方案时,两者都必须是最优的,所以我们完成了。还要注意,给定任何 μ 和任何 λ≥0 ,我们可以通过设置 ρi=ci−λai−μ+ 来完成它以获得 (3) 的可行解。因此,我们将始终处理可行的对偶解,并且该算法将构造满足互补松弛度的原始解。因此,停止标准简化为构造的原始解决方案是可行的。
对于第一阶段,我们对变量进行排序,使得 c1≥⋯≥cn 。由于 λ=0 并且存在单个基本变量 (xh ),其降低成本必须为零,显然 μ=ch 。这意味着 xi 的降低成本 ri=ci−λai−μ=ci−ch 对于 ih 是非负的。如果 (3) 给出的解是可行的——也就是说,如果 ∑ih 。因此我们可以使用二分搜索来完成这个阶段。如果我们假设 n 的值很大,则初始排序可以在 O(nlogn) 时间内完成,而该阶段的其余部分需要 O(logn) 次迭代,每次迭代都使用 O(n) 次。
不幸的是,我没有看到将二等分搜索应用于第二阶段的方法,在该阶段中,我们寻找背包约束为绑定且 λ>0 的解决方案。我们将再次搜索 μ 的值,但这次是单调的。首先将贪心启发式应用于问题(1),保留背包约束但忽略计数约束。如果解决方案偶然满足计数约束,我们就完成了。但是,在大多数情况下,将违反计数约束。如果计数超过 b~ ,那么我们可以推断 (4) 中 μ 的最优值为正;如果计数低于 b~ ,则 μ 的最佳值为负。我们以 μ=0 开始第二阶段,并朝着最优值的方向移动。
由于贪心启发式对项目进行排序使得 c1/a1≥⋯≥cn/an ,并且由于我们从 μ=0 开始,因此我们当前的排序顺序为 (c1−μ)/a1≥⋯≥(cn−μ)/an . 当我们搜索 μ 的最佳值时,我们将保留该排序(根据需要重新排序)。为避免混淆(我希望如此),让我假设 μ 的最佳值为正,这样我们将不断增加 μ。我们正在寻找 (λ,μ) 的值,其中 x 变量中有两个是基本变量,这意味着两个变量的成本降低了 0。假设 xi 和 xj 发生这种情况;那么ri=0=rj⟹ci-λai-μ=0=cj-λaj-μ(7)⟹ci-μai=λ=cj-μaj。很容易证明(留给读者作为练习)如果 (c1−μ)/a1≥⋯≥(cn−μ)/an 对于 μ 的当前值,则 μ 的下一个更高(更低)值在 (7) 中创建平局必须涉及连续的一对连续项目 (j=i+1 )。而且,再次摆脱退化(在这种情况下意味着超过两个项目的成本降低为 0),如果我们将 μ 略微超过项目 i 和 i+1 降低成本 0 的值,排序顺序的唯一变化是项目i 和 i+1 交换位置。再往那个方向移动不会导致 i 和 i+1 再次打成平手,但当然,他们中的任何一个最终都可能与路上的新邻居打成平手。
第二阶段,从 μ=0 开始,进行如下。对于每一对 (i,i+1),计算 μ 的值 μi,其中 (ci−μ)/ai=(ci+1−μ)/ai+1 ;如果该值小于 μ 的当前值(表示平局发生在错误的方向),则将该值替换为 ∞。将 μ 更新为 miniμi ,从 (7) 计算 λ,并从 (5) 和 (6) 计算 x。如果 x 是原始可行的(减少到 0≤xi≤ui 和 0≤xi+1≤ui+1 ),则 stop: x 是最优的。否则按排序顺序交换 i 和 i+1,设置 μi=∞(重新索引的项目 i 和 i+1 不会再次绑定)并重新计算 μi-1 和 μi+1(没有其他 μj 受交换影响)。
如果第一阶段没有找到最优值(并且如果第二阶段开始时的贪婪启发式算法没有走运),则第二阶段必须以最优值结束,然后才能检查出 μ 值(所有 μj= ∞ )。可以通过在编码中付出一点额外努力来处理退化(例如,当出现三向或更高的关系时,在第二阶段检查 i 和 j 的多个组合)或通过进行小扰动来打破退化。