[英]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
变量,并使用以下方法从a
到b
生成数字:
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.