我有一个简单的问题。我试图在图形中设置边缘的权重,我想对其进行一些计算。
我的工作代码如下:
for(e in E(g)){
E(g)[e]$weight <- 1/(degree(g, v = V(g)[ends(g, e)][2], mode = "in"))
}
对于小图表,这很好。
但是对于具有105K边缘的图形,这需要太长时间(65分钟!!)
有没有更有效的方法来做到这一点,我怎样才能更快地做到这一点?
非常感谢提前!
答案 0 :(得分:1)
通过矢量化代码可以使计算速度更快,从而完全避免for循环 - 这会更频繁地重新计算每个节点的程度:
library(igraph)
# A small toy graph to demonstrate
set.seed(234)
g <- random.graph.game(10, .25, directed = T)
# Your approach for constructing weights
for(e in E(g)){
E(g)[e]$weight <- 1/(degree(g, v = V(g)[ends(g, e)][2], mode = "in"))
}
# Vectorized version
res <- 1/degree(g, v = V(g)[ends(g, E(g))[,2]], mode = "in")
# We test to make sure the results are the same
all.equal(E(g)$weight, res)
#> [1] TRUE
# To show how much faster it is lets make a big graph with ~100k edges
set.seed(42)
g <- random.graph.game(1000, .1, directed = T)
length(E(g))
#> [1] 99307
microbenchmark::microbenchmark(E(g)$weight <- 1/degree(g, v = V(g)[ends(g, E(g))[,2]], mode = "in"))
#> Unit: milliseconds
#> expr
#> E(g)$weight <- 1/degree(g, v = V(g)[ends(g, E(g))[, 2]], mode = "in")
#> min lq mean median uq max neval
#> 15.45099 57.88469 54.22476 59.22422 60.43034 106.6269 100
新版本在99,307边缘大约需要60毫秒。