It is known that a function rand7 () can generate a random number ranging from 1 to 7. Please provide a function rand10 () that can generate a random number ranging from 1 to 10.

Source: Internet
Author: User

Question:

It is known that a function rand7 () can generate a random number ranging from 1 to 7. Please provide a function that can generate a random number ranging from 1 to 10.

Ideas:

If we know that a function can generate a random number ranging from 1 to 49, how can we generate a random number ranging from 1 to 10?

Solution:

This solution is based on a method called reject sampling. The main idea is to generate a random number within the target range and return it directly. If the random number is not within the target range, the value is discarded and the sampling is performed again. Because the number in the target range is selected with the same probability, such an even distribution is generated.

Obviously, rand7 must be executed at least twice; otherwise, a number ranging from 1 to 10 may not be generated. Run rand7 twice to generate an integer ranging from 1 to 49,

   1  2  3  4  5  6  71  1  2  3  4  5  6  72  8  9 10  1  2  3  43  5  6  7  8  9 10  14  2  3  4  5  6  7  85  9 10  1  2  3  4  56  6  7  8  9 10  *  *7  *  *  *  *  *  *  *

Because 49 is not a multiple of 10, we need to discard some values. The expected number range is 1-40. If it is not in this range, it is discarded and re-sampled.

Code:

int rand10() {  int row, col, idx;  do {    row = rand7();    col = rand7();    idx = col + (row-1)*7;  } while (idx > 40);  return 1 + (idx-1)%10;}

Because the row range is 1-7 and the col range is 1-7, the idx value range is 1-49. The value greater than 40 is discarded, so that the number in the range of 1-40 is returned by modulo. The following is an expected value for the number of times a sample is required to meet the value range of 1 to 40:

E(# calls to rand7) = 2 * (40/49) +                      4 * (9/49) * (40/49) +                      6 * (9/49)2 * (40/49) +                      ...                      ∞ = ∑ 2k * (9/49)k-1 * (40/49) k=1 = (80/49) / (1 - 9/49)2 = 2.45

Optimization:

The above method requires about 2.45 calls to the rand7 function to obtain a number in the range of 1-10. The following optimization can be performed again.

If the number is greater than 40, we do not need to discard it immediately. We can subtract the number from 41-49 from 40 to get a random number from 1 to 9, while rand7 can generate a random number from 1 to 7, which can generate a random number from 1 to 63. For 1-60, we can directly return data, while for-63, we discard data. In this way, there are only three discarded data, which is more efficient than the previous nine. For the numbers from 61-63, after 60, the value is 1-3. rand7 generates 1-7, which can be reused to generate 1-21 numbers. For numbers from 1 to 20, we directly return, for 21, it is discarded. At this time, the number of dropped items is only one, and the optimization is further improved. Of course, the number of rand7 calls also increases. The Code is as follows:

int rand10Imp() {  int a, b, idx;  while (true) {    a = rand7();    b = rand7();    idx = b + (a-1)*7;    if (idx <= 40)      return 1 + (idx-1)%10;    a = idx-40;    b = rand7();    // get uniform dist from 1 - 63    idx = b + (a-1)*7;    if (idx <= 60)      return 1 + (idx-1)%10;    a = idx-60;    b = rand7();    // get uniform dist from 1-21    idx = b + (a-1)*7;    if (idx <= 20)      return 1 + (idx-1)%10;  }}

The following calculates the expected number of times the optimized method calls the rand7 function:

E(# calls to rand7) = 2 * (40/49) +                      3 * (9/49) * (60/63) +                      4 * (9/49) * (3/63) * (20/21) +                       (9/49) * (3/63) * (1/21) *                      [ 6 * (40/49) +                        7 * (9/49) * (60/63) +                        8 * (9/49) * (3/63) * (20/21) ] +                      ((9/49) * (3/63) * (1/21))2 *                      [ 10 * (40/49) +                        11 * (9/49) * (60/63) +                        12 * (9/49) * (3/63) * (20/21) ] +                      ...                    = 2.2123

The expected number of times is 2.21, which is about 2.45 less than the unoptimized 10%.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.