PDA

View Full Version : Two problems with the function qrand()



Trader
5th November 2010, 12:39
I am having two problems with the function qrand().

1) in "randInt1", every time I run the program, it always returns the same numbers: 41, 85, 72, 38, 80, 69, 65, 68, 96, 22.

2) in "randInt2", he often repeats the numbers.

How can I create random numbers that are not repeated, and are not the same whenever I run the program?



#include <QtCore/QCoreApplication>
#include <QTime>
#include <QDebug>

int randInt1(int low, int high) { // returns a random integer value between low and high
return qrand() % ((high + 1) - low) + low;
}

int randInt2(int low, int high) { // returns a random integer value between low and high
QTime time = QTime::currentTime(); qsrand((uint)time.msec()); // synchronizes with the current time
return qrand() % ((high + 1) - low) + low;
}

int main(int argc, char *argv[]) {
QCoreApplication a(argc, argv);

for (int i = 0; i < 10; i++) qDebug() << "Rand1: " << randInt1(0, 100);

qDebug() << "\n\n";

for (int i = 0; i < 10; i++) qDebug() << "Rand2: " << randInt2(0, 100);

return a.exec();
}

high_flyer
5th November 2010, 12:49
you need a new seed for each new random set.
use void qsrand ( uint seed ).
If you have read qrand() doc, you would have known it.

Also, the 'Qt' tag is for referncing a class in the Qt documentation.
For posting code please use the code tags - '#' (the larger one, there are two)

tbscope
5th November 2010, 12:57
in "randInt2", he often repeats the numbers.

Define repeat.
Is this: 10 10 10 10 11 15 21 21 21 21 21
Or this: 10 11 12 13 10 11 12 13 10 11 12 13
Or something else?

Trader
5th November 2010, 13:49
tbscope:

this: 10 10 10 10 11 15 21 21 21 21 21

Added after 28 minutes:

high_flyer: "you need a new seed for each new random set. use void qsrand ( uint seed ). If you have read qrand() doc, you would have known it."

I'm using qsrand. See the function: randInt2

I found this in other forums that spoke the same problem.



"What you see is the effect of pseudo-randomness. You seed it with the time once, and it generates a sequence of numbers. Since you are pulling a series of random numbers very quickly after each other, you are re-seeding the randomizer with the same number until the next millisecond. And while a millisecond seems like a short time, consider the amount of calculations you're doing in that time."



"If you make the call fast enough the value of QTime::currentTime().msec() will not change, and you're basically re-seeding qsrand with the same seed, causing the next random number generated to be the same as the prior one."



I think I need something faster than milliseconds, maybe the CPU clock cycles.

Is there any solution to this problem?

Lesiok
5th November 2010, 17:18
Just use qsrand() only one time in main().
This is meaningless to using qsrand() every time when You are using qrand().

SixDegrees
5th November 2010, 17:37
Lesiok is correct; calling qsrand() more than once is not something you need to do.

As for repeating numbers: that's going to depend partly on what range you give your functions. If you're generating numbers within a narrow range, repeats are going to occur very frequently.

Although there are many, many different tests for randomness, the simplest one would be to check the frequency of each number; ideally, they should all occur the same number of times over a large run. You can also concoct series metrics by determining the probability that two, three or more numbers would occur after one another, and compare that to the output of your function.

My guess is that qrand is doing what it's supposed to do. Nearly all of the problems I've run across involving RNGs can be traced to misunderstandings on the part of those using the routines.

Note, too, that ALL numerical RNGs repeat the same sequence of numbers over and over and over again; algorithms are chosen that produce series with extremely long periods, but it is the nature of deterministic calculation that no such procedure can ever generate truly random numbers. It can only produce a stream of numbers that displays attributes very close to what would be expected from a truly random process.

Trader
5th November 2010, 20:39
Lesiok && SixDegrees

It worked perfectly.

Thank you!!!

wysota
5th November 2010, 22:01
If one is using a unix system, a good source for random numbers is /dev/random. It has a limited output rate but it's a good way to get a unique random sequence by initializing the seed of the random number generator with data from /dev/random. This allows to get unique sequences on different machines (which is not the case with seed related to the current time as in the example above).