简体   繁体   English

如何在不创建循环的情况下向有向无环图添加边

[英]How to add edges to a directed acyclic graph without creating cycles

I have a graph with directed and undirected edges, now I want to get rid of the undirected edges by replacing them with directed edges (each undirected edge becomes one directed edge).我有一个带有有向边和无向边的图,现在我想通过用有向边替换它们来摆脱无向边(每个无向边变成一个有向边)。 There are two possibilies for each undirected edge (replace it with a directed edge in one direction or the other direction).每个无向边都有两种可能性(用一个方向或另一个方向的有向边替换它)。

How to determine the direction of the undirected edges so that my graph stays acyclic?如何确定无向边的方向以使我的图保持无环?

My approach:我的做法:

Create a graph with only the directed edges and add the undirected edges 1 by 1 (as directed edges) later on.创建一个仅包含有向边的图,稍后将无向边 1 x 1(作为有向边)添加。 Now I have a DAG , my problem is reduced to adding directed edges to the graph while maintaining the DAG properties (only directed edges, no cycles).现在我有一个DAG ,我的问题减少到在保持 DAG 属性的同时向图中添加有向边(只有有向边,没有循环)。

How to add an edge to a DAG and be sure that the resulting graph is also a DAG?如何向 DAG 添加边并确保生成的图也是 DAG?

Build the initial DAG with all directed edges you have.使用您拥有的所有有向边构建初始 DAG。 Topo-sort it.对它进行拓扑排序。 Extend the partial order imposed by sorting to a total order (eg arrange vertices in a level lattice and enumerate them level by level).将排序所施加的偏序扩展为全序(例如,在级别格中排列顶点并逐级枚举它们)。 Notice that all edges go from the smaller vertex to a larger one.请注意,所有边都从较小的顶点到较大的顶点。

Now direct your undirected edges according to the total order (from smaller vertex to a larger one).现在根据总顺序(从较小的顶点到较大的顶点)引导您的无向边。 It is easy to see that the resulting graph has no cycles (for a cycle to exist there must be an edge going in the opposite direction).很容易看出结果图没有循环(要存在循环,必须有一条向相反方向的边)。

This worked out for me:这对我有用:

Do a topological sort on the graph without the undirected edges, add the undirected edges one by one (make them point from larger topo-vlalue to smaller).对没有无向边的图进行拓扑排序,将无向边一条一条相加(使它们从较大的topo-vlalue指向较小的)。

This way it is guaranteed that the DAG will stay a DAG after adding an edge.这样可以保证 DAG 在添加边后仍将是 DAG。

@user58697, there is no need to extend the partial order since there is a total order present after topologically sorting the graph. @ user58697,无需扩展偏序,因为在对图形进行拓扑排序后存在全序。 Each node's topo-value is comparable to other topo-values.每个节点的拓扑值与其他拓扑值相当。

Let's try to solve this problem by looking at an example:-让我们通过看一个例子来尝试解决这个问题:-

Suppose I have the following set of vertices as directed ones:-假设我有以下一组顶点作为有向顶点:-

(1,2)
(2,3)
(4,5)
(5,6)
(7,3)

And we following set of vertices with undirected ones:-我们跟随一组无向顶点:-

(3,4)
(6,7)

So now if we create our graph on paper, it should look something like this所以现在如果我们在纸上创建我们的图表,它应该看起来像这样

1 -> 2 -> 3 
         /  \
        /  4   -> 5 -> 6
       /              /  \
     -----------------7 

So you can clearly see there are two undirected edges present which we want to replace with directed ones,所以你可以清楚地看到存在两个无向边,我们想用有向边替换它们,

So we can pick the first undirected pair as (3,4) and place a vertex 3 -> 4 and after this we will call dfs(1), and if find a cycle then (3,4) is not a valid one, we will then place as 4 -> 3 but in our case 3 -> 4 doesn't cause any cycles.所以我们可以选择第一个无向对作为 (3,4) 并放置一个顶点 3 -> 4 之后我们将调用 dfs(1),如果找到一个循环,那么 (3,4) 不是一个有效的循环,然后我们将放置为 4 -> 3 但在我们的情况下 3 -> 4 不会导致任何循环。

We move on to our next pair called (6,7) and placing 6 -> 7 causes a cycle, so we place 7 -> 6 and this gives us a DAG.我们继续下一个称为 (6,7) 的对,放置 6 -> 7 会导致循环,因此我们放置 7 -> 6,这给了我们一个 DAG。

This is like a brute force solution.这就像一个蛮力解决方案。 Let me give it a more thought, is there any better approach to this problem.让我再考虑一下,有没有更好的方法来解决这个问题。

Add a link to a DAG without creating a cycle在不创建循环的情况下添加到 DAG 的链接

  1. Pick a random node in a DAG where a new link would direct to.在 DAG 中随机选择一个新链接将指向的节点。 Let this be a toNode .让它成为一个toNode
  2. Connect toNode to any other node in the graph that is not in a subtree of that toNode .toNode连接到图中不在该toNode子树中的任何其他节点。

It never creates a cycle.它永远不会产生循环。

the basic idea is to do a topological sort.基本思想是进行拓扑排序。

eg after topological sort array is 3,4,5,6,1,2 We direct undirected edge from 3 -> other edges例如,在拓扑排序数组是 3,4,5,6,1,2 之后我们从 3 引导无向边 -> 其他边
after that do this for 4 and then 5 and so on之后做 4 次,然后 5 次,依此类推

This way it is guaranteed that the DAG will stay a DAG after adding an edge.这样可以保证 DAG 在添加边后仍将是 DAG。

  1. Sort nodes in a topological order按拓扑顺序对节点进行排序
  2. Create an edge from every node to node on the 'right' where an edge doesn't exist在不存在边的“右侧”创建从每个节点到节点的边

Done!完毕!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM