【问题标题】:Enumerating All Minimal Directed Cycles Of A Directed Graph枚举有向图的所有最小有向环
【发布时间】:2009-11-09 20:27:22
【问题描述】:

我有一个有向图,我的问题是枚举该图的所有最小(不能构造为其他循环的联合的循环)有向循环。这与 Tarjan 算法的输出不同。例如,对于this wikipedia page 的有向图,我想将 c d 和 d h 作为两个独立的有向循环。

我不知道这个问题是否是多项式的。我浏览了一篇论文“枚举最小 Dicuts 和强连通子图”,似乎得出的结论是这个问题是增量多项式(我不知道它是什么意思),但我无法为这篇文章提取算法。我也不确定最小强连通分量是否等同于我定义的最小循环。

有人知道这个问题的答案吗?

提前致谢!!!

【问题讨论】:

  • 最小,意思是“最短路径”或“加权弧的最小成本周期”?

标签: algorithm cycle directed-graph


【解决方案1】:

如果我们正在寻找最短路径周期,这似乎很容易。

  • 只需在所有节点上执行breadth first search,以搜索从节点到自身的最短路径。
  • 如果找不到路径,可以删除这个节点,它没有循环
  • 如果你找到了一条路径,你就找到了你的最小循环之一(当我们寻找最短路径时,我们可以确保这个循环不能是两个较短循环的并集)。
    • 将其中的所有节点折叠成一个新的大节点,并根据需要调整边缘。
  • 继续直到没有节点为止。

  • 当您处理完所有节点(顶点)后,您就可以找到所需的最小周期...但是有一个技巧。

如果仅使用初始集合中的节点表示循环,则可以保持“原样”。但是您必须将“大节点”转换为路径(循环之间的公共边),并且每个大节点都可能被几个这样的路径替换(对于级别 1 的大节点至少有 2 个,即不包含大节点本身)。找到的循环以这样一种方式构造,即您可以选择任何路径并仍然获得最小循环集(没有循环可以与其他两个循环结合),但有几个可能的这样的集合。在大节点中选择路径时,您可以添加约束以始终采用最短路径,但仍然可以存在相同长度的路径。所以这个问题的解决方案显然不够独特。

使用这种简单的方法,复杂度将是 O(V.(E+V)),其中 V 是顶点数,E 是边数。 O(E+V) 首先来自广度,最坏的情况是你必须执行 BFS V 次。因此它肯定是更好的多项式。我相信我所描述的在平均情况下确实是 O(log(V).(E+V)),但我还没有证明它(如果它是真的)。​​

【讨论】:

  • 看起来很吸引人,但是如果一个节点和自身之间有几条最短路径,我该怎么办呢?
  • 随便选一个,两者都是解决方案,都是最小的。您还可以考虑枚举所有可能的解决方案,但这看起来是指数级的。我愿意使用带有 boost 或 python 的 C++ 来实现这个算法(为了它的乐趣并检查它是否有效,这种练习是很好的技能训练)。 C++ 或 python 之间有什么偏好吗?
【解决方案2】:

我们正在寻找所有简单的周期,而不仅仅是最短或最便宜的周期。 (如果简单是正确的术语——我的意思是不自相交的循环。)

这是一个应该完成这项工作的广度优先算法:
给节点编号。 在每个节点上放置一个推销员并开始操作: 如果推销员可以选择采取哪条优势,他会模仿自己并采取所有可能的方式。 当他到达一个节点时, 如果它的数字低于他开始的那个,他就死了,如果它是他在记录那个循环之前访问过的那个,他就死了。从列表中删除多余的循环。

我不确定它的复杂性,但它看起来像 O(EV^2)。

编辑:
现在我想起来了,您可能可以从编号最小的节点上的一名推销员开始达到 O(EV)。当他的所有后代都死了时,从尚未访问的最低编号节点上的推销员重新开始。重复直到所有节点都被访问过。

【讨论】:

  • 感谢大家的回答,我不确定这些算法是否有效。问题是我翻阅了一篇正式描述此问题的论文 (dis.uniroma1.it/~demetres/events/ads07/abstracts/Mehlhorn.pdf)。问题的描述似乎与我的预期非常相似。在这篇论文中,一些工作显然被描述为最好的算法是|V|2*|A|,但似乎真的很难编码!!!我将尝试您的解决方案,看看它提供了什么...非常感谢
【解决方案3】:

也许列举独立循环会有帮助?

我会尝试以下方法。

  1. 首先,为了找出哪些顶点参与循环,请执行传递闭包。这是一个 O(V^3) 算法。
  2. 删除所有其他顶点。
  3. 现在,剩余图存在完全独立的循环覆盖(这是我的想法的弱点,我无法证明循环是独立的)
  4. 解决方案是——“二分图中最大对匹配”算法。

4.1。将图 (G) 中的每个顶点 v 变成 2(v1 和 v2),将每个顶点放在二分图 (G2) 的不同部分。

4.2。对于 G 中的每条边 e(v,u),添加一条从 G2 的第 1 部分到第 2 部分的边 - e(v1,u2)。

4.3。在 G2 中找到一个最大配对。它是 G2 边的子集。

5 该子集对应于 G 中的一组最大(完整)独立循环。

【讨论】:

    【解决方案4】:

    这可能为时已晚回答,但无论如何...... 该问题没有多项式解决方案,原因很简单:在 (di) 图中可能存在指数级的多个最小环。

    考虑n/2 大小为2 的集合,并循环排列它们:A_1, ..., A_{n/2},并使用约定A_{n/2+1}=A_1。当且仅当它们位于一组连续索引中时,在两个顶点之间放置一条边(因此A_{n/2} 中的元素也链接到A_1 中的元素,按照上述约定)。如果您对有向图而不是简单图感兴趣,请引导边,使其始终指向具有较大索引的集合中的顶点,或者在 A_{n/2}A_1 的情况下,它指向 @ 中的顶点987654328@ 给A_1 的人。

    很明显,在这个长度为n/2 的图中存在2^{n/2} 最小循环,因为在每个A_i 中只包含一个顶点的所有大小为n/2 的子集就是这样一个循环。如果你想用一个算法把它们全部列出来,那个算法必须至少有2^{n/2}个步骤。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-06-05
      • 2015-04-13
      • 1970-01-01
      • 2018-03-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多