简体   繁体   中英

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. 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).

How to add an edge to a DAG and be sure that the resulting graph is also a DAG?

Build the initial DAG with all directed edges you have. 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).

This way it is guaranteed that the DAG will stay a DAG after adding an edge.

@user58697, there is no need to extend the partial order since there is a total order present after topologically sorting the graph. 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.

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.

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

  1. Pick a random node in a DAG where a new link would direct to. Let this be a toNode .
  2. Connect toNode to any other node in the graph that is not in a subtree of that 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
after that do this for 4 and then 5 and so on

This way it is guaranteed that the DAG will stay a DAG after adding an edge.

  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!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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