algorithmgraphdirected-acyclic-graphsjgraphtspanning-tree

Jgrapht: how to convert a directed cyclic graph into a DAG?


One thought is run a spanning tree algorithm (e.g., Kruskal) to get the spanning tree, and then construct a new graph from the spanning tree, which is quite messy in terms of code. Looks like there is no available implementation to obtain a DAG subgraph of a directed graph. Please instruct if there are better ways of doing this with jgrapht. Thanks!

As described in the previous section.


Solution

  • Your suggestion is not necessary bad. Not sure why this would be messy in code:

    Graph<Integer,DefaultEdge> graphWithCycles = ...; //Your graph with cycles
    
    //Compute spanning tree
    SpanningTreeAlgorithm<DefaultEdge> sa = new KruskalMinimumSpanningTree<>(graphWithCycles);
    SpanningTreeAlgorithm.SpanningTree<DefaultEdge> tree = sa.getSpanningTree();
    
    //Create new graph without cycles induced by the spanning tree
    Graph<Integer,DefaultEdge> graphWithoutCycles = ...; //Your graph without cycles, definition depends on graphWithCycles
    for(DefaultEdge edge: tree.getEdges())
        Graphs.addEdgeWithVertices​(graphWithoutCycles, graphWithCycles, edge);
    

    There's various other approaches, e.g. you could also simply run a BreadthFirstSearch on your graph with cycles and create a new graph induced by the BFS tree as you go:

    Graph<Integer,DefaultEdge> graphWithCycles = ...; //Your graph with cycles
    Graph<Integer,DefaultEdge> graphWithoutCycles = ...; //Your graph without cycles
    BreadthFirstIterator​ bfs = new BreadthFirstIterator​(graphWithCycles);
    while(bfs.hasNext()){
        Integer vertex = bfs.next(); 
        graphWithoutCycles.addVertex(vertex);
        DefaultEdge edge = bfs.getSpanningTreeEdge(vertex);
        if(edge != null) //Edge is null if the vertex is the root of the BFS tree
            graphWithoutCycles.addEdge(bfs.getParent(vertex),vertex,edge);
    }