All Downloads are FREE. Search and download functionalities are using the official Maven repository.

flatgraph.algorithm.LowestCommonAncestors.scala Maven / Gradle / Ivy

There is a newer version: 0.0.91
Show newest version
package flatgraph.algorithm

/** Find the lowest common ancestor(s)
  *
  * 1) for each relevant node, find their recursive parents 2) create the intersection of all of those sets 3) the LCA are those nodes, that
  * do not have any children in that set
  *
  * based on https://www.baeldung.com/cs/lowest-common-ancestor-acyclic-graph
  */
object LowestCommonAncestors {

  def apply[A](nodes: Set[A])(parents: A => Set[A]): Set[A] = {

    def parentsRecursive(node: A, seen: Set[A] = Set.empty): Set[A] = {
      val nodeParents = parents(node) -- seen
      nodeParents ++ nodeParents.flatMap(node => parentsRecursive(node, seen ++ nodeParents))
    }

    if (nodes.size <= 1) {
      nodes
    } else {
      val (head, tail) = (nodes.head, nodes.tail)
      val parentsIntersection = tail.foldLeft(parentsRecursive(head)) { case (res, next) =>
        res.intersect(parentsRecursive(next))
      }

      parentsIntersection.filter { node =>
        val childCount = parentsIntersection.count(parentsRecursive(_).contains(node))
        childCount == 0
      }
    }
  }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy