The following graph sample is a portion of a directed acyclic graph which is to be layered and cleaned up so that only edges connecting consecutive layers are kept.
So what I need is to eliminate edges that form "shortcuts", that is, that jump between non-consecutive layers.
The following considerations apply:
My questions are:
First, topologically sort the graph.
Now from the beginning of sorted array, start breadth first search and try to find the proper "depth" (i.e distance from root) of every node. Since a node can have multiple parents, for a node x
, depth[x]
is maximum of depth of all it's parents, plus one. We initialize depth
for all nodes as -1
.
Now in bfs traversal, when we encounter a node p
, we try to update the depth of all it's childs c
, where depth[c] = max(depth[c],depth[p]+1)
. Now there are two ways we can detect a child with shortcut.
depth[p]+1 < depth[c]
, it means c
has a parent with higher depth than p
. So edge p to c
must be a shortcut.depth[p]+1 > depth[c]
and depth[c]!=-1
, it means c
have a parent with lower depth than p
. So p
is a better parent, and that other parent of c
must have a shortcut with p
.In both cases, we mark c
as problematic.
Now our goal is for every 'problematic' node x
, we check all it's parent, whose depth should be depth[x]-1
. If any of them have depth that is lower than that, that one have a shortcut edge with x
that needs to be removed.
Since the graph can have multiple roots, we should have a variable to mark visited
nodes, and repeat the above thing for any that's left unvisited.
This will sort the yellow ring problem, because before we visit any node, all it's predecessors has already been visited and properly ranked. This is ensured by the topological sort.
(Note : we can do this by just one pass. Instead of marking problematic nodes, we can maintain a parent
variable for all nodes, and delete edge with the old parent whenever case 2 occurs. case 1 should be obvious)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With