C ++ generates random numbers -- generates random numbers with equal probability in any range

Source: Internet
Author: User

If you want to use C ++ to generate a random number between 0--n-1, what would you do? You may say that it is very simple. See:

Srand (unsigned) Time (null ));
Rand () % N;

Think about it, is the result random (of course, we do not consider the pseudo-randomness of the Rand () function )?

No, because the upper limit of rand () is rand_max. Generally, rand_max is not an integer multiple of n. If rand_max % = r, the probability of a value between 0 and R is larger, while the probability of a value between R + 1--n-1 is smaller. What should I do if n> rand_max?

The following provides a suitable solution to generate an equi-probability random number result in any range. Finally, there is a simpler method.

1. If n <rand_max + 1, remove the ending number,

R = rand_max-(rand_max + 1) % N; // remove the ending number
T = rand ();
While (T> r) t = rand ();
Result = T % N; // random number that meets the requirements

2. If n> rand_max, you can consider segmented sampling and divide it into [N/(rnad_max + 1)] segments. First, obtain the segments with equal probability and then obtain an element in each segment, in this way, the segmentation is similar to the ending number problem. Instead of just getting to the integer segment every time, there must be more or less an remainder segment. How to select the value of this part?

Select the data from the remainder segment. First, select an event with the probability of the remainder segment, and then select it separately:

R = n % (rand_max + 1); // Remainder
If (happened (double) r/n) // probability of selecting the remainder
Result = N-R + myrandom (r); // myrandom can be implemented using the code in scenario 1.
Else
Result = rand () + myrandom (N/(rand_max + 1) * (rand_max + 1); // select segments if the remainder segment is not selected

Complete code:
# Include <iostream. h>
# Include <time. h>
# Include <stdlib. h>
Const double minprob = 1.0/(rand_max + 1 );
Bool happened (double probability) // probability 0 ~ 1
{
If (probability <= 0)
{
Return false;
}
If (probability <minprob)
{
Return rand () = 0 & happened (probability * (rand_max + 1 ));
}
If (RAND () <= probability * (rand_max + 1 ))
{
Return true;
}
Return false;
}

Long myrandom (long n) // generates 0 ~ Equal Probability random number between n-1
{
T = 0;
If (n <= rand_max)
{
Long r = rand_max-(rand_max + 1) % N; // The ending number.
T = rand ();
While (T> r)
{
T = rand ();
}
Return T % N;
}
Else
{
Long r = n % (rand_max + 1); // Remainder
If (happened (double) r/n) // The probability of getting the remainder
{
Return N-R + myrandom (R );
}
Else
{
Return rand () + myrandom (N/(rand_max + 1) * (rand_max + 1 );
}
}
}

 

Another very simple method is to use

Random_shuffle (randomaccessiterator _ first, randomaccessiterator _ last ).

For example, to generate a random number between 0--n-1, you can write

# Include <algorithm>
# Include <vector>

Long myrandom (long N)
{
STD: vector <long> VL (n); // defines a vector of N.
For (long I = 0; I <n; ++ I)
{
Vl [I] = I;
}

STD: random_shuffle (Vl. Begin (), Vl. End ());

Return (* Vl. Begin ());
}

Random_shuffle also has an overloaded version with three parameters.

Random_shuffle (randomaccessiterator _ first, randomaccessiterator _ last, randomnumbergenerator & _ rand)

The third parameter can accept a custom random number generator to randomize the elements between the first two parameters.

The disadvantage of this method is that if only a random number is needed, when n is large, the space consumption is very large!

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.