2016-11-28 8 views
2

与えられた整数k からkまでのすべての可能な順列を持つ置換行列をどのように作成すればよいですか?たとえば、k=2を考えてみましょう。それから私は、マトリックスを作成したいと思います:順列行列を作成する - numpy

1 2 
2 1 

k=3のために:私はnumpy.random.permutationを使用して試してみたが、これは、単一の順列を生成

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

。だから、私は列の数がk!に等しくなるまで一意の順列を付け加えてこの関数を使い続けることができますが、これは信じられないほど非効率的です。

+1

何numpyの配列に 'itertools.permutations'を供給についてはどうですか? –

+0

@YakymPirozhenkoは 'itertools'をインポートせずにこれを行うことができますか? – Apollo

+3

順列のリストを生成する独自の関数を記述しない限り、そうではありません。また、 'itertools'は組み込みモジュールなので、明示的な制限がない限り、インポートには大きな欠点はありません。 –

答えて

0

オフに基づいて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.]] 
0

どのように純粋なnumpyのソリューションについて:

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

出力:あり、まだいくつかのパフォーマンスのハックのためのスペースだが、私はあまりにもだ

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

それらを書くのは怠惰です。

0

私の解決策:

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) 
関連する問題