Summarization of the seed value setting in large-scale random number generation in C + +--solving random number sequence repetition problem __c++

Source: Internet
Author: User
Tags rand repetition

Today, a small program of genetic algorithm is compiled. In the default constructor of an individual class, the initialization of binary encoding is done using random numbers. The random number in C + + is actually pseudo-random number, that is, the random number function produces a series of pseudo random numbers calculated by the formula, which takes a seed number to calculate a number, which becomes the number of seeds to produce the next number. Based on the principle of generating random numbers, if the same seed is used, the sequence of random numbers produced after two calls to random numbers will be the same. In general, the current time in C + + is used as the seed number, so the random number sequence of two call random functions will be different, and then achieve more random results. The usual method of generating random numbers for C + + is to call the following two functions:

Srand (Time (NULL)); Set the random number seed, the parameter is to use the current time as a seed

Rand (); produce a random number

In the population class, an array of body classes is established. The object of a population class is established, and the individual with the default constructor of the population class is found to have exactly the same binary encoding. The reason is that time (NULL) can only be achieved in seconds, and the time it takes to establish an object array is significantly lower than this order of magnitude.

A more laborious solution could be used. That is to add a function to the individual class that sets the binary string of the individual class. Using a formal parameter of a unsigned type, this parameter acts as a random number seed within the function. In addition, we should add code to the default constructor of the population class, produce a sequence of random numbers, and use these random numbers as the parameters of the new function of the individual class, to modify the contents of binary strings in the individual class, and to realize the randomization of binary strings in the individual object array. But this will add a lot of code, very cumbersome, but also for object-oriented programming principles, increase the workload of the Group class.

By looking up data on the Internet, there are articles saying that using the structure TIMEB and function ftime can get the millisecond time, and set the random number seed code as follows:

struct TIMEB STB;

Ftime (&STB);

Srand ((unsigned) stb.millitm)

After testing, it was found that this so-called millisecond time seed number still does not solve the problem.

Continue to check the data, found a way to get the CPU high-precision timestamp, the code is as follows:

__declspec (naked) unsigned __int64 getcpucycle (void)
{
_asm
{
Rdtsc
Ret
}
}

Among them, the return value of the RDTSC instruction is stored in edx eax, edx is 32 digits high, and the EAX is low 32 bits. The RDTSC instruction (Read time Stamp Counter) obtains the CPU's high-precision timestamp. This allows us to get the number of time periods since the current CPU has been on power:

unsigned __int64 icpucycle = Getcpucycle ();

So we can use Icpucycle's low 32 bit as a random number of seeds, the code is as follows:

unsigned srnd= (unsigned) icpucycle;

Srand (SRND);

After testing, the above method is feasible. However, the disadvantage of this approach is that it relies on the processor, and some computers may not have the processor support for the directive.

Continue to check the data, and found a feasible method, the method has a microsecond level of precision, that is, the use of QueryPerformanceCounter function, it can return High-precision counter value, its precision can reach microsecond level. Normally this function is used in conjunction with the function queryperformancefrequency, function queryperformancefrequency is the function of the current machine if the timer is present to query the current machine timer frequency, We can use QueryPerformanceFrequency to test whether there is a high-precision timer in the current system, and if so, you can call QueryPerformanceCounter to obtain a high precision count. The code is as follows:

#include <windows.h>

Large_integer nfrequency;

if (:: QueryPerformanceFrequency (&nfrequency))

{

Large_integer Nstartcounter;

:: QueryPerformanceCounter (&nstartcounter);

:: Srand ((unsigned) nstartcounter.lowpart);

}

#include <Windows.h>
using namespace std;

int _tmain (int argc, _tchar* argv[])
{
	int count[100] = {0};
	Large_integer nfrequency;
	for (int i=0;i<10000000;++i)
	{
		if (:: QueryPerformanceFrequency (&nfrequency))
		{
			Large_ INTEGER nstartcounter
			:: QueryPerformanceCounter (&nstartcounter);:
			: Srand ((unsigned) Nstartcounter.lowpart);
			Count[rand ()%100] + +
		;
	}

	for (int i=0;i<100;++i)
	{
		
		
		cout<<i<< ":" <<count[i]<<endl;
	}
	return 0;
}


After testing, using this method can also implement the real random initialization of the object array in my question.

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.