2013-10-28 11 views
5

からランダム非反復整数を生成します。次され、私が達成しようとしているどのような小さな範囲

私は比較的小さな範囲から、整数のベクトルを作成したい、と整数のことを確認してください。同じ整数が続きます。

すなわち、これは、 "合法" ベクトルである: [1 2 3 4 5 3 2 3 5 4]

及び(5 5以下のため)、これは、 "違法" ベクトルである: [1 3 4 2 5 5 2 3 5 4]

私はとすべてのバリエーションをrandpermで実験しましたが、小さな範囲から約100個の要素のベクトルを生成しようとすると、すなわち、1と5の間の整数)。

機能はあまりにも長い間実行されます。

ここで私が作った試みの一つだ:

function result = nonRepeatingRand(top, count) 

    result = randi(top, 1, count); 

    while any(diff(result) == 0) 
     result = randi(top, 1, count);  
    end 

end 

任意およびすべてのヘルプははるかに高く評価されます。ありがとう!

+2

ほんの少しのコメントを楽しみます。反復の条件は、あなたのベクトルが「ランダム」でないことを意味します。 – bla

答えて

11

あなたが探しているシーケンスの種類はランダムな初期値から始めて、違い1からtop - 1までを生成して、累積和を計算モジュラスtopによって定義することができます:オン

function result = nonRepeatingRand(top, count) 

    diff = randi(top - 1, 1, count); 
    result = rem(cumsum(diff) + randi(1, 1, count) - 1, top) + 1; 

end 

私のマシンでは、これは0.58秒で1:5のうち1000万の数字の非反復シーケンスを生成します。

+0

+1非常に巧妙な解決策! –

+0

どうやってそれを思いついたのか分かりません...?とにかく、私の+1! –

+1

ポスターを実装したいという制約が、diffに関して最も簡単に表現されています。ですから、まずdiffとそのシーケンスを生成しないでください。 –

0

どのようにこれ?

top = 5; 
count = 100; 
n1 = nan; 
out = []; 
for t = 1: count 
    n2 = randi(top); 
    while n1 == n2 
     n2 = randi(top); 
    end 
    out = [out, n2]; 
    n1 = n2; 
end 
1

繰り返しを繰り返さないでください。例:私のマシンでは、これは1.6秒で1:5のうち1000万の数字の非繰り返しシーケンスを生成します。

+1

私の他の答えはより良いと思います。より速く、よりエレガントです。 –

0

(randpermのように)すべての値が均等になるように、この「ランダム」シーケンスを反復なしで作成するオプションはありますか?

randpermは限らに思える、と私は...私の「均等配分critereonが」満たされるまで、whileループで最初の関数を呼び出すと考えることができますが、それはより速く行うことができますか?

2

あなたは非がM

randperm(M)に1から乱数を繰り返し生成するために、次のコードを使用することができます。 1からM

に乱数を繰り返す

及びK以外のため

randperm(M、K)。

+1

ありがとうございます:あなたが気づいたように、質問は(非常にエレガントに)約1年前に答えられました。正解にはそのような印が付けられました。第2に、私が質問した質問に答えられなかったのではないかと心配しています.1から4の範囲の100の非繰り返し乱数のシーケンスが必要な場合、 'randperm(4,100)'は誤りを返します。 –

+0

あなたの答えは非常に単純ですが、あなたは最高の愛する、歓声です – Christina

関連する問題