5

マトラブで

p = randperm(n,k) は、1 ~ n を含む範囲でランダムに選択された k 個の一意の整数を含む行ベクトルを返します。

randperm() への 1 回の呼び出しで、それぞれが上記のような複数行のベクトルを返すことはできますか? そうでない場合、いくつかのランダム順列を生成する他の方法はありますか?

この場合、ループを回避すると必然的に速くなりますか?

ありがとう!

4

3 に答える 3

5

RANDPERM自体は、順列を 1 つだけ返します。ループを避けたい場合は、ARRAYFUN で呼び出すことができます:

Nperm = 5; 
N = 6;
result = arrayfun(@(x)randperm(N),(1:Nperm)','UniformOutput',0);

これにより、Nperm x 1 セル配列が返されます。それを行列に変換するには、CELL2MAT を使用できます。

result = cell2mat(result);

すべての順列を返すPERMS関数もありますが、少数の場合にのみ実用的です。

FileExchange の提出物ALLCOMBPERMSなど確認してください。

于 2013-03-28T14:58:34.947 に答える
1

に関してはp = randperm(n)

Matlab 2010a 以前では、入力パラメーターkはサポートされていません。randpermのコードを見ると

[~, p] = sort(rand(1,n));

要素のm順列を生成するように変更するのは非常に簡単であることがわかります (結果のサイズはxになりました)。nmn

[~, p] = sort(rand(m,n), 2);

に関してはp = randperm(n,k)

私のバージョンはそれをサポートしていないので、この場合Matlabがどのようにそれを行うのかわかりません。常に上記のようにしてからトリムすることができます:

p = p(:,1:k);

kただし、よりもはるかに小さい場合はあまり効率的ではありませんn

于 2014-08-10T22:48:54.107 に答える
1

すべての順列が相互に一意である必要がある場合は、次を使用できます

permN = 5; 
permK = 4; 
nPerms = 10;
nGoodPerms = 0;
nMaxFailedTries = 100; 
nFailedTries = 0;

permList = cell(nPerms, 1);

while nGoodPerms < nPerms && nFailedTries <= nMaxFailedTries
    candidatePerm = randperm(permN, permK);
    if any(cellfun(@(x)~isempty(x) && all(x == candidatePerm), permList))
        nFailedTries = nFailedTries + 1;
    else
        nGoodPerms = nGoodPerms + 1;
        permList{nGoodPerms} = candidatePerm;
    end
end

permList = cell2mat(permList{1:nGoodPerms});

要求されたすべての順列が生成されなかった場合は、おそらくそこに警告 (またはエラー) を表示する必要があります。また、前のチェックを追加して、 が馬鹿げたほど大きくないことを確認することもできます (つまり、指定されたandnPermsで生成できるよりも多くの一意の順列)。permNpermK

于 2013-03-28T15:12:06.913 に答える