【问题标题】:How to find all the possible permutations of a matrix in R?如何在R中找到矩阵的所有可能排列?
【发布时间】:2015-05-01 22:02:56
【问题描述】:

我有一个矩阵,例如 5x5。

     [,1] [,2] [,3] [,4] [,5]
[1,]   22   -2   -2   -2    2
[2,]   -2   22    2    2    2
[3,]   -2    2   22    2    2
[4,]   -2    2    2   22    2
[5,]    2    2    2    2   22.

如您所见,矩阵是对称的。 在主对角线上方,有 4+3+2+1=10 个位置,我通过combn 找到所有可能的(排列)矩阵,在这 10 个位置中有 (-2) 3 次。这意味着 10!/3!*7!=120 个矩阵。

但其中一些是等价的。

所以,我的问题是如何从 120 中找到非等价矩阵。

我正在研究置换矩阵,因为如果我选择 120 个矩阵中的一个并使用 rmperm,我会得到 120 个矩阵中的一个(随机)。

当我有 5x5 和 6x6 矩阵时,我没有问题,因为我已经开发了一种算法。但现在我想在 7x7 矩阵中做同样的事情,但算法很慢,因为我有很多循环。

所以,我想用一个命令,当我从 120 个矩阵中选择一个矩阵时,给我 120 个矩阵中的所有排列矩阵。

非常感谢!

【问题讨论】:

  • 如果,正如 josilber 所说,您正在寻找所有行和列排列,那就是 n!^2。对于 10x10 矩阵,超过 13 个 trillion 矩阵,这可能太多了,无法先创建然后挑选出唯一的矩阵。是否有任何对称或结构可以用来缩小问题?
  • Gregor,我使用的矩阵是对称的。
  • 在非对角线位置上是否总是只有 2 个数字(上例中的 -2 和 2)?例如,如果你在这 10 个位置中有 1 到 10 的数字,那么就会有 10 个!它们的排列,所有这些都是独一无二的。在上面的示例中,您能够说只有 120 个排列(不一定都是唯一的)的唯一原因是因为您假设只有两个唯一值,拆分 7/3。
  • 正是 josilber!我总是在非对角线位置上只有 2 个数字(2 和 -2)!
  • 基本上你想要的是多重集的排列。包iterpc 将完成这项工作。

标签: r algorithm matrix permutation


【解决方案1】:

基本上,您要求的是所有行/列排列。对于一个 n x n 矩阵,有 n! (n 阶乘) 行和 n! 的排列列的排列,总共有 (n!)^2 行/列排列(并非所有排列都必须是唯一的)。

第一步是获取样本数据集并获取行/列索引的所有排列的集合(我假设为方形矩阵,但很容易扩展到非方形情况):

# Sample dataset:
library(sna)
set.seed(100)
(g <- rgraph(3))
#      [,1] [,2] [,3]
# [1,]    0    0    1
# [2,]    1    0    0
# [3,]    1    1    0

# All permutations of indices
library(gtools)
(perms <- permutations(nrow(g), nrow(g)))
#      [,1] [,2] [,3]
# [1,]    1    2    3
# [2,]    1    3    2
# [3,]    2    1    3
# [4,]    2    3    1
# [5,]    3    1    2
# [6,]    3    2    1

您可以计算行/列排序的所有配对,您可以使用它们来获取所有可能的行/列排列:

pairings <- expand.grid(1:nrow(perms), 1:nrow(perms))
head(pairings)
#   Var1 Var2
# 1    1    1
# 2    2    1
# 3    3    1
# 4    4    1
# 5    5    1
# 6    6    1
all.perms <- lapply(1:nrow(pairings), function(x) g[perms[pairings[x,1],], perms[pairings[x,2],]])
head(all.perms)
# [[1]]
#      [,1] [,2] [,3]
# [1,]    0    0    1
# [2,]    1    0    0
# [3,]    1    1    0
# 
# [[2]]
#      [,1] [,2] [,3]
# [1,]    0    0    1
# [2,]    1    1    0
# [3,]    1    0    0
# ...

最后,您可以使用unique 来获取all.perms 中唯一矩阵的元素:

all.unique.perms <- unique(perms)
length(all.unique.perms)
# [1] 18

【讨论】:

  • Josilber,非常感谢,但也许我没有解释清楚。看,我的问题,因为我要编辑它!
【解决方案2】:

基本上你想要的是多重集的排列。包 iterpc 将完成这项工作。

> library(iterpc)
> I <- iterpc(c(3,7), ordered=TRUE)
> getlength(I)
[1] 120
> getall(I)
      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
  [1,]    1    1    1    2    2    2    2    2    2     2
  [2,]    1    1    2    1    2    2    2    2    2     2
  [3,]    1    1    2    2    1    2    2    2    2     2
  [4,]    1    1    2    2    2    1    2    2    2     2
  [5,]    1    1    2    2    2    2    1    2    2     2
  [6,]    1    1    2    2    2    2    2    1    2     2
  [7,]    1    1    2    2    2    2    2    2    1     2
  [8,]    1    1    2    2    2    2    2    2    2     1
  [9,]    1    2    1    1    2    2    2    2    2     2
 [10,]    1    2    1    2    1    2    2    2    2     2
 [11,]    1    2    1    2    2    1    2    2    2     2
 [12,]    1    2    1    2    2    2    1    2    2     2
 [13,]    1    2    1    2    2    2    2    1    2     2
 [14,]    1    2    1    2    2    2    2    2    1     2
 [15,]    1    2    1    2    2    2    2    2    2     1
 [16,]    1    2    2    1    1    2    2    2    2     2
 [17,]    1    2    2    1    2    1    2    2    2     2
 [18,]    1    2    2    1    2    2    1    2    2     2
 [19,]    1    2    2    1    2    2    2    1    2     2
 [20,]    1    2    2    1    2    2    2    2    1     2
 [ reached getOption("max.print") -- omitted 100 rows ]

这里的每一行都是 1 和 2 的排列。您应该将 1 替换为 -2。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-30
    • 2022-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多