根据这些概率,这会给我合适的随机数吗?C++
Will this give me proper random numbers based on these probabilities? C++
代码:
int random = (rand() % 7 + 1)
if (random == 1) { } // num 1
else if (random == 2) { } // num 2
else if (random == 3 || random == 4) { } // num 3
else if (random == 5 || random == 6) { } // num 4
else if (random == 7) { } // num 5
基本上,我想要这些数字中的每一个,以及每一个概率:1:1/72:1/73:2/74:2/75:1/7
这个代码会给我正确的结果吗?也就是说,如果这是无限次运行,我会得到合适的频率吗?有没有一种不那么冗长的方法?
不是,由于rand((的工作方式,它实际上有点偏离。特别是,rand返回范围为[0,rand_MAX]的值。假设RAND_MAX为10。然后rand((会给出0…10,它们会被映射(通过模数(到:
0 → 0
1 → 1
2 → 2
3 → 3
4 → 4
5 → 5
6 → 6
7 → 0
8 → 1
9 → 2
10 → 3
注意0–3比4–6更常见;这是随机数生成中的偏差。(你也加了1,但这只是转移了它(。
RAND_MAX当然不是10,但也可能不是7的倍数(减1(。很可能是二次方。所以你会有一些偏见。
我建议使用Boost随机数库,它可以为您提供一个随机数生成器,无偏差地生成1–7。还可以使用C++11查看bames53的答案,如果您的代码只需要针对C++11平台,那么这是正确的方法。
另一种方式:
float probs[5] = {1/7.0f, 1/7.0f, 2/7.0f, 2/7.0f, 1/7.0f};
float sum = 0;
for (int i = 0; i < 5; i++)
sum += probs[i]; /* edit */
int rand_M() {
float f = (rand()*sum)/RAND_MAX; /* edit */
for (int i = 0; i < 5; i++) {
if (f <= probs[i]) return i;
f -= probs[i];
}
return 4;
}
假设rand()
是好的,那么您的代码只会对较低的X数字产生很小的偏差,其中X是RAND_MAX%7。由于rand()
的实现质量的原因,您很可能无法获得所需的几率。如果你发现是这样的话,那么你会想要使用一个替代的随机数生成器。
C++11引入了报头CCD_ 3,其包括若干质量RNG。这里有一个例子:
#include <random>
#include <functional>
auto rand = std::bind(std::uniform_int_distribution<int>(1,7),std::mt19937());
考虑到这一点,当你调用rand()
时,你会得到一个从1到7的数字,每个数字的概率都相等。(如果质量和速度特性不同,您可以选择不同的发动机。(然后,您可以使用它来实现您的示例当前与std::rand()
一起使用的if-else条件。然而,<random>
允许您使用它们的一个非均匀分布做得更好。在这种情况下,您想要的是discrete_distribution
。此分布允许您明确说明从0到n的每个值的权重。
// the random number generator
auto _rand = std::bind(std::discrete_distribution<int>{1./7.,1./7.,2./7.,2./7.,1./7.},std::mt19937());
// convert results of RNG from the range [0-4] to [1-5]
auto rand = [&_rand]() { return _rand() +1; };
int toohigh = RAND_MAX - RAND_MAX%7;
int random;
do {
random = rand();
while (random >= toohigh); //should happen ~0.03% of the time
static const int results[7] = {1, 2, 3, 3, 4, 4, 5};
random = results[random%7];
这应该给出具有rand
所能处理的分布的数字,并且没有大的if
开关。
注意,这确实有一个理论上可能的无限循环,但它在循环中保持偶数的统计几率很小。它两次循环的几率非常接近赢得加州超级乐透头奖的几率。即使这个星球上的每个人都得到了五个随机数,它也可能不会循环三次。(假设一个完美的RNG。(
rand返回伪-随机整数:
请注意,这个模运算并没有生成真正的跨度中均匀分布的随机数(因为在大多数情况下较低的数字更有可能(,但这通常是一个好的短跨度的近似值。
现在,关于不那么长的方法,您可以使用switch-case构造,或一系列条件运算符?:
(这将使您的代码变短且不可读:(。
- 为什么随机数生成器不在void函数中随机化数字,而在main函数中随机化
- 整数不会重复超过随机数
- if数组上的随机数
- 在将数字随机生成为数组期间从内存输出随机数的数组
- 半随机数生成C++
- 程序在尝试猜测它选择的随机数时进入无限循环?
- 有没有办法在 c++ 中同时生成随机数?如果没有,是否有解决方法?
- 具有随机数的二维数组不会更改
- 随机数未达到限制
- 我想生成许多矩阵并用随机数填充它
- <random>在实践中应该实际使用哪个随机数引擎? std::mt19937?
- 制作具有平均值的随机数生成器
- 为什么 rand 不在我的代码中生成随机数?
- C++ 随机数生成器:尝试将结果作为向量获取,但通过制作 void 函数来执行此操作而出现错误
- 从给定种子生成相同的随机数序列C++
- 随机数生成函数说明
- C++ 尝试生成随机数时弹出警告帮助?
- 尝试在 c++ 中创建随机数生成器并收到错误
- 从给定的随机数组值生成随机数 Arduino程序C++
- 如何在个人计算机和群集 (c++) 上生成相同的随机数