gpt4 book ai didi

r - 多个源顶点的子组件(mode = "in")

转载 作者:行者123 更新时间:2023-12-02 15:23:41 24 4
gpt4 key购买 nike

问题

igraph R包中,是否有一个可以处理多个源顶点的subcomponent()和/或BFS的有效实现?

动机

drake R package将用户的工作流程建模为相互依赖的对象和文件的 DAG。 DAG 应该只包含用户的目标及其上游依赖项,因此 drake 使用 igraph::subcomponent() 来消除多余的顶点。这种方法效率低下,因为 v 参数必须是单个顶点,因此 drake 最终会为用户想要构建的每个目标执行新的 BFS。

编辑:2019-01-10

drake 现在使用 different approach that ultimately relies on sequential calls to adjacent_vertices() 。这种方法很笨重,但是the speed improvement is actually quite nice 。仍然坚持追求更优雅、更精致的东西。

最佳答案

我认为您可以使用 distances() 函数来执行此操作,该函数生成节点之间的距离(没有边)矩阵。这似乎只执行一次搜索,并且比迭代每个顶点要快得多。

示例代码:

library(igraph)
library(microbenchmark)

# generate some random testing data
set.seed(1234)
g <- erdos.renyi.game(50, .01)

# Here we make a function that iterates
# across the vector of IDs applying the function
# and returns a list where each element is the
# ids of the subcomponents
sc_apply <- function(g) {
vs <- V(g)
res <- sapply(vs, function(v){as.numeric( # to facilitate comparison
subcomponent(g, v, mode = "in")
)})
res
}

# Try it for testing
t1 <- sc_apply(g)

# Here we get the matrix of node distances. Infinite distance
# implies a seperate component. We iterate through rows of
# matrix to extract the set of nodes that are connected
sc_distmat <- function(g) {
dmat <- distances(g, mode = "in")
res <- apply(dmat, 1, function(row){which(is.finite(row))})
res
}

# extract for testing
t2 <- sc_distmat(g)

# check that equal (we need to sort the
# subcomponent list elements first to facilitate comparison)
all.equal(lapply(t1, sort), t2)
#> [1] TRUE

结果是相同的 - 但值得注意的是,如果您的图形是一个巨大的组件,那么 apply 将返回一个矩阵而不是列表,因此您需要以稍微不同的方式进行比较。

现在让我们看看这是否更快:

# generate graphs of different sizes (not too big because my
# laptop is borderline antique!)
set.seed(42)
small_g <- erdos.renyi.game(10, .2)
mid_g <- erdos.renyi.game(50, .1)
big_g <- erdos.renyi.game(100, .1)

# check speed improvement
microbenchmark(sc_apply(small_g), sc_distmat(small_g))
#> Unit: microseconds
#> expr min lq mean median uq
#> sc_apply(small_g) 2181.465 2243.4895 2734.7132 2313.005 2777.7135
#> sc_distmat(small_g) 451.333 471.8565 840.4742 521.865 598.0845
#> max neval cld
#> 9152.262 100 b
#> 27139.262 100 a
microbenchmark(sc_apply(mid_g), sc_distmat(mid_g))
#> Unit: microseconds
#> expr min lq mean median uq
#> sc_apply(mid_g) 11006.113 11327.794 13590.9536 12919.492 15397.2510
#> sc_distmat(mid_g) 757.752 795.308 949.2551 841.834 965.4545
#> max neval cld
#> 27068.296 100 b
#> 2061.824 100 a
microbenchmark(sc_apply(big_g), sc_distmat(big_g))
#> Unit: milliseconds
#> expr min lq mean median uq
#> sc_apply(big_g) 23.11678 26.696373 29.940675 29.191045 33.012796
#> sc_distmat(big_g) 1.67531 1.727873 2.156307 1.855994 2.244872
#> max neval cld
#> 47.081647 100 b
#> 7.576123 100 a

如您所见,distances() 方法速度更快,并且随着图表大小的增大而变得越来越快。

reprex package 于 2019-01-10 创建(v0.2.1)

关于r - 多个源顶点的子组件(mode = "in"),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54068165/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com