簡體   English   中英

擴展rand()最大范圍

[英]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不同值映射到1025不同值時產生的偏差。 除非RAND_MAX + 11025的精確倍數(例如,是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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM