寻找图中最小反馈顶点集(Minimum Feedback Vertex Set)问题的精确算法(分支定界法)
题目描述
给定一个有向图或无向图 G = (V, E),我们希望找到一个最小反馈顶点集,即一个顶点集合 S ⊆ V,使得从图中删除 S 中的所有顶点后,剩下的子图是一个有向无环图(对于有向图)或森林(即无环图,对于无向图)。集合 S 的大小尽可能小。这是一个 NP 难问题。我们将通过分支定界法,结合一些归约规则,来系统地搜索最优解。
解题过程
步骤1:理解问题与目标
- 在无向图中,反馈顶点集移除后剩下一个森林(无环图)。
- 在有向图中,反馈顶点集移除后剩下一个有向无环图(DAG)。
- 由于 NP 难,穷举所有顶点子集(2^n 种)不可行。分支定界法将搜索树剪枝,加速求解。
- 我们将以无向图为例讲解,但算法思想可扩展到有向图。
步骤2:核心思想与归约规则
分支定界法 = 系统搜索 + 下界(剪枝) + 归约规则(缩小图规模)。
归约规则可降低问题规模,无需分支:
- 度数为1的顶点:如果存在顶点 v 的度数 ≤ 1,则 v 不可能出现在任何环中,因此可以直接删除(不放入反馈集)。
- 自环顶点:如果有自环,则该顶点必须加入反馈集(因为自环本身就是环),直接将其加入解集并删除。
- 多重边:多重边在无向图中可视为单条边,不影响环结构,可合并。
- 度数为2的顶点折叠(可选优化):如果一个顶点 v 恰好有两个邻居 u 和 w,则可以删除 v 并将 u 和 w 用一条新边连接(如果 u-w 间无边)。此时任何包含 v 的环可转化为包含 u 和 w 的环,但反馈集大小计算需调整(v 是否在反馈集中会影响 u 或 w 的计数,需记录权重或后处理,这里为简化先不展开)。
- 支配点规则:如果顶点 u 的所有邻居也是顶点 v 的邻居(即 N(u) ⊆ N(v)),则优先考虑将 u 放入反馈集,因为去掉 u 可能比去掉 v 更优。实际中,可合并 u 到 v 的权重等。
步骤3:算法框架
- 初始化:当前反馈集 S_curr = ∅,当前最优解 S_best = V(上界 = |V|),当前图 G_curr = 输入图。
- 反复应用归约规则简化 G_curr,并更新 S_curr 和 S_best 的上界。
- 进入分支定界递归函数 search(G, S_curr, size_curr):
- 下界计算:计算当前图 G 的反馈顶点集大小的一个下界,例如:
a. 图 G 中环覆盖下界:通过最大匹配或线性规划松弛计算,但为简单实现,可用“图的最小度数”启发:反馈集至少包含 (|E| - |V| + 1) 个顶点?不精确。一个简单下界是:如果 G 中存在 k 个顶点不相交的环,则反馈集至少需要 k 个顶点(每个环至少去掉一个顶点)。找顶点不相交的环可通过贪心或最大匹配在二部图中找。
b. 实践中,可用“图的最小反馈顶点集大小的线性规划松弛下界”或“最小顶点覆盖在二部图中的近似”快速估算。 - 如果 size_curr + 下界 ≥ |S_best|,剪枝(不可能得到更优解)。
- 如果 G 无环,则找到一个可行解,若 size_curr < |S_best|,则更新 S_best。
- 否则,选择分支顶点 v:通常选度数最大的顶点,因为去掉它可以破坏更多环。
- 分支两种情况:
(1) 将 v 加入反馈集:从 G 中删除 v(及相连边),size_curr + 1,递归。
(2) 不将 v 加入反馈集:则 v 必须留在无环图中,那么所有与 v 成环的邻居需处理?实际上,当我们决定 v 不在反馈集时,我们不能简单地保留 v,而需确保删除其他顶点以破坏环。更标准的做法是:
情况2:v 不在反馈集,则 v 必须保留,此时任何包含 v 的环必须通过删除 v 的某个邻居来破坏。因此,我们可以考虑将 v 的所有邻居加入候选,但这样分支太多。更好的办法是:选择一个包含 v 的环,然后对这个环的所有顶点(除 v 外)进行分支,即至少选其中一个加入反馈集。但实现复杂。
简化策略:只分支“选 v”或“不选 v”,当不选 v 时,从图中暂时删除 v 但记录 v 必须保留,然后在后续处理中,如果形成环则通过其他方式打破。标准精确算法常用“迭代压缩”或“分支:选 v 或不选 v,不选 v 时,标记 v 为必须保留,并压缩环”。但为清晰,我们采用基本分支:选 v 或不选 v 时,在图中保留 v 但标记,然后后续再处理环。 - 实际常用更简单的分支规则:任选一条边 (u,v),分支两种情况:
a. u 在反馈集:删除 u,递归。
b. u 不在反馈集:则 u 保留,那么必须删除 v 以破坏所有包含边 (u,v) 的环?不全面。
更稳健的方法:任选一个顶点 v,分支:
(1) v 在反馈集:删除 v。
(2) v 不在反馈集:则对于每个包含 v 的环,必须删除该环中除 v 外的某个顶点。实现上,可考虑 v 的邻居集合,但为简单,我们回到基本搜索:在无归约规则可用时,选一个顶点 v 分支两种情况。
但这样效率低。
实际上,经典精确算法对无向图最小反馈顶点集采用“分支规则”:找图中一个度 ≥ 3 的顶点 v,分支 v 在解中或不在。当 v 不在解中时,由于 v 要保留且图要无环,则 v 的所有邻居中,必须删除一些顶点以破坏环,这又引出对邻居子集的分支。
为简化讲解,我们采用一个已简化的分支定界流程:
- 下界计算:计算当前图 G 的反馈顶点集大小的一个下界,例如:
步骤4:具体算法步骤
输入:无向图 G = (V, E)。
输出:最小反馈顶点集 S。
辅助:全局变量 best_size = |V|, best_set = V。
递归函数 branch_and_bound(G, S, size):
-
应用归约规则简化 G,更新 S 和 size。
-
如果 |S| ≥ best_size,剪枝返回。
-
如果 G 无环(是森林),则若 size < best_size,更新 best_size = size, best_set = S,返回。
-
否则,选择顶点 v,使得 v 的度数 ≥ 2 且在 G 中属于某个环(可通过检测连通分量和度判断)。
-
分支情况1:将 v 加入反馈集。
G' = G 删除 v 及其关联边。
branch_and_bound(G', S ∪ {v}, size + 1)。 -
分支情况2:v 不加入反馈集,则 v 必须保留,且要保证最终无环。由于 v 保留,任何包含 v 的环必须通过删除该环中除 v 外的至少一个顶点来破坏。一个实用技巧:当 v 不选时,我们可以暂时从 G 中删除 v,但标记 v 的邻居之间需要额外约束:因为 v 保留,实际上 v 是连接其邻居的路径,但为简化处理,我们可以将 v 删除,并将 v 的所有邻居两两之间加一条新边(形成团),因为通过 v 的这些邻居之间原本可能无直接边,但保留 v 时它们之间可通过 v 连通,在无环条件下,这些邻居之间不能形成新环。但更简单的方法:在 v 不加入反馈集时,我们可考虑 v 的邻居集合 N(v),然后必须从 N(v) 中选至少一个顶点加入反馈集,以破坏所有包含 v 的环。但这样分支多。
实际常用:在 v 不加入反馈集时,将 v 从图中移除,但将 v 的邻居两两连接新边(即添加边使 N(v) 成为团),因为 v 保留时,这些邻居之间通过 v 形成长度为2的路径,但添加团边是确保任何通过这些邻居的环在去掉 v 后仍能被检测。然后递归。但这样可能增加环,不直观。
鉴于复杂性,许多精确算法采用不同思路(如迭代压缩)。为教学清晰,我们采用简单分支:
分支情况2:v 不加入反馈集,则 v 必须保留,且我们要求最终图中无环,因此我们可以暂时保留 v,但后续遇到环时再处理。但这样不直接。
另一种常见分支:选择一条边 (u,v),分支:
a. u 在反馈集(删除 u)
b. u 不在反馈集,则 v 必须在反馈集(因为要破坏边 (u,v) 所在的环,且 u 保留,则必须删除 v)。
但这不是普遍正确的,因为可能有其他环不含 v 但含 u。
因此,我们回到经典分支规则(对无向图):- 如果存在顶点 v 度数 ≥ 3,分支 v 在解或 v 不在解。
- 当 v 不在解时,由于 v 度数 ≥ 3,则至少有三个邻居 a,b,c。保留 v 时,必须确保 a,b,c 之间不形成环(通过 v)。一种方法是将 v 删除,并将 a,b,c 两两连接新边,然后递归。但需记录反馈集大小不变。
- 这等价于“折叠” v 到其邻居的边。
由于详细推导较复杂,我们给出最终可实现的简化版算法步骤:
简化版分支定界步骤(基于度数和环的选择):
-
归约图直到无法归约。
-
如果图无环,更新最优解。
-
否则,选择一个顶点 v 属于某个环。
-
分支1:v 在反馈集,删除 v,递归。
-
分支2:v 不在反馈集,则我们必须确保所有含 v 的环被破坏。为此,我们可以删除 v 的所有邻居?不对,那样代价大。更精确:因为 v 不在反馈集,则任何包含 v 的环必须包含 v 的两个邻居,且这两个邻居之间的路径不经过 v 也能成环。所以我们可以考虑将 v 的邻居两两连接新边(即添加边使 N(v) 成为团),然后删除 v,递归,且反馈集大小不变。这模拟了保留 v 时,v 的邻居之间若有边则形成环(需在邻居中选点删除)。但添加团边会增加环,使得后续必须删除邻居中的点。
但此操作较复杂,因此许多实现采用更直接的方法:在 v 不在反馈集时,从图中删除 v,但增加下界,或强制在递归前预处理。鉴于教学目的,我们给出一个可工作的思路:
实际精确算法常用“分支规则”:- 如果存在顶点 v 度数 ≤ 1,归约删除 v(规则1)。
- 如果存在自环,将对应顶点加入反馈集(规则2)。
- 如果存在重边,视为单边。
- 如果存在顶点 v 度数 = 2,且邻居 u,w 之间无边,则折叠 v:删除 v,添加边 (u,w),并记录如果 u 或 w 在反馈集中,则相当于 v 不在反馈集;如果 u 和 w 都不在反馈集,则 v 必须在反馈集。可通过权重调整实现。
- 否则,选一个度数最大的顶点 v,分支:
(1) v 在反馈集:删除 v,代价+1。
(2) v 不在反馈集:则由于 v 度数 ≥ 3,可以折叠 v:删除 v,将 v 的所有邻居两两连接新边(若无边),然后递归,代价不变,但后续因新加的边可能导致环,从而必须选邻居中的点。
此方法可保证找到最优解,但实现时需记录顶点权重或后处理反馈集。
步骤5:下界计算示例
为剪枝,需快速计算下界。一个简单下界:
- 若图 G 有 n 个顶点,m 条边,则最小反馈顶点集大小 ≥ m - n + 1(因为森林最多 n-1 条边,需删除至少 m-(n-1) 条边才能无环,但删除一个顶点可能去掉多条边,此下界很弱)。
- 更好下界:通过计算图的最大二部子图或最大无环子图的大小,但复杂。一个实用下界:找一组顶点不相交的环,其数量为 k,则下界 = k。可用贪心:重复找环并删除其所有顶点,计数。
步骤6:总结
- 最小反馈顶点集问题的精确解可用分支定界法,核心是归约规则减少规模,下界剪枝,分支策略系统地搜索。
- 实现时需仔细设计数据结构(图、删除/恢复操作)。
- 该问题是 NP 难,算法适用于中小图(|V| ≤ 50)。
- 扩展:有向图需考虑有向环,归约规则类似,但分支更复杂。
通过以上步骤,我们可逐步构建搜索树,剪枝大量分支,最终找到最小反馈顶点集。