[英]Extend rand() max range
我創建了一個測試應用程序,可以生成0到250 000范圍內的10k隨機數。然后我計算出MAX和min值,並注意到MAX值總是在32k左右......
你知道如何擴大可能的范圍嗎? 我需要一個MAX值約為250 000的范圍!
這是根據rand()的定義,參見:
http://cplusplus.com/reference/clibrary/cstdlib/rand/
http://cplusplus.com/reference/clibrary/cstdlib/RAND_MAX/
如果您需要更大的隨機數,您可以使用外部庫(例如http://www.boost.org/doc/libs/1_49_0/doc/html/boost_random.html )或從多個小隨機數中計算大型隨機數數字由你自己。
但要注意你想要的分配。 如果只是總結小的隨機數,結果將不會平均分配。
如果您只是按常數因子縮放一個小的隨機數,則可能的值之間會有間隙。
取隨機數的乘積也不起作用。
可能的解決方案如下:
1) Take two random numbers a,b
2) Calculate a*(RAND_MAX+1)+b
因此,您可以獲得均勻分布的隨機值,最高可達(RAND_MAX + 1)^ 2-1
據推測,您還希望在此擴展范圍內平均分配。 關於可以有效執行此操作的唯一方法是生成一系列較小的數字,並將它們縮放,就像您在不同的基礎上工作一樣。 例如,對於250000,您可能在[0,10)范圍內有4個隨機數,在[0,25]范圍內有一個隨機數:
int
random250000()
{
return randomInt(10) + 10 * randomInt(10)
+ 100 * randomInt(10) + 1000 * randomInt(10)
+ 10000 * randomInt(25);
}
為此,你的隨機數生成器必須是好的; 許多rand()
都沒有(或者至少沒有 - 我最近沒有驗證過這種情況)。 您還希望消除將RAND_MAX + 1
不同值映射到10
或25
不同值時產生的偏差。 除非RAND_MAX + 1
是10
和25
的精確倍數(例如,是50
的精確倍數),否則您需要以下內容:
int
randomInt( int upperLimit )
{
int const limit = (RAND_MAX + 1) - (RAND_MAX + 1) % upperLimit;
int result = rand();
while ( result >= limit ) {
result = rand();
return result % upperLimit;
}
(執行此操作時注意:有些機器RAND_MAX + 1
將溢出;如果可移植性存在問題,則需要采取其他預防措施。)
當然,所有這一切都假設一台質量很好的發電機,這遠不是一個特定的發電機。
您可以通過生成較小的隨機數來按位操作數字。
例如,如果您需要32位隨機數:
int32 x = 0;
for (int i = 0; i < 4; ++i) { // 4 == 32/8
int8 tmp = 8bit_random_number_generator();
x <<= 8*i; x |= tmp;
}
如果你的數字不需要良好的隨機性,你可以使用rand()和0xff作為8位隨機數發生器。 否則,將需要更好的東西。
將您的數字向上擴展N / RAND_MAX
,其中N
是您所需的最大值。 如果數字合適,你可以這樣做:
unsigned long long int r = rand() * N / RAND_MAX;
顯然如果初始部分溢出你不能這樣做,但是N = 250000
你應該沒問題。 RAND_MAX
在許多流行平台上都是32K。
更一般地,要在區間[A, B]
統一得到隨機數,請使用:
A + rand() * (B - A) / RAND_MAX;
當然你應該使用正確的C ++風格的<random>
庫; 在此網站上搜索許多類似的問題,解釋如何使用它。
編輯:為了防止評論升級,這里是另一個正確的C ++解決方案的復制/粘貼,用於在區間[A, B]
上實現真正均勻分布:
#include <random>
typedef std::mt19937 rng_type;
typedef unsigned long int int_type; // anything you like
std::uniform_int_distribution<int_type> udist(A, B);
rng_type rng;
int main()
{
// seed rng first:
rng_type::result_type const seedval = get_seed();
rng.seed(seedval);
int_type random_number = udist(rng);
// use random_number
}
不要忘記看到RNG! 如果存儲種子值,則可以稍后重播相同的隨機序列。
你使用的是短期投資嗎? 如果是這樣,你會看到32,767作為你的最大數量,因為任何更大的數據都會溢出short int。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.