我有一个带有几个周期的加权定向多图。使用clusters
包中的igraph
函数,我可以使节点属于强连接组件。但我需要形成一个循环的节点的路径/顺序。
编辑
我有一个非常密集的图形,有30个节点和大约2000个边缘。因此,graph.get.subisomorphisms.vf2
在我的案例中运行时间太长。
我不熟悉图算法,但我想可能会对原始图或反向图执行DFS并使用order
或order.out
可能有效,但不是肯定的。
或欢迎任何其他让这种运行更快的想法!
实施例
library(igraph)
set.seed(123)
graph <-graph(c(1,2,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,8,10,9,10,9,10,10,11,10,5,11,12,12,13,13,14,14,15,14,20,15,16, 16,17,17,18,18,19,19,20,20,21,21,1,22,23,22,23,23,22),directed=T)
E(graph)$weight= runif(ecount(graph),0,10)
> clusters(graph, "strong")
$membership
[1] 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 1
$csize
[1] 2 21
$no
[1] 2
如何在此处获得具有最高权重的循环的边缘列表?谢谢!
答案 0 :(得分:1)
假设每个强连接组件中的所有节点形成一个循环,并且您只对这个大循环感兴趣(例如,在您的示例中,您只对节点1:21的循环和节点22的循环感兴趣:23),然后你可以提取形成循环的节点顺序,抓住边上的权重,并计算循环的总重量。
# Compute the node order of the cycle for each component by performing an
# isomorphism with a same-sized directed ring graph
clusts <- clusters(graph, "strong")
(cycles <- lapply(1:clusts$no, function(x) {
sg <- induced.subgraph(graph, clusts$membership == x)
n <- sum(clusts$membership == x)
col <- rep(c(1, 0), c(1, n-1)) # Used to grab isomorphism starting at 1
sg.idx <- graph.get.subisomorphisms.vf2(sg, graph.ring(n, directed=TRUE), col, col)[[1]]
which(clusts$membership == x)[sg.idx]
}))
# [[1]]
# [1] 22 23
#
# [[2]]
# [1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
现在您可以获取每个周期的边权重之和:
sapply(cycles, function(x) sum(graph[from=x, to=c(tail(x, -1), x[1])]))
# [1] 8.833018 129.959437
请注意,这通常是NP难的,因为在一般图中找到哈密顿循环是NP难的。因此,对于大型图表,graph.get.subisomorphisms.vf2
调用可能会非常慢。