6

Given an integer k how would I create a permutation matrix with all possible permutations of the sequence 1 to k? For example, let's consider k=2. Then I would like to create the matrix:

1 2
2 1

and for k=3:

1 1 2 2 3 3
2 3 1 3 1 2 
3 2 3 1 2 1

I've tried using numpy.random.permutation but this only produces a single permutation. So, I could continue using this function, appending unique permutations until the number of columns is equal to k! but this seems incredibly inefficient.

Apollo
  • 8,874
  • 32
  • 104
  • 192

3 Answers3

1

Based off this answer:

import numpy as np
import itertools as it
import math
def myPerms(k):
  f_k=math.factorial(k)
  A=np.empty((k,f_k))
  for i,perm in enumerate(it.permutations(range(k))):
    A[:,i] = perm
  A+=1
  return A

print(myPerms(3))
#[[ 1.  1.  2.  2.  3.  3.]
# [ 2.  3.  1.  3.  1.  2.]
# [ 3.  2.  3.  1.  2.  1.]]
Community
  • 1
  • 1
Felipe Lema
  • 2,700
  • 12
  • 19
1

How about a pure numpy solution:

from math import factorial as fac
import numpy as np

def permmat(n):
    if n==1:
        return np.array([[1]], dtype=np.int8)
    fnm1 = fac(n-1)
    pmat_nm1 = permmat(n-1)
    pmat = np.empty((n, fac(n)), dtype=np.int8)
    pmat[0] = np.repeat(np.arange(n,0,-1), fnm1)
    pmat[1:, :fnm1] = pmat_nm1
    for i in range(1,n):
        view = pmat[1:, fnm1*i:fnm1*(i+1)]
        view[:,:] = pmat_nm1
        view[pmat_nm1==(n-i)] = n
    return pmat

print(permmat(4))

Output:

[[4 4 4 4 4 4 3 3 3 3 3 3 2 2 2 2 2 2 1 1 1 1 1 1]
 [3 3 2 2 1 1 4 4 2 2 1 1 3 3 4 4 1 1 3 3 2 2 4 4]
 [2 1 3 1 2 3 2 1 4 1 2 4 4 1 3 1 4 3 2 4 3 4 2 3]
 [1 2 1 3 3 2 1 2 1 4 4 2 1 4 1 3 3 4 4 2 4 3 3 2]]

There's still space for some performance hack but I'm too lazy to write them.

Kh40tiK
  • 2,276
  • 19
  • 29
-1

my solution:

perm_mat = np.zeros(PERM_SIZE,NUM_OF_PERM))
for i in range(NUM_OF_PERM):
perm_mat[:,i] = np.random.permutation(PERM_SIZE))
perm_mat = perm_mat.astype(int)
Nadav
  • 157
  • 1
  • 1
  • 7