假设我们在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)?也就是说,在上面的示例中
以此类推。
感觉igraph
中应该有一种优雅的方法,但是我没有找到它。我玩过对all_simple_paths
的调用,但由于我没有很好的方法来获取每个节点的电平,因此这无济于事。
我知道许多用于其他数据结构的系统发育软件包implement this,但是如果图形上有合理的解决方案,我宁愿避免相互转换。 (不过,我对tidygraph
解决方案感到非常满意。)
答案 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