Why does rand() yield the same sequence of numbers

2019-01-02 23:55发布

Every time I run a program with rand() it gives me the same results.

Example :

#include <iostream>
#include <cstdlib>

using namespace std;

int random (int low, int high) {
    if (low > high) return high;
    return low + (rand() % (high - low + 1));
}
int main (int argc, char* argv []) {
    for (int i = 0; i < 5; i++) cout << random (2, 5) << endl;
}

Output :

3
5
4
2
3

Each time I run the program it outputs the same numbers every time. Is there a way around this?

标签: c++ random
6条回答
不美不萌又怎样
2楼-- · 2019-01-03 00:12

You are actually getting psuedo random numbers. To make them "more random" you can seed the random number generator using something that "changes" (most commonly the current time).

查看更多
迷人小祖宗
3楼-- · 2019-01-03 00:24

The seed for the random number generator is not set.

If you call srand(time(NULL)) then you will get more random results:

#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;

int main() {
    srand(time(NULL));
    cout << rand() << endl;
    return 0;
}

The reason is that a random number generated from the rand() function isn't actually random. It simply is a transformation. Wikipedia gives a better explanation of the meaning of pseudorandom number generator: deterministic random bit generator. Every time you call rand() it takes the seed and/or the last random number(s) generated (the C standard doesn't specify the algorithm used, though C++11 has facilities for specifying some popular algorithms), runs a mathematical operation on those numbers, and returns the result. So if the seed state is the same each time (as it is if you don't call srand with a truly random number), then you will always get the same 'random' numbers out.

If you want to know more, you can read the following:

http://www.dreamincode.net/forums/topic/24225-random-number-generation-102/

http://www.dreamincode.net/forums/topic/29294-making-pseudo-random-number-generators-more-random/

查看更多
Bombasti
4楼-- · 2019-01-03 00:29

That's a feature of the rand() function.

What you have is not a random number generator, but more strictly a "Pseudo Random Number Generator". Being able to reproduce the same random sequences for the same seed (you seed using the srand(x) function) can be important to reproduce bugs or to preserve state across program runs.

Personally, I use this feature to be able to pause/persist rendering-processes in a monte carlo based terrain renderer. A nice side effect is that you are able to guarantee different monte carlo experiments on different machines, and therefore be able to generate guaranteed different results that can then be reduced in a final step to a higher quality end result (of course you can later reuse this higher quality end result to produce even higher quality results).

Note, however, that neither C nor C++ define the number sequence from rand(). So if you need guaranteed sequences across platforms, use one of C++11's new random number generators (e.g. a mersenne twister), roll your own (some generators are almost trivial to grasp, however, because most of them rely on specific overflow behaviour their implementation might not be trivial), or use a third party component (e.g. boost::random).

查看更多
ら.Afraid
5楼-- · 2019-01-03 00:31

You need to seed the random number generator (see the function 'srand'). Assuming you aren't doing cryptography, then seeding it with the output of 'time' is probably good enough.

查看更多
淡お忘
6楼-- · 2019-01-03 00:32

use randomize(). It automatically seeds the value. Or if you want to use rand() then you can seed it by using srand(seedvalue); the seed value can be anything like system time..that'll give you different random numbers everytime

查看更多
等我变得足够好
7楼-- · 2019-01-03 00:35

If you call rand() without first calling srand(), it will act as if you have called srand(1) implicitly. The relevant bit of the standard C99 7.20.2.2 The srand function (on which cstdlib is based) states:

If rand is called before any calls to srand have been made, the same sequence shall be generated as when srand is first called with a seed value of 1.

In other words, you will get the same sequence each time. You can change your main into:

int main (int argc, char* argv []) {
    srand (time (0));  // needs ctime header.
    for (int i = 0; i < 5; i++)
        cout << random (2, 5) << endl;
    wait ();
}

to fix this, assuming you don't run it more than once a second.

As mentioned, you'll need the ctime header for this. You should also be pulling in cstdlib since that's where rand and srand live. It's also usually a good idea to use the cXXX headers rather than the XXX.h ones (cmath rather than math.h, for example).

So, having made all those changes (and using explicit namespaces, which I prefer though others may not), I'd end up with:

#include <iostream>
#include <cstdlib>
#include <ctime>
#include <cmath>

void wait () {
    int e;
    std::cin >> e;
}

int random (int low, int high) {
    if (low > high) return high;
    return low + (std::rand() % (high - low + 1));
}

int main (int argc, char* argv []) {
    std::srand (std::time (0));
    for (int i = 0; i < 5; i++)
        std::cout << random (2, 5) << '\n';
    wait ();
}

which gives a different sequence each time I run it, for a few times anyway. Obviously, there's a hard limit on when the data will repeat (there are only 45 possibilities) and the "random" nature of the output means it may repeat before then as well :-)

查看更多
登录 后发表回答