How to find all the possible permutations of a matrix in R?

天大地大妈咪最大 提交于 2021-02-10 23:19:03

问题


I have a matrix, for example, 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.

As you can see, the matrix is symmetric. Above the main diagonal, there are 4+3+2+1=10 positions, and I find via combn all the possible (permutation) matrices, which have (-2) 3 times in these 10 positions. That means 10!/3!*7!=120 matrices.

But some of them are equivalent.

So,my problem is how to find the non-equivalent matrices from the 120.

I am taking about permutation matrices, because if I pick one of the 120 matrices and I use rmperm, I have as a result one (random) of the 120 matrices.

When I have 5x5 and 6x6 matrices, I don't have problem, because I have developed an algorithm. But now I want to do the same in a 7x7 matrix and more, but the algorithm is very slow, because I have lots of loops.

So, I want with one command, when I pick a matrix from the 120 matrices, to give me ALL the permutations matrices from the 120.

Thanks a lot!


回答1:


Basically what you want is permutation of multiset. The package iterpc will do the job.

> 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 ]

Each row here is a permutations of 1 and 2. You should replace the 1's by -2.




回答2:


Basically, you're asking for all row/column permutations. For an n x n matrix there are n! (n factorial) permutations of the rows and n! permutations of the columns, for a total of (n!)^2 total row/column permutations (not all of which are necessarily unique).

The first step would be to obtain a sample dataset and get the set of all permutations of the row/column indices (I'm assuming square matrices but it would be easy to extend to the non-square case):

# 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

You can compute all pairings of the row/column orderings, which you can use to grab all possible row/column permutations:

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
# ...

Finally, you can use unique to grab the elements of all.perms that are unique matrices:

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


来源:https://stackoverflow.com/questions/29995794/how-to-find-all-the-possible-permutations-of-a-matrix-in-r

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!