【问题标题】:Adding Combinations of Numbers in a Matrix在矩阵中添加数字组合
【发布时间】:2022-02-12 11:53:10
【问题描述】:

我发现这个链接告诉你如何用随机数制作一个矩阵:https://www.tutorialspoint.com/how-to-create-a-matrix-with-random-values-in-r

  #random symmetric matrix with diagnoal elements as 0
 A <- matrix(runif(16), 4, 4)
A1 = A %*% t(A)

out_1 = A1 - diag(diag(A1))

         [,1]     [,2]     [,3]     [,4]
[1,]     0.00 20371.54 19136.91 18380.49
[2,] 20371.54     0.00 19392.13 19476.78
[3,] 19136.91 19392.13     0.00 16651.73
[4,] 18380.49 19476.78 16651.73     0.00
  • 假设每个索引对应于这个矩阵 (out_1) 中的一个城市 - 有 4 个城市。

  • 任意(行、列)组合对应两个城市之间的距离(例如[2][3]对应城市2和城市3的距离)。

  • 从逻辑上讲,相同的两个城市之间的距离是相同的,例如[2] [3] = [3] [2]

  • 从逻辑上讲,一个城市与其自身的距离为 0,例如[2] [2] = 0

使用这个矩阵(out_1),我想从这个矩阵中计算所有具有以下结构的“路径”:

  • 路径必须从同一个城市开始和结束,并且除了第一个城市之外,其他城市不能两次访问。

例如,最终目标如下所示:

- Path 1 : [1] [2] , [2] [3], [3] [4], [4] [1] = 20371.54 + 19392.13 + 16651.73 + 18380.49 = 74795.89  
- Path 2 : [2] [4] , [4] [3], [3] [1], [1] [2] = 19476.78 + 16651.73 + 19136.91 + 20371.54 =   75636.96
- ....
- Path n: [3] [4] , [4] [1], [1] [2], [2] [3] =  16651.73 + 18380.49 + 20371.54 + 19392.13 =   74795.89 

我试图在 R 中找到一些库来执行此操作(注意:我认为我正在尝试做的事情被称为“图的哈密顿循环”):https://www.rdocumentation.org/packages/adagio/versions/0.8.4/topics/hamiltonian

但这不起作用:

    c = c(out_1)
 hamiltonian(c, cycle = TRUE)

    Error in graph_vect2list(edges) : 
      Argument 'edges' is not a correct edge list.

如何获得所有此类“路径”的列表,显示城市的顺序和每条路径的总距离?

谢谢!

【问题讨论】:

  • 您的路径是否需要仅访问其他城市一次?还是最多一次?
  • 您好!为简单起见 - 假设每个城市应该只访问一次。谢谢!

标签: r matrix


【解决方案1】:

在一个完整的顺序图 n 上有 factorial(n-1) 哈密顿循环——如果排除反向循环,则为一半,例如,如果在 n = 3 时仅保留 (123) 和 (132) 之一。在某些情况下,从 A 到 B 的距离与从 B 到 A 的距离不同,因此包含反向循环可能很有用。

这是一种计算所有factorial(n-1) 循环的方法,依赖包gtools 中的函数permutations 来执行“路径查找”。 gtoolsseveral 的替代品,您可以免费使用。

mkX <- function(n) {
    X <- abs(crossprod(matrix(rnorm(n * n), n, n)))
    diag(X) <- 0
    X
}

roundtrips <- function(X) {
    n <- nrow(X)
    if (n < 2L) {
        trips <- matrix(integer(0L), 0L, 0L)
        distances <- double(0L)
    } else {
        trips <- cbind(1L, gtools::permutations(n - 1L, n - 1L, seq.int(2L, n)))
        distances <- apply(trips, 1L, function(i) sum(X[cbind(i, c(i[-1L], 1L))]))
    }
    list(X = X, trips = trips, distances = distances)
}

set.seed(1L)
X <- mkX(4L)
roundtrips(X)
$X
          [,1]      [,2]     [,3]     [,4]
[1,] 0.0000000 0.4134306 1.058161 1.029243
[2,] 0.4134306 0.0000000 1.465003 2.127536
[3,] 1.0581611 1.4650029 0.000000 2.001777
[4,] 1.0292425 2.1275361 2.001777 0.000000

$trips
     [,1] [,2] [,3] [,4]
[1,]    1    2    3    4
[2,]    1    2    4    3
[3,]    1    3    2    4
[4,]    1    3    4    2
[5,]    1    4    2    3
[6,]    1    4    3    2

$distances
[1] 4.909453 5.600905 5.679943 5.600905 5.679943 4.909453

这里,X 是一个距离矩阵;它不需要是对称的,但在这个例子中是对称的。 trips 是一个整数矩阵,其行定义了图的不同哈密顿循环。 distances 是一个双向量,列出了在这些循环中遍历的距离。当X 对称时,距离成对出现,对应于循环和它们的倒数。

慎重选择nfactorial(n-1) 增长很快。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-06
    • 2011-12-20
    • 2021-05-11
    • 2010-12-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多