随机数生成器,C++

not*_*tar 4 c++ random

我知道在C++中生成随机数有一些限制(可能是非均匀的).如何生成1到14620之间的数字?

谢谢.

How*_*ant 19

如果你有一个c ++ 0x环境,那么boost lib的近似衍生物现在是标准的:

#include <random>
#include <iostream>

int main()
{
    std::uniform_int_distribution<> d(1, 14620);
    std::mt19937 gen;
    std::cout << d(gen) << '\n';
}
Run Code Online (Sandbox Code Playgroud)

这将是快速,简单和高品质.

你没有指定,但是如果你想要浮点而不是只有:

std::uniform_real_distribution<> d(1, 14620);
Run Code Online (Sandbox Code Playgroud)

如果您需要非均匀分布,您可以非常轻松地构建自己的分段常量或分段线性分布.


wil*_*ell 18

一种常见的方法是使用std::rand()模数:

#include<cstdlib>
#include<ctime>

// ...
std::srand(std::time(0));  // needed once per program run
int r = std::rand() % 14620 + 1;
Run Code Online (Sandbox Code Playgroud)

但是,正如@tenfour在他的回答中提到的那样,模运算符可以破坏值std::rand()返回的一致性.这是因为模数将它丢弃的值转换为有效值,并且此转换可能不一致.例如,对于nin [0,10],该值n % 9将9转换为0,因此您可以通过将零或9转换为零来获得零.其他值只有一次产生的机会.

另一种方法是将随机数转换为std::rand()[0,1]范围内的浮点值,然后将值转换并移动到您想要的范围内.

int r = static_cast<double>(std::rand()) / RAND_MAX * 14620 + 1;
Run Code Online (Sandbox Code Playgroud)


ten*_*our 11

srand() / rand() 正如其他人所回答的那样,你需要的功能.

问题%是结果明显不均匀.为了说明,假设rand()返回0-3的范围.以下是将其称为4000次的假设结果:

0 - 1000 times
1 - 1000 times
2 - 1000 times
3 - 1000 times
Run Code Online (Sandbox Code Playgroud)

现在,如果您进行相同的采样(rand() % 3),您会注意到结果如下:

0 - 2000 times
1 - 1000 times
2 - 1000 times
Run Code Online (Sandbox Code Playgroud)

哎哟! 更加统一的解决方案是:

int n = (int)(((((double)std::rand()) / RAND_MAX) * 14620) + 1);

对于草率的代码很抱歉,但我们的想法是使用浮点数学将其正确缩放到您想要的范围,并转换为整数.