如何将无向图转换为 DAG?

发布于 2024-12-15 05:49:17 字数 358 浏览 3 评论 0原文

Wiki 页面

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

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

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

The Wiki page says

Any undirected graph may be made into a DAG by choosing a total order for its vertices and orienting every edge from the earlier endpoint in the order to the later endpoint.

But I don't know how to get the total order of an undirected graph. Should I use DFS? If so, how would I proceed?

More info: I'm working on an un-directed graph which has one source and one sink. I'm trying to direct these edges so that by following the edge direction I can get from the source to the sink.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

素衣风尘叹 2024-12-22 05:49:17

全序基本上只是按某种顺序排列所有顶点——可以将其视为用 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

A total order is basically just arranging all the vertices in some order -- think of it as labelling each vertex with a number from 1 to |V(G)|. This gives us a consistent way to know which vertex is higher for any pair of vertices we examine.

Yes, you can obtain a total ordering with depth-first search. Just assign each vertex the value of an incrementing counter each time you explore a vertex in DFS. This is how you can get a total ordering.

But you don't need to explicitly get a labelling of a total ordering to get a DAG. If we use the above time-of-exploration as our ordering, then we can proceed as follows: Orient edges as you do the DFS traversal, pointing each undirected edge away from the vertex that you're currently expanding.

Basically, we have vertices explored earlier pointing to vertices explored later.

eg. if you had

  A
 / \
B---C

and you started by exploring A, you would orient edges incident on A away from A:

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

Now say you choose B to explore next in your DFS traversal. Then you would leave the edge between A and B alone, because you've already oriented that edge (A has already been fully expanded). The edge between B and C was untouched, so orient that away from our current vertex, B, to get:

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

When you explore C, all of its neighbours have been fully expanded, so there is nothing left to do for C, and there are no more vertices left to explore.

Response to "More Info":

In that case, just make sure you expand the source vertex first and just don't explore the sink. Eg. for

A-B-C
|/
D

where D is the source and B is the sink, you could: expand D, then A, then C. You would get:

D --> A
D --> B
A --> B
C --> B
在巴黎塔顶看东京樱花 2024-12-22 05:49:17

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

A----B

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

A--->B

否则,它就变成:

B--->A

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

类似地,对于:

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

如果将总顺序定义为:

B A C

那么有向图应该类似于:

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

Actually I think what it means in the wiki page by "choosing a total order" means defining a total order yourself. In other words, if we check the simplest undirected graph:

A----B

Converting this undirected graph to a DAG clearly depends on whether you choose to order A before B or A after B. If you choose A before B, then it becomes:

A--->B

Otherwise, it becomes:

B--->A

That is exactly what it means by "orienting every edge" from the "EARLIER" endpoint (endpoints that appear earlier in the total order) to the "LATER" endpoint.

Similarly, for:

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

If you define the total order as:

B A C

Then the directed graph should be something like:

B->A, B->C, A->C
旧话新听 2024-12-22 05:49:17

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

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

A -- B
  \  |
   \ |
     C

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

A -> B
 \\  |
   \ v
     C

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

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

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

The problem is that after we change our undirected edges into directed ones we don't want any cycles left.

For example, suppose we have the complete triangle graph

A -- B
  \  |
   \ |
     C

We could choose orientations for the edges as A -> B, B -> C and C -> A

A -> B
 \\  |
   \ v
     C

But then we'd get a cycle and that is not a Directed Acyclic Graph.

The trick suggested in the Wikipedia page is choose an ordering of the vertices, any ordering, actually, and use that to decide what directions to point the edges.

Since the edges point upwards in the ordering we can never "fall back down" again to complete a cycle so the resulting graph is guarantted to be acyclic.

赠佳期 2024-12-22 05:49:17

可以得到全序,将无向图转化为逆后序的DAG编号节点。

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

该顺序给出了图的拓扑排序,它是全序,并且由于存在拓扑排序,因此图被转换为 DAG。

编辑:澄清一下,一旦您用 RPO 编号标记了节点,对于每条边 a <-> b 在原图中,DAG 中的边是 a ->; b 当且仅当RPO 编号(a) < RPO-number (b),否则边为b ->一个。

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

You can get a total order and turn the undirected graph into a DAG numbering nodes in reverse post order.

Perform a post-order depth first traversal, assigning a number to each node as you leave it, in sequence from 1 to n. The order you visit adjacent nodes determines the direction of the edges in the DAG. Do not traverse edges, which lead from a higher numbered node to a lower numbered node - this breaks cycles, effectively determining that in the final DAG this edge will be in the opposite direction.

This order gives a topological sort of the graph, it's a total order and since a topological ordering exists, the graph is turned into a DAG.

EDIT: To clarify, once you've labelled nodes with their RPO-number, for each edge a <-> b in the original graph, the edge in the DAG is a -> b iff RPO-number(a) < RPO-number (b), otherwise the edge is b -> a.

EDIT: The above it an overkill, though, it will work if some edges are directed and some not, if all are undirected, as pointed by @missingno, any order will suffice.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文