【问题标题】:Efficiently extract duplicate/multiple paths with igraph使用 igraph 有效地提取重复/多条路径
【发布时间】:2022-01-02 22:22:53
【问题描述】:

如何从 igraph 中提取重复路径,有没有比下例中的双循环更有效的方法? 通过重复/多条路径,我的意思是结果应该包含B1 -> B2a -> B3B1 -> B2b -> B3。但是我的代码并没有产生这种情况。 数据:

library(dplyr)
library(igraph)

d <- tribble(~input, ~output,
             "A1", "A2",
             "A2", "A3a",
             "A2", "A3b",
             "B1", "B2a",
             "B1", "B2b",
             "B2a", "B3",
             "B2b", "B3")

我的分析:

g <- graph_from_data_frame(d, directed = TRUE)
(finals <- V(g)[degree(g, mode = "out") == 0])
(starts <- V(g)[degree(g, mode = "in") == 0])
res_collect <- vector("list", length(starts) * length(finals))
tmp <- 1
for (i_s in seq_along(starts)) {
  for (i_f in seq_along(finals)) {
    res <- tryCatch(
      {
        all_simple_paths(g, from = starts[[i_s]], to = finals[[i_f]])[[1]]
      },
      error = function(cond) {
        message("failed at starts-nr=", i_s, ", finals-nr=", i_f); return(as.integer(NA))
      }
    )
    res_collect[[tmp]] <- res
    tmp <- tmp + 1
  }
}

问题:

res_collect[!is.na(res_collect)]
# [[1]]
# + 3/8 vertices, named, from 60df173:
#   [1] A1  A2  A3a
# 
# [[2]]
# + 3/8 vertices, named, from 60df173:
#   [1] A1  A2  A3b
# 
# [[3]]
# + 3/8 vertices, named, from 60df173:
#   [1] B1  B2a B3 

缺少 1 条路径:B1 -> B2b -> B3。

【问题讨论】:

  • 请用简单的英语解释问题。不要使用代码来传达概念。 “重复路径”不清楚——你应该定义它。
  • “重复”表示结果中不显示不同的中间产品(=顶点)。我编辑了我的帖子。
  • 你仍然没有描述你想要完成的任务。你能用简单的英语解释一下你想做什么吗?
  • 例如,“我想找到从任何源顶点到有向图的任何汇顶点的所有简单路径(不包含任何长度的重复顶点)。”再次,请用人类语言而不是代码完整地解释问题。代码不会传达您要执行的操作。
  • 我相信我是用人类语言解释的。我不相信我是用动物语言解释的。

标签: r igraph


【解决方案1】:

你可以试试下面的代码

do.call(
  c,
  lapply(
    starts,
    all_simple_paths,
    graph = g,
    to = finals
  )
)

给了

[[1]]
+ 3/4 vertices, named, from fb6335c:
[1] A1  A2  A3a

[[2]]
+ 3/4 vertices, named, from fb6335c:
[1] A1  A2  A3b

[[3]]
+ 3/4 vertices, named, from fb6335c:
[1] B1  B2a B3

[[4]]
+ 3/4 vertices, named, from fb6335c:
[1] B1  B2b B3

【讨论】:

  • 这不太正确。您不需要分解图表。这没有区别(并且不会消除没有路径的源/汇对,请考虑graph_from_literal(1-+2-+3-+4,5-+3,2-+6))。但是,您需要以某种方式遍历startsall_simple_pathsfrom 参数采用单个顶点,而不是顶点集合。只会考虑第一个。
  • 类似unlist( lapply(starts, function (f) all_simple_paths(g, f, finals)) , recursive = F)
  • @Szabolcs 是的,谢谢你纠正我。你说的对。我更新了我的答案。我使用decompose,因为我正在考虑分而治之的策略来处理具有许多集群的大型网络,但似乎decompse 的开销很大。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-05
  • 1970-01-01
相关资源
最近更新 更多