简体   繁体   English

rand()生成相同的数字 - 即使我的主要是srand(time(NULL))!

[英]rand() generating the same number – even with srand(time(NULL)) in my main!

So, I'm trying to create a random vector (think geometry, not an expandable array), and every time I call my random vector function I get the same x value, though y and z are different. 所以,我正在尝试创建一个随机向量(想想几何,而不是一个可扩展的数组),每当我调用我的随机向量函数时,我得到相同的x值,尽管y和z是不同的。

int main () {
    srand ( (unsigned)time(NULL));
    Vector<double> a;
    a.randvec();
    cout << a << endl;
    return 0;
}

using the function 使用该功能

//random Vector
template <class T>
void Vector<T>::randvec()
{
    const int min=-10, max=10;
    int randx, randy, randz;

    const int bucket_size = RAND_MAX/(max-min);

    do randx = (rand()/bucket_size)+min;
    while (randx <= min && randx >= max);
    x = randx;

    do randy = (rand()/bucket_size)+min;
    while (randy <= min && randy >= max);
    y = randy;

    do randz = (rand()/bucket_size)+min;
    while (randz <= min && randz >= max);
    z = randz;
}

For some reason, randx will consistently return 8, whereas the other numbers seem to be following the (pseudo) randomness perfectly. 出于某种原因,randx将始终返回8,而其他数字似乎完全遵循(伪)随机性。 However, if I put the call to define, say, randy before randx, randy will always return 8. 但是,如果我在randx之前将调用定义为randy,那么randy将始终返回8。

Why is my first random number always 8? 为什么我的第一个随机数总是8? Am I seeding incorrectly? 我播种不正确吗?

The issue is that the random number generator is being seeded with a values that are very close together - each run of the program only changes the return value of time() by a small amount - maybe 1 second, maybe even none! 问题是随机数生成器的种子值非常接近 - 程序的每次运行只会将time()的返回值改变一小部分 - 可能是1秒,甚至可能没有! The rather poor standard random number generator then uses these similar seed values to generate apparently identical initial random numbers. 然后,相当差的标准随机数发生器使用这些相似的种子值来生成明显相同的初始随机数。 Basically, you need a better initial seed generator than time() and a better random number generator than rand(). 基本上,你需要一个比time()更好的初始种子生成器和一个比rand()更好的随机数生成器。

The actual looping algorithm used is I think lifted from Accelerated C++ and is intended to produce a better spread of numbers over the required range than say using the mod operator would. 我认为使用的实际循环算法是从Accelerated C ++中提取的,旨在产生比所需的范围更好的数字扩展,而不是使用mod运算符。 But it can't compensate for always being (effectively) given the same seed. 但它无法弥补总是(有效地)给予相同的种子。

I don't see any problem with your srand() , and when I tried running extremely similar code, I did not repeatedly get the same number with the first rand() . 我没有看到你的srand()有任何问题,当我尝试运行非常相似的代码时,我没有重复使用第一个rand()获得相同的数字。 However, I did notice another possible issue. 但是,我确实注意到另一个可能的问题。

do randx = (rand()/bucket_size)+min;
while (randx <= min && randx >= max);

This line probably does not do what you intended. 这条线可能不符合你的意图。 As long as min < max (and it always should be), it's impossible for randx to be both less than or equal to min and greater than or equal to max . 只要min < max (并且它应该是), randx就不可能小于或等于min且大于或等于max Plus, you don't need to loop at all. 另外,您根本不需要循环。 Instead, you can get a value in between min and max using: 相反,您可以使用以下方法获取介于最小值和最大值之间的值:

randx = rand() % (max - min) + min;

Also to mention, you can even get rid of that strange bucket_size variable and use the following method to generate numbers from a to b inclusively: 另外,你甚至可以摆脱那个奇怪的bucket_size变量,并使用以下方法ab生成数字:

srand ((unsigned)time(NULL));

const int a = -1;
const int b = 1;

int x = rand() % ((b - a) + 1) + a;
int y = rand() % ((b - a) + 1) + a;
int z = rand() % ((b - a) + 1) + a;

