繁体   English   中英

在R中找到路径或路线

[英]Find a path or route in 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 

为此,我认为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 )。

在此处输入图片说明

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

# 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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM