[英]rand() not generating random numbers even after srand(time(NULL))
[英]rand() generating the same number – even with srand(time(NULL)) in my main!
所以,我正在嘗試創建一個隨機向量(想想幾何,而不是一個可擴展的數組),每當我調用我的隨機向量函數時,我得到相同的x值,盡管y和z是不同的。
int main () {
srand ( (unsigned)time(NULL));
Vector<double> a;
a.randvec();
cout << a << endl;
return 0;
}
使用該功能
//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;
}
出於某種原因,randx將始終返回8,而其他數字似乎完全遵循(偽)隨機性。 但是,如果我在randx之前將調用定義為randy,那么randy將始終返回8。
為什么我的第一個隨機數總是8? 我播種不正確嗎?
問題是隨機數生成器的種子值非常接近 - 程序的每次運行只會將time()的返回值改變一小部分 - 可能是1秒,甚至可能沒有! 然后,相當差的標准隨機數發生器使用這些相似的種子值來生成明顯相同的初始隨機數。 基本上,你需要一個比time()更好的初始種子生成器和一個比rand()更好的隨機數生成器。
我認為使用的實際循環算法是從Accelerated C ++中提取的,旨在產生比所需的范圍更好的數字擴展,而不是使用mod運算符。 但它無法彌補總是(有效地)給予相同的種子。
我沒有看到你的srand()
有任何問題,當我嘗試運行非常相似的代碼時,我沒有重復使用第一個rand()
獲得相同的數字。 但是,我確實注意到另一個可能的問題。
do randx = (rand()/bucket_size)+min;
while (randx <= min && randx >= max);
這條線可能不符合你的意圖。 只要min < max
(並且它應該是), randx
就不可能小於或等於min
且大於或等於max
。 另外,您根本不需要循環。 相反,您可以使用以下方法獲取介於最小值和最大值之間的值:
randx = rand() % (max - min) + min;
另外,你甚至可以擺脫那個奇怪的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;
一個簡單的quickfix就是在播種后調用rand
幾次。
int main ()
{
srand ( (unsigned)time(NULL));
rand(); rand(); rand();
Vector<double> a;
a.randvec();
cout << a << endl;
return 0;
}
為了更好地解釋,在測試程序的四個連續運行中第一次調用rand()給出了以下輸出:
27592
27595
27598
27602
注意它們有多相似? 例如,如果將rand()
除以100,則連續3次得到相同的數字。 現在看看四個連續運行中rand()的第二個結果:
11520
22268
248
10997
這看起來好多了,不是嗎? 我真的沒有看到任何理由的downvotes。
我確實遇到了同樣的問題。 我通過移動srand()調用來修復它,所以它只在我的程序中被調用一次(之前我曾在函數調用的頂部播種它)。 不太了解技術性 - 但問題已經解決了。
通過整數除法,您的實現會忽略隨機數的最小4-5位。 由於您的RNG以系統時間播種,因此您獲得的第一個值將每20秒僅更改(平均)。
這應該工作:
randx = (min) + (int) ((max - min) * rand() / (RAND_MAX + 1.0));
哪里
rand() / (RAND_MAX + 1.0)
是[0,1]中的隨機雙精度值,其余的只是將其移動。
與此問題中的代碼沒有直接關系,但我在使用srand ((unsigned)time(NULL))
遇到了同樣的問題,並且仍然從后續調用rand()
返回相同的值序列。
事實證明,srand需要分別調用你正在使用它的每個線程。 我有一個正在生成隨機內容的加載線程(這不是種子問題的隨機因素)。 我剛剛在主線程中使用srand而不是加載線程。 所以添加另一個srand ((unsigned)time(NULL))
來開始加載線程修復了這個問題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.