A simple quickfix is to call rand a few times after seeding. 一个简单的quickfix就是在播种后调用rand几次。

int main ()
{
    srand ( (unsigned)time(NULL));
    rand(); rand(); rand();

    Vector<double> a;
    a.randvec();
    cout << a << endl;
    return 0;
}

Just to explain better, the first call to rand() in four sequential runs of a test program gave the following output: 为了更好地解释,在测试程序的四个连续运行中第一次调用rand()给出了以下输出:

27592
27595
27598
27602

Notice how similar they are? 注意它们有多相似? For example, if you divide rand() by 100, you will get the same number 3 times in a row. 例如,如果将rand()除以100,则连续3次得到相同的数字。 Now take a look at the second result of rand() in four sequential runs: 现在看看四个连续运行中rand()的第二个结果:

11520
22268
248
10997

This looks much better, doesn't it? 这看起来好多了,不是吗? I really don't see any reason for the downvotes. 我真的没有看到任何理由的downvotes。

I had the same problem exactly. 我确实遇到了同样的问题。 I fixed it by moving the srand() call so it was only called once in my program (previously I had been seeding it at the top of a function call). 我通过移动srand()调用来修复它,所以它只在我的程序中被调用一次(之前我曾在函数调用的顶部播种它)。 Don't really understand the technicalities - but it was problem solved. 不太了解技术性 - 但问题已经解决了。

Your implementation, through integer division, ignores the smallest 4-5 bit of the random number. 通过整数除法,您的实现会忽略随机数的最小4-5位。 Since your RNG is seeded with the system time, the first value you get out of it will change only (on average) every 20 seconds. 由于您的RNG以系统时间播种,因此您获得的第一个值将每20秒仅更改(平均)。

This should work: 这应该工作:

randx = (min) + (int) ((max - min) * rand() / (RAND_MAX + 1.0));

where 哪里

rand() / (RAND_MAX + 1.0)

is a random double value in [0, 1) and the rest is just shifting it around. 是[0,1]中的随机双精度值,其余的只是将其移动。

Not directly related to the code in this question, but I had same issue with using srand ((unsigned)time(NULL)) and still having same sequence of values being returned from following calls to rand() . 与此问题中的代码没有直接关系,但我在使用srand ((unsigned)time(NULL))遇到了同样的问题,并且仍然从后续调用rand()返回相同的值序列。

It turned out that srand needs to called on each thread you are using it on separately. 事实证明,srand需要分别调用你正在使用它的每个线程。 I had a loading thread that was generating random content (that wasn't random cuz of the seed issue). 我有一个正在生成随机内容的加载线程(这不是种子问题的随机因素)。 I had just using srand in the main thread and not the loading thread. 我刚刚在主线程中使用srand而不是加载线程。 So added another srand ((unsigned)time(NULL)) to start of loading thread fixed this issue. 所以添加另一个srand ((unsigned)time(NULL))来开始加载线程修复了这个问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 rand() 即使在 srand(time(NULL)) 之后也不生成随机数 - rand() not generating random numbers even after srand(time(NULL)) 通过函子调用时,rand()会生成相同的随机数集(即使在使用srand(time(NULL))进行播种之后) - rand() generating same set of random numbers when called through functors (even after seeding with srand(time(NULL)) 即使我叫srand(time(NULL)),Rand()还是生成器相同的数字 - Rand() is generator the same number even though I called srand(time(NULL)) Srand() 和 rand() 仍然生成相同的随机数 - Srand() and rand() still generating the same random number rand()即使与srand(time(NULL))也不起作用 - rand() doesn't work even with srand( time(NULL) ) rand()即使在srand()之后也产生相同的结果 - rand() producing the same results even after srand() 为什么rand()在这个for循环中使用srand(time(null))返回相同的值? - Why does rand() return the same value using srand(time(null)) in this for loop? 为什么在使用rand生成随机数之前需要调用srand - why is srand required to be called before generating a random number using rand rand()不给我一个随机数(即使使用srand()时) - rand() not giving me a random number (even when srand() is used) rand() 在每次函数调用时产生相同的结果(使用 srand(time(0)) - rand() produces the same result on each function call (with srand(time(0))
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM