【问题标题】:Graph path-finding algorithm variant图寻路算法变体
【发布时间】:2017-03-02 06:51:31
【问题描述】:

我正在寻找一种算法,该算法将无向图作为输入并找到一个顶点子集,以便由这些顶点诱导的子图形成一个连接的无环树。

例如,在下图中,“X”节点会创建一个有效的解决方案,但包含任何“O”节点都会使其无效。

    O
   /|
O-X-X-X
 \ /
  X-X

解决方案对我的有用性与子集的大小成正比。虽然我不需要整个最大子集,但一个近似值会很有帮助。

我已经尝试了从随机节点开始并添加相邻顶点(如果它们不引发循环)的明显算法。但是,我觉得这会产生非常次优的树。

我应该提到我的特定应用程序涉及约 100 个节点和约 1000 条边的图。这足够小,如果实施得当(例如使用Dancing Links,但我还没有尝试过,那么蛮力回溯算法可能是可行的。

【问题讨论】:

  • 您在寻找尽可能大的子集吗?
  • 正如我所解释的,子集越大越好,但它不需要证明是最大的。近似和启发式都很好。

标签: algorithm graph tree


【解决方案1】:

这个问题被称为非常类似于Feedback Vertex Set,不幸的是它是NP-hard。根据 Wikipedia 页面,最知名的近似算法的 approximation ratio 为 2:Becker, Ann; Geiger, Dan (1996), "Optimization of Pearl's method of conditioning and greedy-like approximation algorithms for the vertex feedback set problem."

“连接反馈顶点集”的 NP 硬度证明

我忽略了结果图需要连接的条件,反馈顶点集(FVS)不是这种情况。下面我将展示您的问题,我将其称为连接反馈顶点集 (CVFS),但仍然是 NP-hard。

给定一个 FVS 的实例 (G = (V, E), k),我们需要构造一个具有 (G, k) 是 FVS 的 YES 实例当且仅当 (G', k') 是 CFVS 的 YES 实例。非正式地,这个 G' 看起来像 G 的“一堆副本”,带有一些额外的顶点和边。让我们这样做:

对于 V 中的每个顶点 v_i,创建一个 |V| 的路径(不是一个团,正如我最初在 cmets 中所说的...) V' 中的顶点 v'_i_j,1

对于 E 中的每条边 (v_i, v_j),创建所有 |V| G' 中对应顶点之间的对应“平行”边——即创建边 (v'_i_1, v'_j_1), (v'_i_2, v'_j_2), ..., (v'_i_|V |, v'_j_|V|)。 (这些边都连接同一层的顶点。)

对于 V 中的每个顶点 v_i,还要在 V' 中创建一个额外的“骨架顶点”u'_i。使这个 u'_i 与 v'_i_1 相邻。

将另一个顶点r添加到V',并使其与每个骨架顶点u'_i相邻。

最后,设置 k' = |V|*k + |V| - 1.

首先,我将证明如果 FVS 实例 (G, k) 是 YES 实例,那么 (G', k') 就是您的问题的 YES 实例。令 X 是 FVS 实例 (G, k) 的任何解(即删除的顶点集),它使 G 的至少 1 个顶点未被删除(这样的解必须存在,因为 1 顶点图不包含环);那么我们可以为您的问题实例构造一个解决方案 X',如下所示:

  1. 对于FVS解X中删除的每个顶点v_i,我们可以删除对应的路径v_i_1, ..., v_i_|V|从 G' 中以至多 |V|*k 的总成本(删除每条路径的成本为 |V| 顶点删除,并且 X 最多从 G 中删除 k 个顶点)。这保证了 G'-X' 中不会存在仅由肉顶点组成的循环(如果存在,这将与 FVS 解 X 到 (G, k) 的可行性相矛盾)。
  2. 对于 FVS 解 X 中的每个连通分量,我们可以删除 G' 中除 1 个对应的骨架顶点之外的所有顶点。我们在 G' 中剩下的是一堆 |V| FVS 解决方案 G-X 的副本,加上该解决方案的每个组件的单个骨架顶点,加上根顶点 r。因为我们只有从每个连接的组件到 r 的单一路径(通过每个组件的单个骨架顶点),所以 G' 中不可能有循环。由于 G-X 至少包含 1 个连通分量,这可能涉及最多 |V|-1 个删除,所以最多 |V|*k + |V| - 总共需要 1 次删除,因此构建的 CFVS 实例 (G', k') 的答案是肯定的。

其次,我将证明,如果您的问题的构造实例 (G', k') 是 YES 实例,那么 FVS 的原始实例 (G, k) 是 YES 实例。

令 X' 是构造的 CFVS 实例 (G', k') 的任何解(即删除的顶点集)。考虑 G'-X' 中每一层肉顶点所引出的子图:有 |V|这样的层。一般来说,不同的层可能包含不同数量的删除。选择任何包含最少删除数量的层 j;因为 G'-X' 是无环的,所以每个诱导子图也是无环的,尤其包括第 j 层。第 j 层的删除数量最多为 k'/|V|,因为否则(通过 j 的最小选择)总体上将严格超过 k' 个删除,这是一个矛盾。但任何整数

(G, k) 是 FVS 的 YES 实例意味着 (G', k') 是 CFVS 的 YES 实例,反之亦然,因此 (G, k) 是 FVS 的 NO 实例意味着 ( G', k') 是 CFVS 的 NO 实例,因此问题实例是等价的。显然 (G', k') 可以在多项式时间内从 (G, k) 构造,因此可以得出 CVFS 是 NP-hard 的。这显然也是 NP 完全的,因为可以在 O(|V|+|E|) 时间内使用单个 DFS 检查 YES 实例的解决方案的正确性(即无循环性和连通性)。

【讨论】:

  • 太棒了,知道问题的名称可以更容易地找到解决方案。我确实有一点额外的限制,那就是我想要一棵连接的树而不是森林。
  • 我明白了。我很确定这仍然是 NP 难的;如果我有时间仔细考虑,我会添加一个证明草图。 (基本思想是采用任何 FVS 实例,将每个顶点炸成一个大约有 n 个顶点的团,然后添加一个轻的顶点“骨架”,将所有这些团连接在一起,并认为 FVS 实例的任何解决方案都对应解决您的问题,使骨架完好无损。)
  • 我会对那个证明草图感兴趣。我的解决方案必然是比 FVS 森林更小(或相等)的子集,但我认为您可以提出我的最佳树和 FVS 森林共享相对较少节点的示例。但是我还没有读过贝克尔,所以我可能误解了你的想法。
  • 如果它是 NP 难的,也许我应该尝试指数算法并希望我的实例足够小以使其实用。
  • @Quantum7:我现在为您的实际问题添加了硬度证明;-) 结果证明我需要使用路径而不是派系。
【解决方案2】:

这听起来像findingmaximum spanning tree,然后使用它的结构获取一个子集可能会有所帮助。

如果没有,试试这个:

  1. 找到边数最少的节点。
  2. 如果通过将其添加到子集中您仍然拥有一棵树,请将其标记为属于该子集并从图中“擦除”其所有边。
  3. 重复第 1 步,直到无法添加不在子集中的所有节点。

希望对你有帮助

【讨论】:

  • 最大生成树不起作用,因为生成树可以包含多对节点,这些节点包含原始图中的一条边。至于您的其他过程,从字面上应用它会在第一步中产生一个单顶点子集。试图猜测您的意思,我认为您是在建议一种启发式方法,如果新节点不违反标准,则将其添加到树中。这或多或少是我现在正在尝试的(结果很差),尽管我没有尝试过按边数排序节点的启发式方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-05
  • 2015-07-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多