マトラブで
p = randperm(n,k) は、1 ~ n を含む範囲でランダムに選択された k 個の一意の整数を含む行ベクトルを返します。
randperm() への 1 回の呼び出しで、それぞれが上記のような複数行のベクトルを返すことはできますか? そうでない場合、いくつかのランダム順列を生成する他の方法はありますか?
この場合、ループを回避すると必然的に速くなりますか?
ありがとう!
マトラブで
p = randperm(n,k) は、1 ~ n を含む範囲でランダムに選択された k 個の一意の整数を含む行ベクトルを返します。
randperm() への 1 回の呼び出しで、それぞれが上記のような複数行のベクトルを返すことはできますか? そうでない場合、いくつかのランダム順列を生成する他の方法はありますか?
この場合、ループを回避すると必然的に速くなりますか?
ありがとう!
RANDPERM自体は、順列を 1 つだけ返します。ループを避けたい場合は、ARRAYFUN で呼び出すことができます:
Nperm = 5;
N = 6;
result = arrayfun(@(x)randperm(N),(1:Nperm)','UniformOutput',0);
これにより、Nperm x 1 セル配列が返されます。それを行列に変換するには、CELL2MAT を使用できます。
result = cell2mat(result);
すべての順列を返すPERMS関数もありますが、少数の場合にのみ実用的です。
に関してはp = randperm(n)
:
Matlab 2010a 以前では、入力パラメーターk
はサポートされていません。randperm
のコードを見ると
[~, p] = sort(rand(1,n));
要素のm
順列を生成するように変更するのは非常に簡単であることがわかります (結果のサイズはxになりました)。n
m
n
[~, p] = sort(rand(m,n), 2);
に関してはp = randperm(n,k)
:
私のバージョンはそれをサポートしていないので、この場合Matlabがどのようにそれを行うのかわかりません。常に上記のようにしてからトリムすることができます:
p = p(:,1:k);
k
ただし、よりもはるかに小さい場合はあまり効率的ではありませんn
。
すべての順列が相互に一意である必要がある場合は、次を使用できます
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
で生成できるよりも多くの一意の順列)。permN
permK