Method for generating random numbers with arbitrary distribution-VC ++ Program Implementation

Source: Internet
Author: User
Tags random seed

I. Generation of evenly distributed random numbers

As we all know, random numbers play a major role in all aspects. In the VC environment, we provide the library function rand () to generate a random integer. The random number ranges from 0 to 0 on average ~ Rand_max is evenly distributed. rand_max is a constant defined in the vc6.0 environment as follows:

#define RAND_MAX 0x7fff

It is the maximum value of a short type data. To generate a floating-point random number, you can use rand ()/1000.0 To Get A 0 ~ A random floating point number that is evenly distributed between 32.767. If you want to increase the range, you can generate a linear combination of several random numbers to realize random numbers distributed evenly in any range. For example, to generate-1000 ~ The accuracy between 1000 is a random number with an even distribution of four decimal places. Generates a random integer between 0 and 10000. The method is as follows:

int a = rand()%10000;

Then the four decimal places are retained to generate 0 ~ Random decimal number between 1:

double b = (double)a/10000.0;

Then, a linear combination can be used to generate random numbers in any range.-1000 ~ The Random Number of the average distribution within 1000 can be as follows:

double dValue = (rand()%10000)/10000.0*1000-(rand()%10000)/10000.0*1000;

Dvalue is the desired value.

So far, you may think that all the work has been completed. Otherwise, you may find that there is a problem. After simplifying the formula above, it will become:

double dValue = (rand()%10000)/10.0-(rand()%10000)/10.0;

In this way, the range of the generated random number is correct, but the accuracy is incorrect. It turns into a random number with only one correct decimal number, and the decimal number of the last three digits is zero, obviously it's not what we want. Why? What should we do.

Find the cause first. The Random Number Resolution produced by rand () is 32767, and the two are 65534. After the remainder, the degree of parallelism is reduced to 10000, the two are 20000 and the required resolution is 1000*10000*2 = 20000000, which is obviously far from enough. The methods provided below can achieve the correct results:

double a = (rand()%10000) * (rand()%1000)/10000.0;    double b = (rand()%10000) * (rand()%1000)/10000.0;    double dValue = a-b;

Dvalue is the required result. In the following function, you can generate a random number with an average distribution within a range with a precision of 4 decimal places.

double AverageRandom(double min,double max)    {        int minInteger = (int)(min*10000);        int maxInteger = (int)(max*10000);        int randInteger = rand()*rand();        int diffInteger = maxInteger - minInteger;        int resultInteger = randInteger % diffInteger + minInteger;        return resultInteger/10000.0;    }

However, there is a noteworthy problem that the generation of random numbers requires a Random Seed, because the random numbers produced by computers are obtained through recursive methods and must have an initial value, that is, the random seed. If the Random Seed is not initialized, the computer will have a random seed that is indeed saved, so that the results of each recurrence will be exactly the same, therefore, you need to initialize the Random Seed each time the program runs. In VC, the method is to call the srand (INT) function. Its parameter is a random seed, but if you give a constant, the obtained random sequence is exactly the same, so the system time can be used as the Random Seed, because the system time can ensure its randomness.

The call method is srand (gettickcount (), but srand (gettickcount () cannot be used to initialize each call to Rand (), because the computer is running fast now, when rand () is called consecutively, the system time is not updated, so the Random Seed obtained is exactly the same for a period of time, therefore, Random Seed Initialization is generally performed only once before a large number of random numbers are generated. The following code generates 400 in-1 ~ A random number that is evenly distributed between 1.

double dValue[400];    srand(GetTickCount());    for(int i= 0;i < 400; i++)    {        double dValue[i] = AverageRandom(-1,1);    }

The random number generated by this method is shown in result 1:

Figure 1 400-1 ~ Random Number with an average distribution between 1

Ii. Generation of random numbers distributed randomly

The following describes how to generate random numbers with known probability density functions. A typical normal distribution is used as an example to generate random numbers with arbitrary names.

If a random number sequence follows a one-dimensional normal distribution, it has the following probability density functions:

(1-1)

Where μ, σ (> 0) are constants, which are mathematical expectations and mean variance. If you are not clear about the concepts of mathematical expectations and mean variance, please refer to relevant probability theory books. If μ = 0, σ = 0.2, the curve is

Figure 2 probability density function curve of Normal Distribution

We can see that the probability density near μs is large, and the probability density away from μs is small. The random numbers we want to generate must follow this distribution, this means that the probability of the random number to be generated near μs should be large and smaller than μs. The following method can be used to ensure this: points are randomly generated in the large rectangle in Figure 2. These points are evenly distributed. If the generated points fall below the probability density curve, the generated points are considered to meet the requirements, keep them. If they are above the probability density curve, they are considered unqualified and placed. If a large number of points are randomly distributed evenly in the entire rectangle, the abscissa of the points to be preserved follows the normal distribution. It can be imagined that, because the f (x) value at μ is relatively large, the number of points near μ is naturally large, and the number of points close to μ is small, this can be seen from the area. The random number we want to generate is the abscissa here.

Based on the above idea, we can use a program to implement a random number that follows a normal distribution within a certain range. The procedure is as follows:

Double normal (Double X, double Miu, double sigma) // probability density function {return 1.0/SQRT (2 * pI * sigma) * exp (-1 * (X-Miu) * (X-Miu)/(2 * Sigma * sigma);} double normalrandom (double Miu, double Sigma, double min, double max) // generate a random number with a normal distribution {Double X; double dsdom; Double Y; do {x = averagerandom (Min, max); y = normal (dresult, Miu, SIGMA ); DSU = averagerandom (0, normal (Miu, Miu, SIGMA);} while (DSU> Y); Return X ;}

Parameter description: Double Miu: μ, mathematical expectation of a normal function

Double Sigma: σ, mean variance of Normal Functions

Double min, double Max, indicating the range of the generated Random Number

In the above method, take μ = 0, σ = 0.2, And the range is-1 ~ 1 to generate 400 normal random numbers 3 is shown in:

Figure 3 μ = 0, σ = 0.2, range:-1 ~ Random Number Distribution of 400 normal distributions at 1 hour

Take μ = 0, σ = 0.05, range:-1 ~ 1 to generate 400 normal random numbers 4 is shown in:

Figure 4 μ = 0, σ = 0.05, range:-1 ~ Random Number Distribution of 400 normal distributions at 1 hour

From the comparison in figure 3 and figure 4, we can see that the smaller σ, the more random numbers are generated near μ, and the closer the random number is.
The higher the probability of μ.

First, we generate 4000 random numbers with a normal distribution between 0 and 4, take μ = 0, σ = 0.2, and then make statistics on the number of generated data and draw a curve, as shown in figure 5:

Figure 5 μ = 0, σ = 0.2, range: 0 ~ Random Number statistics of 4000 normal distributions

As you can see from Figure 5, there are a large number of records generated at the same distance, and the number of records generated at the same distance is small. The contour line of the chart exactly matches the shape of the probability density curve. This verifies the correctness of the method.

With the above foundation, the same method is used. As long as you know the probability density function, it is not difficult to generate random numbers with any distribution. The method generates a vertex first and then makes a trade-off, the point falling below the probability density curve meets the requirements. The abscissa is the random number to be obtained.

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.