Max*_*xpm 34 c++ random generator mersenne-twister
以下代码每秒输出一个随机数:
int main ()
{
srand(time(NULL)); // Seeds number generator with execution time.
while (true)
{
int rawRand = rand();
std::cout << rawRand << std::endl;
sleep(1);
}
}
Run Code Online (Sandbox Code Playgroud)
我如何调整这些数字的大小,使它们总是在0-100的范围内?
Bla*_*ace 77
如果您正在使用C++并且关注良好的分发,则可以使用TR1 C++ 11 <random>.
#include <random>
std::random_device rseed;
std::mt19937 rgen(rseed()); // mersenne_twister
std::uniform_int_distribution<int> idist(0,100); // [0,100]
std::cout << idist(rgen) << std::endl;
Run Code Online (Sandbox Code Playgroud)
Kon*_*lph 30
到目前为止发布的所有示例实际上都给出了分布不均的结果 经常执行代码并创建统计信息以查看值是如何变形的.
在任何范围[0,N ]中生成实数均匀随机数分布的更好方法如下(假设实际上遵循均匀分布,这是非常明显的):rand
unsigned result;
do {
result = rand();
} while (result > N);
Run Code Online (Sandbox Code Playgroud)
当然,这种方法很慢但确实产生了良好的分布.一种稍微聪明的方法是找到小于的N的最大倍数RAND_MAX并将其用作上限.在那之后,人们可以安全地接受result % (N + 1).
为了解释为什么天真模量方法是坏的以及为什么上述更好,请参考Julienne关于使用rand的优秀文章.
Jus*_*ner 26
int rawRand = rand() % 101;
Run Code Online (Sandbox Code Playgroud)
请参阅(了解更多详情):
其他人也指出,这不会给你最好的随机数分布.如果您的代码中的这类内容很重要,则必须执行以下操作:
int rawRand = (rand() * 1.0 / RAND_MAX) * 100;
Run Code Online (Sandbox Code Playgroud)
编辑
三年过去了,我正在编辑.正如其他人提到的,rand()有很多问题.显然,当有更好的替代方案时,我不能推荐它的使用.您可以在此处阅读有关详情和建议的所有信息:
你可以做
cout << rawRand % 100 << endl; // Outputs between 0 and 99
cout << rawRand % 101 << endl; // outputs between 0 and 100
Run Code Online (Sandbox Code Playgroud)
为人民投降;注意最初发布后一分钟,我留下了评论:
来自http://www.cplusplus.com/reference/clibrary/cstdlib/rand “请注意,尽管这种模运算不会在跨度中生成真正均匀分布的随机数(因为在大多数情况下,较小的数字更有可能出现),但通常对于短跨度是一个很好的近似值。”
使用64位int并使用100个数字作为输出时,数字0-16用数字的1.00000000000000000455%表示(相同精度的相对精度为1%乘以10 -18),而数字17-99表示用数字的0.99999999999999999913%。是的,分布不是很完美,但是对于小跨度来说是一个很好的近似值。
还要注意,OP在哪里要求分配相同的数字?就我们所知,这些用于微小偏差无关紧要的用途(例如,除密码学以外的任何事物);如果他们使用密码学数字,那么这个问题对于他们来说太天真了,以至于他们无法编写自己的密码学)。
编辑 -对于真正关心随机数均匀分布的人,以下代码有效。请注意,这不一定是最佳的,因为对于64位随机整数,它将需要两次调用,rand()每10 ^ 18次调用一次。
unsigned N = 100; // want numbers 0-99
unsigned long randTruncation = (RAND_MAX / N) * N;
// include every number the N times by ensuring rawRand is between 0 and randTruncation - 1 or regenerate.
unsigned long rawRand = rand();
while (rawRand >= randTruncation) {
rawRand = rand();
// with 64-bit int and range of 0-99 will need to generate two random numbers
// about 1 in every (2^63)/16 ~ 10^18 times (1 million million times)
// with 32-bit int and range of 0-99 will need to generate two random numbers
// once every 46 million times.
}
cout << rawRand % N << stdl::endl;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
18165 次 |
| 最近记录: |