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

a 夏天 提交于 2019-11-30 10:22:00

If you need simple but decent quality, I would use the upper 32 (or fewer) bits of a 64-bit LCG, possibly with a tempering function applied to the output. When doing this, I've copied the tempering function used in Mersenne Twister. I would not recommend actually using Mersenne Twister, as it has a lot more complexity and internal state than other PRNGs without significantly better qualities.

Here is some sample code:

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 would be one option. Another option is Subtract with carry

most implementations of the C rand() function use variations of LGC. rand(), like any computerized random generator is not truly random, it is only pseudo random. Using srand() can improve randomness, but not make it perfect. It depends on how varied and random the seed used in srand() is. For example if you called rand() n times using the same identical seed in srand(), the results would be the same. But if you called srand(clock()) each time (and the elapsed time between calls was greater than the period of ticks in clock()), then you would have an improved random generator.

Here is a simple code example, where both clock() and a support function, NotRecentlyUsed() (for small samples of min and max) are used:

#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;
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!