[英]Alternatives to using rand() function in C++
我嘗試了以下簡單代碼,該代碼“隨機地”產生1或-1的百萬次並將其加起來:
#include<iostream>
#include<stdlib.h>
#include<time.h>
int pos_or_neg()
{
if (rand()%2==1) return 1;
else return -1;
}
int main()
{
int i,s=0;
srand (time(NULL));
for (i=0;i<1000000;i++)
s+=pos_or_neg();
std::cout << s;
}
如果rand()實例是獨立的,則結果應該以標准偏差1000進行正態分布,但是我最多只能得到數百個大小的結果。 如果我生成更多的數字(例如1億個),那么這將更加引人注目,並且幅度甚至會減小 !
rand()真的那么糟糕嗎,或者我做錯了什么? 在第一種情況下,有哪些好的替代方案?
rand()
通常是使用線性同余生成器實現的,而眾所周知,線性同余生成器的低位是非隨機的。 因此,要么使用其他生成器,要么選擇其他生成器; 例如rand() & 0x10
。
使用以下代碼,我獲得了大約1000的標准差。
#include <random>
#include <iostream>
constexpr int N = 1000000;
int main()
{
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<> dis(0, 1);
int frequencyOfOnes = 0;
for (int n=0; n<N; ++n)
frequencyOfOnes += dis(gen);
std::cout << "Out of " << N << " events, " << frequencyOfOnes << " had 1 as a result " << std::endl;
}
正如@ zett42所指出的那樣,已經有一個關於此主題的問題。 您可以去那里獲取有關該主題的更多信息。
您絕對應該檢查一下此討論,以了解為什么將rand與模數一起使用可能不是一個好主意。
https://channel9.msdn.com/Events/GoingNative/2013/rand-Considered-Harmful
因此,如果您想要統一分配,我強烈建議您使用http://en.cppreference.com/w/cpp/numeric/random/uniform_int_distribution
要考慮的一件事是,采用rand()
並在其上使用mod
假定RAND_MAX+1
可被您的mod函數平均整除。 如果不是這樣,那么您至少會出現不平衡,因為您選擇“偶數”的次數將不會與選擇“奇數”的次數相同。
如果只是嘗試提供隨機值的“硬幣翻轉”,請改用bernoulli_distribution
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.