计算 C++ 中发生某事的可能性是否为 1/4 的最佳方法?
我想知道是否有一种聪明的方法来找出
有 1/4 的机会发生某事。
我知道我们可以用 rand() % 4 来做到这一点并检查它是否等于 0,但是有没有办法不使用 rand() 呢? 在c++中,谢谢。
I was wondering if there is a smart way to find out
There is a 1/4 chance something happens.
I know we can do this with rand() % 4 and checking if it is equal to 0, but is there a way without using rand()? In c++, thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(11)
如果你的意思是你想避免许多
rand()
实现固有的糟糕性,你可能应该研究 Boost Random 库,它有几个高质量的 pRNG(伪随机数生成器),以及许多控制输出的方法。 该库也以稍微修改的形式存在于std::tr1
中。If you mean you want to avoid the inherent crappiness of many
rand()
implementations, you should probably look into the Boost Random library, which has several high-quality pRNGs (pseudo-random number generators), and many ways to control the output. This library is also present in slightly modified form instd::tr1
.从不 从使用 % 将 PRNG 值截断到某个范围内。 大多数 PRNG 具有相对非随机的低阶位。
对于您的情况,请使用 BCS 建议的除法 (RAND_MAX / n)。
Never ever use % for truncating a PRNG value into a range. Most PRNGs have relatively non-random lower order bits.
For your case, use a division (RAND_MAX / n) like BCS suggests.
如果您不喜欢 C 的标准 rand(),请选择比 C 更好的 rand()。
pick a better rand() than C's if you don't like C's standard rand().
您可以写自己的兰特。 (不要这样做)。
你可以抓住tickcount。 (不要经常这样做)。
您只需数一下,每四个调用都会返回 true。
您可能应该只调用 rand()。
You could write your own rand. ( dont do it ).
You could grab the tickcount. ( dont do it too often ).
You could just count, and every fourth call return true.
You should probably just call rand().
我对C++不太了解,所以我可能是错的。 但似乎
rand()
返回一个介于0
和RAND_MAX-1
之间的值。 所以也许你可以这样做:PS:也许这需要一些选角。
I don't know much C++, so I might be wrong. But it seems
rand()
return a value between0
andRAND_MAX-1
. So maybe you could do something like this:PS: Maybe this requires some casting.
为什么不使用 rand() 呢? 如果您担心“真”随机性与伪随机性,您可以尝试 使用随机位的物理源。 更复杂,而且通常是不必要的。
Why not use rand()? If you are concerned about "true" randomness vs. pseudo randomness, you can try using physical sources of random bits. Much more complicated, and usually unnecessary.
您可以使用另一种类型的 RNG,例如具有更好整体熵的 梅森扭曲器。 我还听说过关于乘法与进位 RNG 的好消息。
You could use another type of RNG such as the Mersenne twister which has better overall entropy. I also hear good thing about Multuply with Carry RNGs.
4是特殊情况。 您可以假设您的 PRNG 有 50% 的机会输出偶数,我认为 libc (rand) 的 LCG 就是这种情况。 因此两次输出偶数的概率是 25%。
因此...
现在对于迂腐的人来说...
您想要做的是生成均匀的随机数,但限制在一定范围内,在本例中熵为 4。如果您的 PRNG 的熵为32 位,您无法确定计算输出 mod 4 是否会按预期工作。 这需要更多的工作。
幸运的是,这项工作已经在 boost 库中实现了。
例如,每次你得到 1(或 2、3、4,如你所愿)时,你都会说“ok”。
但您可能不想使用 boost 库。 然后,只需查看uniform_int的代码并重现行为。 人才模仿,天才窃取。 ;)
4 is a special case. You can assume that your PRNG has got 50% chances of outputting an even number, which is the case - I think - for the LCG of the libc (rand). The probability of outputting an even number twice is therefore 25%.
Therefore...
And now for the pedantic...
What you want to do is to have an uniform random generated, but restricted to a certain range, in this case an entropy of 4. If your PRNG has, say, an entropy of 32-bit, you cannot be certain that computing the output mod 4 will work as expected. This require a bit more work.
Fortunately, this work has already been implemented in the boost library.
And you would for example say "ok" everytime you get 1 (or 2, 3, 4, as you fancy).
But you may not want to use the boost library. Then, simply look at the code of uniform_int and reproduce the behaviour. Talents imitate, geniuses steal. ;)
嗯...编写您自己的
rand()
? 您将需要某种类型的随机函数!Umm... write your own
rand()
? You will need some kind of random function!尝试:
然后你会发现它为你提供了 25% 的完美概率发生某事(假设你执行 if 语句四次的倍数。
Try:
Then you'll find it gives you a perfect 25% probability of something happening (assuming you execute the if-statement a multiple of four times.
</humor>