簡體   English   中英

與彩票調度程序的LCG相比,更好的(偽)隨機數發生器是什么?

[英]What are the better (pseudo) random number generator than the LCG for lottery scheduler?

我想設計一個彩票調度器,我需要一個非常好的(偽)隨機數發生器,類似於LCG,但我想知道是否還有其他更好的選擇? 我特意尋找用C語言編寫的隨機生成器。

LCG代碼:

unsigned long lcg_rand(unsigned long a)
{
  return (a * 279470273UL) % 4294967291UL;
}

另外我想知道srand()可以用於此目的或不是非常准確?

如果你需要簡單但體面的質量,我會使用64位LCG的高32位(或更少),可能還有一個應用於輸出的回火功能。 這樣做時,我復制了Mersenne Twister中使用的回火功能。 我不建議實際使用Mersenne Twister,因為它比其他PRNG具有更多的復雜性和內部狀態而沒有明顯更好的品質。

以下是一些示例代碼:

static uint32_t temper(uint32_t x)
{
    x ^= x>>11;
    x ^= x<<7 & 0x9D2C5680;
    x ^= x<<15 & 0xEFC60000;
    x ^= x>>18;
    return x;
}
uint32_t lcg64_temper(uint64_t *seed)
{
    *seed = 6364136223846793005ULL * *seed + 1;
    return temper(*seed >> 32);
}

Mersenne Twister是一個選擇。 另一種選擇是減去攜帶

C rand()函數的大多數實現都使用LGC的變體。 rand() ,就像任何計算機化的隨機生成器不是真正隨機的,它只是偽隨機的。 使用srand()可以改善隨機性,但不能使其完美。 它取決於srand()使用的種子的變化和隨機性。 例如,如果你在srand()使用相同的相同種子n次調用rand() n次,結果將是相同的。 但是如果你每次都調用srand(clock()) (並且調用之間經過的時間大於clock()的ticks周期),那么你將擁有一個改進的隨機生成器。

這是一個簡單的代碼示例,其中使用了clock()和支持函數NotRecentlyUsed() (對於minmax的小樣本):

#include <ansi_c.h>

#define _UNIQUE_

int randomGenerator(int min, int max);
int NotUsedRecently (int number);

int main(void)
{
    int i=0;
    for(i=0;i<1000;i++)
    {
        printf("%d,\t", randomGenerator(0, 20));
            if(i%20 == 0) printf("\n");
    }
    getchar();
    return 0;   
}

//////////////////////////////////////////////////////
//generates pseudo random numbers between min and max
//If it is desired to use this without a guarantee of uniqueness
//for a specified span of values, un-define _UNIQUE_
//
int randomGenerator(int min, int max)
{
    int random, trying;

    trying = 1;         
    while(trying)
    {
        srand(clock());
        random = (rand()/32767.0)*(max+1);
        ((random >= min)
#ifdef _UNIQUE_
            && NotUsedRecently(random) 
#endif
            ) ? (trying = 0) : (trying = 1);
    }

    return random;
}

//This function is used to guarantee that a span of n generated values
//will not be the same. To adjust the span, change the index in 
//static int recent[n];  Note: it is required that n < (max-min)
//otherwise an infinite loop will occur
int NotUsedRecently (int number)
{
    static int recent[20];//Use No greater value for index than max - min
    int i,j;
    int notUsed = 1;

    for(i=0;i<(sizeof(recent)/sizeof(recent[0]));i++)  (number != recent[i]) ? (notUsed==notUsed) : (notUsed=0, i=(sizeof(recent)/sizeof(recent[0])));
    if(notUsed) 
    {
        for(j=(sizeof(recent)/sizeof(recent[0]));j>1;j--)
        {
            recent[j-1] = recent[j-2];
        }
        recent[j-1] = number;
    }
    return notUsed;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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