2013-10-28 287 views
5

我試圖做到的是以下幾點:生成一個小範圍的隨機不重複的整數

我希望創建一個整數向量,從一個相對較小的範圍內,並確保沒有整數後面跟着相同的整數。

即,這是一個 「合法」 的向量: [1 3 4 2 5 3 2 3 5 4]

,這是一個 「非法」 載體(自5如下5): [1 3 4 2 5 5 2 3 5 4]

我試過用randi和各種各樣的變化與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

那種序列的你正在尋找可以通過產生差異1top - 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。那麼爲什麼不先生成差異,並從中得出序列。 –

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

不要每次重新生成序列,而是要修復重複。例如:

function result = nonRepeatingRand(top, count) 

    result = randi(top, 1, count); 

    ind = (diff(result) == 0); 
    while any(ind) 
     result(ind) = []; 
     result(end + 1 : count) = randi(top, 1, count - numel(result)); 

     ind = (diff(result) == 0); 
    end 

end 

在我的機器上,這會在1.6秒內生成1:5的1000萬數字的非重複序列。

+1

我認爲我的其他答案更好:更快,更優雅。 –

0

是否有可能選擇創建此「隨機」序列而不重複,以便所有值均勻分佈(與randperm一樣)?

randperm似乎有限,我只能想到在while循環中調用第一個函數,直到我的「平等分配標準」滿足..但它可以更快地完成?

2

可以使用下面的代碼生成非重複的隨機數從1到M

randperm(M);

和對於K的非重複從1個隨機數至M

randperm(M,K);

享受

+1

謝謝,但是:正如你可能已經注意到的那樣,這個問題在一年前得到了(非常優雅的)回答,正確的答案被標記爲這樣。其次,恐怕你沒有回答我問過的問題 - 如果我需要在1-4範圍內的100個非重複隨機整數序列,'randperm(4,100)'當然會返回一個錯誤。 –

+0

你的答案非常簡單,但你是最好的親愛的,乾杯 – Christina

相關問題