Generate Random(a, b) making calls to Random(0, 1)

后端 未结 5 747
-上瘾入骨i
-上瘾入骨i 2021-01-03 07:37

There is known Random(0,1) function, it is a uniformed random function, which means, it will give 0 or 1, with probability 50%. Implement Random(a, b)

5条回答
  •  谎友^
    谎友^ (楼主)
    2021-01-03 08:15

    Your inclination to put the range from 0 to a-b first is correct. However, you cannot do it as you stated. This question asks exactly how to do that, and the answer utilizes unique factorization. Write m=a-b in base 2, keeping track of the largest needed exponent, say e. Then, find the biggest multiple of m that is smaller than 2^e, call it k. Finally, generate e numbers with RANDOM(0,1), take them as the base 2 expansion of some number x, if x < k*m, return x, otherwise try again. The program looks something like this (simple case when m<2^2):

    int RANDOM(0,m) {
    
        // find largest power of n needed to write m in base 2
        int e=0;
        while (m > 2^e) {
            ++e;
        }
    
        // find largest multiple of m less than 2^e
        int k=1;
        while (k*m < 2^2) {
            ++k
        }
        --k; // we went one too far
    
        while (1) {
            // generate a random number in base 2
            int x = 0;
            for (int i=0; i

    Now you can simply add a to the result to get uniformly distributed numbers between a and b.

提交回复
热议问题