如何使用 igraph 提取 R 中所有最短路径的边类型?

How to extract edge types for all shortest paths in R with igraph?

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

试试下面的代码

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

这可以通过循环 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"

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

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