列生成算法在多重背包问题中的应用示例
题目描述
考虑一个多重背包问题:假设有 \(n\) 种物品,每种物品 \(i\) 的价值为 \(p_i\),重量为 \(w_i\),且最多可选取 \(b_i\) 个(\(b_i\) 为有限整数)。背包的总容量限制为 \(C\)。目标是在不超过背包容量的前提下,选择物品(每种物品可选多个,但不超过 \(b_i\)),使得总价值最大。该问题可建模为整数规划,但直接求解效率低。列生成算法通过将问题分解为主问题(限制主问题)和子问题(定价问题),逐步生成有价值的列(即物品的选取模式)来逼近最优解。
解题过程
- 问题建模
标准整数规划模型为:
\[ \max \sum_{i=1}^n p_i x_i \]
\[ \text{s.t.} \quad \sum_{i=1}^n w_i x_i \leq C, \quad 0 \leq x_i \leq b_i, \quad x_i \in \mathbb{Z}^+. \]
其中 \(x_i\) 表示选择物品 \(i\) 的数量。直接求解该模型在 \(n\) 较大时计算复杂。
- 列生成框架
- 主问题(Master Problem, MP):
将物品选取模式视为列。设 \(\lambda_j\) 表示使用第 \(j\) 种模式的比例(连续松弛),模式 \(j\) 由向量 \(a_j = (a_{1j}, a_{2j}, \dots, a_{nj})\) 定义,其中 \(a_{ij}\) 表示该模式下物品 \(i\) 的数量。主问题为:
- 主问题(Master Problem, MP):
\[ \max \sum_j \left( \sum_{i=1}^n p_i a_{ij} \right) \lambda_j \]
\[ \text{s.t.} \quad \sum_j \left( \sum_{i=1}^n w_i a_{ij} \right) \lambda_j \leq C, \quad \sum_j \lambda_j \leq 1, \quad \lambda_j \geq 0. \]
初始时,主问题包含少量列(如空模式或简单启发式生成的列)。
- 限制主问题(Restricted Master Problem, RMP):
仅使用已生成列的子集求解主问题的线性松弛。
- 定价问题(Pricing Problem)
- 计算当前 RMP 的对偶变量:设容量约束的对偶变量为 \(\pi\),模式数量约束的对偶变量为 \(\sigma\)。
- 子问题目标是找到减少成本(reduced cost)最大的列,即求解:
\[ \max \sum_{i=1}^n p_i a_i - \pi \left( \sum_{i=1}^n w_i a_i \right) - \sigma \]
\[ \text{s.t.} \quad 0 \leq a_i \leq b_i, \quad a_i \in \mathbb{Z}^+. \]
该问题实际是一个单约束背包问题(每个物品有数量上限),可用动态规划快速求解。若最大减少成本非正,则当前解为最优;否则,将新列加入 RMP。
-
迭代步骤
- 步骤 1:初始化 RMP,包含可行列(如空列)。
- 步骤 2:求解 RMP 的线性松弛,得到对偶变量 \(\pi\) 和 \(\sigma\)。
- 步骤 3:求解定价问题,若最大减少成本 \(\leq 0\),停止迭代;否则,将新列加入 RMP。
- 步骤 4:重复步骤 2–3 直至收敛。
- 步骤 5:最终通过整数规划求解器处理 RMP 的整数约束(如需整数解)。
-
示例说明
假设有 3 种物品:- 物品 1:\(p_1=10, w_1=5, b_1=2\)
- 物品 2:\(p_2=8, w_2=3, b_2=3\)
- 物品 3:\(p_3=6, w_3=2, b_3=4\)
背包容量 \(C=10\)。- 初始列:空列(价值 0,重量 0)。
- 第一次迭代:定价问题求解得新列 \(a=(2,0,0)\)(价值 20,重量 10),减少成本为 20。加入后 RMP 更新。
- 后续迭代生成更优列(如混合模式),直至减少成本非正。
关键点
- 列生成通过动态生成列避免枚举所有可能模式,适合大规模问题。
- 定价问题需高效求解(如动态规划),确保算法效率。
- 最终可能需结合分支定界获得整数解(分支定价)。