【问题标题】:How to convert an undirected graph to a DAG?如何将无向图转换为 DAG?
【发布时间】:2011-11-14 20:51:21
【问题描述】:

Wiki page

任何无向图都可以通过选择其顶点的总顺序并将每条边从较早的端点按顺序定向到较晚的端点来构成 DAG。

但我不知道如何获得无向图的总顺序。我应该使用 DFS 吗?如果是这样,我将如何进行?

更多信息:我正在研究一个具有一个源和一个接收器的无向图。我正在尝试引导这些边缘,以便通过遵循边缘方向,我可以从源到接收器。

【问题讨论】:

  • 对于“总订单”的含义,请参见此处:en.wikipedia.org/wiki/Total_order
  • “源”和“汇”在无向图中没有意义。你的意思是说无向图中的两个顶点在转化为DAG后分别指定为源和汇吗?
  • @RafałDowgird 是的,我就是这个意思。

标签: algorithm graph-theory graph-algorithm


【解决方案1】:

总顺序基本上只是按某种顺序排列所有顶点——可以将其视为用从 1 到 |V(G)| 的数字标记每个顶点。这为我们提供了一种一致的方式来了解我们检查的任何一对顶点中哪个顶点更高。

是的,您可以通过深度优先搜索获得总排序。每次在 DFS 中探索一个顶点时,只需为每个顶点分配一个递增计数器的值。这就是您获得总订单的方式。

但您无需明确获得总排序的标签即可获得 DAG。如果我们使用上述探索时间作为我们的排序,那么我们可以进行如下操作:在进行 DFS 遍历时定位边,将每条无向边指向远离您当前正在扩展的顶点。

基本上,我们将较早探索的顶点指向稍后探索的顶点。

例如。如果你有

  A
 / \
B---C

您从探索 A 开始,您会将 A 上的边缘定向远离 A:

A --> B
A --> C
B --- C

现在假设您在 DFS 遍历中选择 B 进行下一步探索。然后,您将不理会 A 和 B 之间的边缘,因为您已经确定了该边缘的方向(A 已经完全展开)。 B 和 C 之间的边没有被触及,所以将它的方向远离我们当前的顶点 B,得到:

A --> B
A --> C
B --> C

当您探索 C 时,它的所有邻居都已完全展开,因此 C 没有什么可做的,也没有更多的顶点可以探索。

回复“更多信息”:

在这种情况下,只需确保先扩展源顶点,而不要探索接收器。例如。对于

A-B-C
|/
D

其中 D 是源,B 是汇,你可以:展开 D,然后是 A,然后是 C。你会得到:

D --> A
D --> B
A --> B
C --> B

【讨论】:

  • 我只是稍微提炼了原来的问题。
【解决方案2】:

实际上,我认为“选择总订单”在 wiki 页面中的含义是指自己定义总订单。换句话说,如果我们检查最简单的无向图:

A----B

将这个无向图转换为 DAG 显然取决于您是选择在 B 之前排序 A 还是在 B 之后排序 A。如果您在 B 之前选择 A,那么它变为:

A--->B

否则就变成:

B--->A

这正是从“EARLIER”端点(出现在总顺序中较早的端点)到“LATER”端点的“定向每条边”的含义。

同样,对于:

    A
   / \
  /   \
 B-----C

如果您将总订单定义为:

B A C

那么有向图应该是这样的:

B->A, B->C, A->C

【讨论】:

    【解决方案3】:

    问题是,在我们将无向边更改为有向边后,我们不希望留下任何循环。

    例如,假设我们有完整的三角图

    A -- B
      \  |
       \ |
         C
    

    我们可以选择边缘的方向为 A -> B、B -> C 和 C -> A

    A -> B
     \\  |
       \ v
         C
    

    但是我们会得到一个循环,这不是有向非循环图。

    维基百科页面中建议的技巧是选择顶点的顺序,实际上是任何顺序,然后使用它来决定指向边缘的方向。

    由于边缘在顺序中指向上方,我们永远不能再次“回落”来完成一个循环,因此保证生成的图是非循环的。

    【讨论】:

    • 谢谢。 “实际上任何订单”,这就是我一直在寻找的部分。
    【解决方案4】:

    您可以得到一个总顺序,并将无向图变成一个有向无环图编号节点以反向后序

    执行后序深度优先遍历,为每个节点分配一个编号当你离开它时,顺序从1到n。您访问相邻节点的顺序决定了 DAG 中边的方向。不要遍历从编号较高的节点通向编号较低的节点的边 - 这会破坏循环,有效地确定在最终 DAG 中该边将处于相反方向。

    这个顺序给出了图的拓扑排序,它是一个全序,并且由于存在拓扑排序,所以图变成了 DAG。

    编辑:澄清一下,一旦你用它们的 RPO 编号标记节点,对于原始图中的每条边 a <-> b,DAG 中的边是 a -> b iff @987654323 @,否则边缘为b -> a

    编辑:上面的内容有点矫枉过正,但是,如果某些边缘是有向的,而有些不是,它会起作用,如果所有的边缘都是无向的,正如@missingno 所指出的那样,任何顺序都足够了。

    【讨论】:

      猜你喜欢
      • 2011-09-17
      • 2016-10-30
      • 2012-04-11
      • 2021-09-30
      • 1970-01-01
      • 2017-12-26
      • 1970-01-01
      • 2021-06-07
      • 2017-01-18
      相关资源
      最近更新 更多