在R中查找路径或路线

时间:2013-12-30 14:56:15

标签: r

所以这里是一个矩阵A,它显示了点1到10是否相互连接。 1表示它们是连接的,0表示它们不是连接的。我想知道是否有从一个点到另一个点的路径。假设起点为1,结束点为3.两者之间的点数无关紧要。积分可以重复使用。我只是想知道1是否可以达到3.我怎么能这样做?

从我们可以看到,其中一条可能的路径是1-8-6-2-3。但是如何用R做呢?非常感谢。任何帮助表示赞赏。

A 
       [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] 
 [1,]    0    0    0    0    0    0    0    1    0     0 
 [2,]    0    0    1    0    1    1    0    0    0     0 
 [3,]    0    1    0    0    0    0    0    0    0     0 
 [4,]    0    0    0    0    0    0    0    1    0     0 
 [5,]    0    1    0    0    0    0    0    0    0     0 
 [6,]    0    1    0    0    0    0    1    1    0     0 
 [7,]    0    0    0    0    0    1    0    0    0     1 
 [8,]    1    0    0    1    0    1    0    0    0     0 
 [9,]    0    0    0    0    0    0    0    0    0     0 
[10,]    0    0    0    0    0    0    1    0    0     0 

2 个答案:

答案 0 :(得分:6)

对于这项任务,我认为igraph会让你的生活更轻松

require(igraph)
dat <- read.table(text =
   '0    0    0    0    0    0    0    1    0     0
    0    0    1    0    1    1    0    0    0     0
    0    1    0    0    0    0    0    0    0     0
    0    0    0    0    0    0    0    1    0     0
    0    1    0    0    0    0    0    0    0     0
    0    1    0    0    0    0    1    1    0     0
    0    0    0    0    0    1    0    0    0     1
    1    0    0    1    0    1    0    0    0     0
    0    0    0    0    0    0    0    0    0     0
    0    0    0    0    0    0    1    0    0     0', header = FALSE)

dat <- as.matrix(dat)
g <- graph.adjacency(dat, mode = "undirected")
get.shortest.paths(g, 1, 3)
## [[1]]
## [1] 1 8 6 2 3

如果您只是想测试路径是否存在,您可以像这样创建自己的功能

test_paths <- function(g, from, to, ...) {
    is.finite(c(shortest.paths(g, from,  to, ...)))
}

test_paths(g, 1, 9)
## [1] FALSE

test_paths(g, 1, 8)
## [1] TRUE

这段代码背后的想法很简单:shortest.path当两个节点之间没有路径时(以及路径长度存在时)返回Inf,所以我们可以测试返回的数字是否是有限的( is.finite)。

enter image description here

答案 1 :(得分:1)

你可以通过重复矩阵​​乘法来做到这一点,直到矩阵保持不变:

# generate symetric matrix
set.seed(123)
m <- matrix(rbinom(100, 1, 0.2), nrow = 10)
m <- m * upper.tri(m)
m <- m + t(m)
m0 <- m
m0

生成矩阵:

      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
 [1,]    0    1    1    1    0    0    0    0    0     0
 [2,]    1    0    0    1    0    0    0    0    0     0
 [3,]    1    0    0    0    0    0    0    0    0     0
 [4,]    1    1    0    0    0    0    0    0    0     0
 [5,]    0    0    0    0    0    0    1    0    0     0
 [6,]    0    0    0    0    0    0    0    0    0     0
 [7,]    0    0    0    0    1    0    0    0    1     0
 [8,]    0    0    0    0    0    0    0    0    1     0
 [9,]    0    0    0    0    0    0    1    1    0     0
[10,]    0    0    0    0    0    0    0    0    0     0

现在成倍增加,直到稳定下来:

m <- m0 
while (TRUE) { 
    new_m <- sign(m + m %*% m)
    if (all(new_m == m))
        break;
    m <- new_m
}
m

如果这些节点之间存在路径,则结果矩阵包含1:

      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
 [1,]    1    1    1    1    0    0    0    0    0     0
 [2,]    1    1    1    1    0    0    0    0    0     0
 [3,]    1    1    1    1    0    0    0    0    0     0
 [4,]    1    1    1    1    0    0    0    0    0     0
 [5,]    0    0    0    0    1    0    1    1    1     0
 [6,]    0    0    0    0    0    0    0    0    0     0
 [7,]    0    0    0    0    1    0    1    1    1     0
 [8,]    0    0    0    0    1    0    1    1    1     0
 [9,]    0    0    0    0    1    0    1    1    1     0
[10,]    0    0    0    0    0    0    0    0    0     0