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

后端 未结 3 1070
滥情空心
滥情空心 2020-12-30 17:15

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

相关标签:
3条回答
  • 2020-12-30 17:51

    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);
    }
    
    0 讨论(0)
  • 2020-12-30 17:54

    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;
    }
    
    0 讨论(0)
  • 2020-12-30 18:06

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

    0 讨论(0)
提交回复
热议问题