I\'m looking for an algorithm to \"invert\" (reverse? turn inside-out?) a DAG:
A* # I can\'t ascii-art the arrows, so just
/ \\ # pretend
Traverse the graph building a set of reversed edges and a list of leaf nodes.
Perform a topological sort of the reversed edges using the leaf (which are now root) nodes to start with.
Construct the reversed graph based on the reversed edges starting from the end of the sorted list. As the nodes are constructed in reverse topological order, you are guaranteed to have constructed the children of a given node before constructing the node, so creating an immutable representation is possible.
This is either O(N) if you use structures for your intermediate representation which track all links in both directions associated with a node, or O(NlnN) if you use sorting to find all the links of a node. For small graphs, or languages which don't suffer from stack overflows, you can just construct the graph lazily rather than explicitly performing the topological sort. So it depends a little what you're implementing it all in how different this would be.
A -> (B -> G, C -> (E -> F, D -> F))
original roots: [ A ]
original links: [ AB, BG, AC, CE, EF, CD, DF ]
reversed links: [ BA, GB, CA, EC, FE, DC, FD ]
reversed roots: [ G, F ]
reversed links: [ BA, CA, DC, EC, FE, FD, GB ] (in order of source)
topologically sorted: [ G, B, F, E, D, C, A ]
construction order : A, C->A, D->C, E->C, F->(D,E), B->A, G->B