基于线性规划的图Steiner树问题的分支切割法求解示例
我将为您讲解图Steiner树问题的一个分支切割法求解示例,这个问题是经典的组合优化问题,在通信网络设计等领域有重要应用。
问题描述:Steiner树问题
问题背景:
给定一个无向连通图 \(G=(V,E)\),其中 \(V\) 是顶点集,\(E\) 是边集,每条边 \(e \in E\) 有一个非负费用 \(c_e\)。同时给定一个终端顶点集合 \(T \subseteq V\)(称为Steiner点集),要求找到一个包含 \(T\) 中所有顶点的连通子图,且总边费用最小。这个子图必然是一棵树(称为Steiner树),它可以包含非终端顶点(称为Steiner顶点)来减少总费用。
难点:
这是一个NP难问题。当 \(T = V\) 时,退化为最小生成树问题,可在多项式时间内求解。但当 \(T \subset V\) 时,寻找最优解是困难的。
整数规划模型:
我们采用基于割的模型。定义决策变量 \(x_e \in \{0,1\}\),表示边 \(e\) 是否被选中。
目标函数:最小化总费用
\[\min \sum_{e \in E} c_e x_e \]
约束条件:
- 连通性约束:对于任意割 \((S, V \setminus S)\) 使得 \(S \cap T \neq \emptyset\) 且 \((V \setminus S) \cap T \neq \emptyset\)(即割分离了至少两个终端顶点),被选边集必须跨越该割至少一次。
\[\sum_{e \in \delta(S)} x_e \ge 1 \quad \forall S \subset V: S \cap T \neq \emptyset, T \setminus S \neq \emptyset \]
其中 \(\delta(S)\) 表示一个端点属于 \(S\)、另一个端点不属于 \(S\) 的边集。
- 整数性约束:
\[x_e \in \{0,1\} \quad \forall e \in E \]
这个模型有指数数量的约束(每个合法割对应一个约束),因此无法直接列出所有约束求解。
解题过程:分支切割法
我们使用分支切割法(Branch-and-Cut),它结合了分支定界和割平面法。核心思想:在分支定界树的每个节点,求解线性规划松弛(可能加入部分割约束),然后检查当前分数解是否违反未加入的割约束;若是,则找到相应的割平面加入线性规划,重新求解;重复直至解满足所有割约束或确定加入足够割平面,再进行分支。
步骤1:初始化线性规划松弛
初始松弛仅包含度约束(可选,可加快收敛)和变量边界。
- 目标函数:\(\min \sum_{e \in E} c_e x_e\)
- 约束:
\[ 0 \le x_e \le 1 \quad \forall e \in E \]
通常还会加入:对于每个终端顶点 \(v \in T\),其关联边被选数量至少为1(除非 \(|T|=1\)):
\[ \sum_{e \in \delta(\{v\})} x_e \ge 1 \quad \forall v \in T \]
但这不保证全局连通性,所以后续需要割平面。
初始松弛最优解可能是全0或某些边选一小部分分数,显然不满足连通性。
步骤2:割平面生成(分离问题)
求解当前线性规划得到分数解 \(x^*\)。我们需要检查是否存在被违反的割约束,即是否存在 \(S\) 使得:
\[\sum_{e \in \delta(S)} x_e^* < 1 \]
且 \(S \cap T \neq \emptyset\), \(T \setminus S \neq \emptyset\)。
这等价于:在当前图 \(G\) 上,边权为 \(x_e^*\),寻找一个最小容量的割 \((S, V \setminus S)\) 满足 \(S\) 分离了 \(T\)。若该最小割容量 \(< 1\),则对应约束被违反。
分离算法:
- 固定一个终端顶点 \(r \in T\) 作为根。
- 对于每个其他终端顶点 \(t \in T \setminus \{r\}\):
- 计算从 \(r\) 到 \(t\) 在边权 \(x^*\) 下的最大流(最小割)。
- 若最大流值 \(< 1\),则得到被违反的割 \(S\)(包含 \(r\) 的割集),加入割平面:
\[ \sum_{e \in \delta(S)} x_e \ge 1 \]
- 由于对称性,通常检查所有终端对 \((r,t)\) 即可保证找到所有被违反的割(实践中也可随机选根,或检查几个根)。
加入割平面后,重新求解线性规划。
步骤3:迭代割平面加入
重复步骤2,直至对每个终端对 \((r,t)\),最大流值均 \(\ge 1\)。此时分数解 \(x^*\) 满足所有连通性约束(实际是满足所有终端对之间的最小割至少为1,这等价于全局连通性),得到一个可行的线性规划松弛解,其目标值是原问题最优值的下界。
步骤4:分支定界
若此时所有 \(x_e^*\) 都是整数(0或1),则得到整数最优解,算法结束。否则,选择某个分数变量 \(x_e\)(例如最接近0.5的),进行分支:
- 左分支:强制 \(x_e = 0\)
- 右分支:强制 \(x_e = 1\)
对每个子节点,重复步骤1-3(求解线性规划松弛并加入割平面),得到该节点的下界。如果某个节点的下界超过当前已知整数解的上界,则剪枝。如果得到整数解,则更新上界。
继续分支,直至所有节点处理完毕,此时得到最优解。
示例演示
考虑一个小型图示例:
- 顶点:\(V = \{1,2,3,4\}\)
- 边及费用:
\(e_{12}: c=3\)
\(e_{13}: c=4\)
\(e_{14}: c=5\)
\(e_{23}: c=2\)
\(e_{24}: c=3\)
\(e_{34}: c=1\) - 终端顶点集:\(T = \{1,2,3\}\)(顶点4是潜在的Steiner顶点)
步骤1:初始松弛
初始线性规划:
\[\min 3x_{12} + 4x_{13} + 5x_{14} + 2x_{23} + 3x_{24} + x_{34} \]
s.t.
\[0 \le x_e \le 1 \quad \forall e \]
加上终端度约束(可选):
\[x_{12}+x_{13}+x_{14} \ge 1 \]
\[ x_{12}+x_{23}+x_{24} \ge 1 \]
\[ x_{13}+x_{23}+x_{34} \ge 1 \]
求解得:\(x_{12}=0.5, x_{13}=0.5, x_{23}=0.5\),其他为0,目标值=4.5。
步骤2:割平面分离
选择根 \(r=1\),检查终端对 (1,2):
- 边权 \(x^*\) 下,从1到2的最大流路径:1→2直接容量0.5,1→3→2容量 min(0.5,0.5)=0.5,总最大流=1.0(等于1,不违反)。
检查 (1,3): - 1→3直接容量0.5,1→2→3容量 min(0.5,0.5)=0.5,总最大流=1.0。
因此当前解满足所有终端对割约束,无需加割。
但解是分数,需要分支。
步骤3:分支
选择 \(x_{12}\)(值为0.5)分支。
左分支:\(x_{12}=0\)
求解线性规划(加上 \(x_{12}=0\)),得:
\(x_{13}=0.5, x_{23}=0.5, x_{34}=0.5\),其他为0,目标值=3.5。
检查割:根 r=1,对终端2:1→3→2路径容量 min(0.5,0.5)=0.5,无其他路径,最大流=0.5 < 1,违反。
对应的割 S={1,3,4}(从1可达的点集),加入割:
\[x_{13}+x_{14}+x_{34} \ge 1 \]
重新求解,得:\(x_{13}=0.5, x_{23}=0.5, x_{34}=0.5\) 仍满足新约束(左端=0.5+0+0.5=1)。继续检查其他终端对,无违反。目标值=3.5。
解仍分数,可继续分支(但先看右分支)。
右分支:\(x_{12}=1\)
求解线性规划(加上 \(x_{12}=1\)),得:
\(x_{12}=1, x_{23}=0, x_{13}=0, x_{34}=1, x_{14}=0, x_{24}=0\),目标值=3+1=4。
检查所有终端对连通性:
- 1到2:直接边,满足。
- 1到3:路径1→2→? 无,但1→? 可通过1→? 不直接;实际上,1通过边12到2,但2到3无边,且2到4无边,4到3有边x34=1,但1到4无边。因此1和3不连通!这意味着需要检查割。
计算从1到3的最大流:在分数解中,1→2容量1,但2→3容量0,2→4容量0,所以从1无法到3,最大流=0,违反。
对应割 S={1,2},加入割:
\[x_{13}+x_{14}+x_{23}+x_{24} \ge 1 \]
重新求解,得:\(x_{12}=1, x_{34}=1, x_{23}=0, x_{13}=0, x_{14}=0, x_{24}=0\) 不满足新约束(左端=0),需调整。
求解后得新解:\(x_{12}=1, x_{23}=1, x_{34}=0\),其他为0,目标值=3+2=5。
检查连通性:此时1-2-3连通,但终端集T={1,2,3}已连通,所以是可行整数解(Steiner树为边12和23),费用=5。
步骤4:回溯与比较
左分支下界=3.5,右分支整数解=5。全局上界=5。
继续分支左分支(下界3.5),可能得到更优解。若在左分支继续分支并找到整数解,比如选择 \(x_{13}\) 分支,可能得到树 {13,23} 费用=6,或树 {13,34,12?} 等。最终搜索得到最优解可能是 {23,34,13}? 但费用=2+1+4=7,不如5。实际上,枚举可知最优Steiner树为 {12,23} 费用5,或 {12,24,34,13}? 包含Steiner顶点4的树 {12,24,34} 费用=3+3+1=7 更差。但本例中,Steiner顶点4并未帮助减少费用。
因此最优解为边 {12,23},总费用=5。
总结
分支切割法通过动态加入割平面来强化线性规划松弛,从而获得紧的下界,并结合分支定界搜索整数解。对于Steiner树问题,割平面分离转化为最大流问题,可在多项式时间内完成,这使得该方法能够处理中等规模的问题实例。在实际软件(如ILOG CPLEX、SCIP)中,这些过程已自动化,用户只需定义模型,求解器会自动处理分支切割。