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

戏子无情 提交于 2019-12-30 03:34:07

问题


I want to design a lottery scheduler and I need to have a very good (pseudo) random number generator similar to LCG but I was wondering if there are other better choice out there or not? I am specifically looking for random generators written in C.

LCG code:

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

Also I would like to know if srand() can be used for this purpose or is not highly accurate?


回答1:


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);
}



回答2:


Mersenne Twister would be one option. Another option is Subtract with carry




回答3:


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;
}


来源:https://stackoverflow.com/questions/19083566/what-are-the-better-pseudo-random-number-generator-than-the-lcg-for-lottery-sc

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