【问题标题】:How to extract edge types for all shortest paths in R with igraph?如何使用 igraph 提取 R 中所有最短路径的边缘类型?
【发布时间】:2021-09-02 13:47:35
【问题描述】:

igraph 有两个有用的函数,shortest_pathsall_shortest_paths。前者输出最短路径之一,另一个输出所有最短路径。但是,前者也能输出路径的边缘类型,而后者似乎不能。

如何使用all_shortest_paths 提取所有最短路径的“边缘类型”?我在下面提供了澄清代码:

library(igraph)
m <- read.table(row.names=1, header=TRUE, text=
                  " A B C D
                A 0  1  1  0  
                B 0  0 0  1 
                C 0 0  0  1
                D 0  0  0  0")
m <- as.matrix(m)
ig <- graph.adjacency(m, mode="directed")
plot(ig)
E(ig)
for (i in 1:length(E(ig))) {
  
  if (i == 4) {
    
    E(ig)[i]$type <- -1
  } else {

    E(ig)[i]$type <- 1
  }
  
}

###This gets one of the shortest paths
test1 <- shortest_paths(ig, from = V(ig)[1], to = V(ig)[4], mode = "out", output = "epath")

###This outputs the types for the shortest path above
test1$epath[[1]]$type

###This gets all the shortest paths
test2 <- all_shortest_paths(ig, from = V(ig)[1], to = V(ig)[4], mode = "out")

###The code below doesn't work. How do I get the types for ALL the shortest paths?
test2$res[[1]]$type

【问题讨论】:

  • all_shortest_paths 的底层 C 函数用于仅返回顶点序列,而不是边索引序列。 It has been recently updated to also return edge indices. 因此,对 igraph 的 C 核心进行了必要的更新。随时在 GitHub 上为 R/igraph 打开一个问题,并请求将此改进也传播到 R 接口。

标签: r igraph


【解决方案1】:

试试下面的代码

df <- get.data.frame(ig)
lapply(
  test2$res,
  function(x) {
    nm <- names(x)
    merge(
      df,
      data.frame(from = head(nm, -1), to = tail(nm, -1))
    )$type
  }
)

你会得到

[[1]]
[1]  1 -1

[[2]]
[1] 1 1

如果你想查看更多信息,可以使用

df <- get.data.frame(ig)
lapply(
  test2$res,
  function(x) {
    nm <- names(x)
    merge(
      df,
      data.frame(from = head(nm, -1), to = tail(nm, -1))
    )
  }
)

你会得到

[[1]]
  from to type
1    A  C    1
2    C  D   -1

[[2]]
  from to type
1    A  B    1
2    B  D    1

【讨论】:

  • 这是否适用于长度超过 2 条边的路径?我认为这一步from = head(nm, -1), to = tail(nm, -1)只适用于我的具体例子。
  • 我认为它应该适用于一般情况。 @新星
【解决方案2】:

这可以在循环通过test2$res 并使用igraph 的访问器函数as_ids() 时相对简单地完成:

suppressMessages(library(igraph))
m <- read.table(row.names=1, header=TRUE, text=
                  " A B C D
                A 0  1  1  0  
                B 0  0 0  1 
                C 0 0  0  1
                D 0  0  0  0")
m <- as.matrix(m)
ig <- graph.adjacency(m, mode="directed")
plot(ig)
E(ig)
for (i in 1:length(E(ig))) {
  if (i == 4) {
    E(ig)[i]$type <- "green"
  } else {
    E(ig)[i]$type <- "red"
  }
}

OriginalGraph <- get.data.frame(x = ig)
EdgeTypesPresent <- vector(mode = "list",
                           length = length(test2))

for (m1 in seq_along(test2$res)) {
  p1 <- as_ids(test2$res[[m1]])
  EdgeTypesPresent[[m1]] <- unique(OriginalGraph$type[OriginalGraph$from %in% p1 &
                                                        OriginalGraph$to %in% p1])
  
}

这给了我们:

> EdgeTypesPresent
[[1]]
[1] "red"   "green"

[[2]]
[1] "red"

【讨论】:

    【解决方案3】:

    获取边的选择并提取类型:

    lapply(test2$res, \(x) E(ig)[head(x, -1) %->% tail(x, -1)]$type)
    #[[1]]
    #[1]  1 -1
    #
    #[[2]]
    #[1] 1 1
    

    请参阅 R 内部的 https://igraph.org/r/doc/igraph-es-indexing.html?"igraph-es-indexing" 以了解有关其工作方式的选项的所有详细信息。例如:

    E(ig)[c("A","B") %->% c("B","D")]
    #+ 2/4 edges from 16165ed (vertex names):
    #[1] A->B B->D
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-06-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多