c 生成偽隨機數的方法

2021-07-05 07:27:31 字數 1240 閱讀 8359

**:

假如你想用c++來生成0——n-1之間的隨機數,你會怎麼做?你可能會說,很簡單,看:

srand( (unsigned)time( null ) );

rand() % n;

仔細想一下,這個結果是隨機的嗎(當然,我們不考慮rand()函式的偽隨機性)?

不是的,因為rand()的上限是rand_max,而一般情況下,rand_max並不是n的整數倍,那麼如果rand_max % = r,則0——r之間的數值的概率就要大一些,而r+1——n-1之間的數值的概率就要小一些。還有,如果n > rand_max,那該怎麼辦?

下面給出一種比較合適的方案,可以生成任意範圍內的等概率隨機數 result。最後還有乙個更簡單的方法。

1、如果n

r = rand_max-(rand_max+1)%n; //去除尾數

t = rand();

while( t > r ) t = rand();

result = t % n; // 符合要求的隨機數

2、如果 n>rand_max,可以考慮分段抽樣,分成[n/(rnad_max+1)]段,先等概率得到段再得到每段內的某個元素,這樣分段也類似地有乙個尾數問題,不是每次都剛好分到整數段,一定或多或少有乙個餘數段,這部分的值如何選取?

選到餘數段的資料拿出來選取,先進行一次選到餘數段概率的事件發生,然後進行單獨選取:

還有另外一種非常簡單的方式,那就是使用

random_shuffle( randomaccessiterator _first, randomaccessiterator _last ).

例如,生成0——n-1之間的隨機數,可以這麼寫

#include 

#include

long myrandom( long n )

std::random_shuffle( vl.begin(), vl.end() );

return (*vl.begin());

}random_shuffle 還有乙個三引數的過載版本

random_shuffle( randomaccessiterator _first, randomaccessiterator _last, randomnumbergenerator& _rand )

第三個引數可以接受乙個自定義的隨機數生成器來把前兩個引數之間的元素隨機化。

這個方法的缺陷就是,如果只是需要乙個隨機數的話,當n很大時,空間消耗很大!

生成偽隨機數

真正的隨機數只能自然生成,所以我們人工得到的隨機數被稱為偽隨機數。使用中的rand 函式可以生成0 rand max之間的隨機整數.rand 函式使用乙個起始的種子值生成一系列數字,對於乙個特定的種子產生的序列數永遠是相同的。如果使用rand 函式只使用乙個種子值,即預設的種子值,就會使得序列數是有...

隨機數生成 偽隨機數和真隨機數

c語言隨機數的生成,很隨機,又不隨機,比如像下面的程式 c語言生成隨機數的函式在stdlib.h庫中 include includeint main return 0 上面的 經過執行生成了 41 18467 6334 26500但是無論執行多好遍結果都是一樣的,隨機數並不隨機。這是因為rand 函...

C語言偽隨機數的生成

在stdlib.h中,有兩個函式與偽隨機數的生成有關 srand和rand。c語言中,隨機數表有很多列,srand函式是根據其引數 unsigned型別 來獲得乙個種子 seed 根據種子來設定從哪一列開始取隨機數。rand無引數,返回乙個相應的隨機數。種子相同,則從同一列隨機數中選取,rand每次...