Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Algorithm to find lowest common ancestor in directed acyclic graph?

Imagine a directed acyclic graph as follows, where:

  • "A" is the root (there is always exactly one root)
  • each node knows its parent(s)
  • the node names are arbitrary - nothing can be inferred from them
  • we know from another source that the nodes were added to the tree in the order A to G (e.g. they are commits in a version control system)

Directed Acyclic Graph

What algorithm could I use to determine the lowest common ancestor (LCA) of two arbitrary nodes, for example, the common ancestor of:

  • B and E is B
  • D and F is B

Note:

  • There is not necessarily a single path to a given node from the root (e.g. "G" has two paths), so you can't simply traverse paths from root to the two nodes and look for the last equal element
  • I've found LCA algorithms for trees, especially binary trees, but they do not apply here because a node can have multiple parents (i.e. this is not a tree)
like image 964
Andrew Swan Avatar asked Feb 13 '13 23:02

Andrew Swan


People also ask

How do you find shortest path in directed acyclic graph explain with an example?

Given a Weighted Directed Acyclic Graph and a source vertex in the graph, find the shortest paths from given source to all other vertices. Try It! For a general weighted graph, we can calculate single source shortest distances in O(VE) time using Bellman–Ford Algorithm.

What is LCA algorithm?

In ontologies, the lowest common ancestor is also known as the least common ancestor. In a tree data structure where each node points to its parent, the lowest common ancestor can be easily determined by finding the first intersection of the paths from v and w to the root.

What is an ancestor in a DAG?

The ancestors of a vertex v in a DAG is the set of all vertices v' != v such that v is reachable from v'. So in your example, the ancestors of 3 would be 1, 2, 4 and 5.


1 Answers

Den Roman's link (Archived version) seems promising, but it seemed a little bit complicated to me, so I tried another approach. Here is a simple algorithm I used:

Let say you want to compute LCA(x,y) with x and y two nodes. Each node must have a value color and count, resp. initialized to white and 0.

  1. Color all ancestors of x as blue (can be done using BFS)
  2. Color all blue ancestors of y as red (BFS again)
  3. For each red node in the graph, increment its parents' count by one

Each red node having a count value set to 0 is a solution.

There can be more than one solution, depending on your graph. For instance, consider this graph:

DAG example where LCA can have two values

LCA(4,5) possible solutions are 1 and 2.

Note it still work if you want find the LCA of 3 nodes or more, you just need to add a different color for each of them.

like image 151
Anthony Garcia-Labiad Avatar answered Sep 23 '22 23:09

Anthony Garcia-Labiad