igraph中最低的共同祖先

时间:2019-12-21 17:34:35

标签: r igraph graph-theory tidygraph

假设我们在igraph中有一棵树:

library(igraph)

g <- make_tree(14, children = 3)
plot(g, layout = layout_as_tree)

reprex package(v0.3.0)于2019-12-21创建

我们如何找到任意节点集合的lowest common ancestor(LCA)?也就是说,在上面的示例中

  1. 7和14的LCA为2。
  2. 6、9、12和14的LCA为1。
  3. 1和8的LCA为1。
  4. 任何节点的LCA本身。

以此类推。

感觉igraph中应该有一种优雅的方法,但是我没有找到它。我玩过对all_simple_paths的调用,但由于我没有很好的方法来获取每个节点的电平,因此这无济于事。

我知道许多用于其他数据结构的系统发育软件包implement this,但是如果图形上有合理的解决方案,我宁愿避免相互转换。 (不过,我对tidygraph解决方案感到非常满意。)

2 个答案:

答案 0 :(得分:5)

对于树,您可以获取从节点到根的路径。然后在路径之间找到交点的最高索引:

lca <- function(graph, ...) {
  dots = c(...) 
  path = ego(graph, order=length(V(graph)), nodes=dots, mode="in")
  max(Reduce(intersect, path))
  }    

lca(g, 7, 14)
lca(g, 10, 8)

答案 1 :(得分:4)

至少对于中等大小的图形,您可以从点之间的距离矩阵中执行此操作。当且仅当存在从x到y的路径时,x才是y的祖先。同样,如果x的索引> y的索引,则x在树中不高于y。

DM = distances(g, V(g), mode="out")
LCA = function(NodeList) {
    max(which(rowSums(is.infinite(DM[,NodeList])) == 0)) 
}
LCA(c(7,14))
2
LCA(c(6,9,12,14))
1