A specific example
I need to generate a random number between 0 and 2, inclusive. (or choose randomly between -1, 0, and 1).
我需要生成0到2之间的随机数,包括0和2。 (或在-1,0和1之间随机选择)。
The naive approach would be to do something like rand() mod 3
where rand()
returns an integer. This approach will not generate statistically random numbers unless the upper bound of rand()
is not relatively prime (and the lower bound is 0).
天真的方法是做rand()mod 3之类的东西,其中rand()返回一个整数。除非rand()的上限不是相对素数(并且下限为0),否则此方法不会生成统计随机数。
For instance, assuming rand() returned 2 bits (from 0 to 3, inclusive), the modulus would map:
例如,假设rand()返回2位(从0到3,包括0和3),模数将映射:
0 -> 0
1 -> 1
2 -> 2
3 -> 0
0 - > 0 1 - > 1 2 - > 2 3 - > 0
This skew toward 0 would obviously be much less if more bits would be returned, but regardless, the skew would remain.
如果返回更多位,则向0倾斜显然会小得多,但无论如何,倾斜都将保持不变。
The generic question
Is there a way of generating an evenly distributed random number between 0 and n-1, inclusive, where n is relatively prime to 2?
有没有办法在0和n-1之间产生均匀分布的随机数,其中n是2的相对素数?
4 个解决方案
#1
A common approach is to discard random values above the last full cycle, and just ask for a new random number.
一种常见的方法是丢弃上一个完整周期之上的随机值,只需要一个新的随机数。
#2
It might help choosing your rand() upper bound to be k*n where k is an integer. This way the outcome will be evenly distributed provided that rand() is a good random generator.
它可能有助于选择你的rand()上限为k * n,其中k是一个整数。这样,只要rand()是一个好的随机生成器,结果就会均匀分布。
If it's not possible to reduce the upper bound, you can pick k so that k*n is as close to rand() upper bound as possible and discard the results above this number trying again.
如果无法减小上限,则可以选择k,使k * n尽可能接近rand()上限,并再次尝试丢弃此数字以上的结果。
#3
See my answer to a similar question.
请参阅我对类似问题的回答。
Basically, use your RNG and discard everything above N and try again. For optimization, you can use mod, and discard everything above n * floor(MAX / n)
基本上,使用你的RNG并丢弃N以上的所有东西,然后再试一次。为了优化,您可以使用mod,并丢弃n * floor(MAX / n)以上的所有内容
#4
Generic Answer: You need to use more than just 2 bits of the number.
通用答案:您需要使用多于2位的数字。
My rule of thumb is to generate floating-point values, x, 0.0 <= x < 1.0, multiply by 3 and truncate. That should get you values in the range 0, 1 and 2 that depend on a larger number of bits.
我的经验法则是生成浮点值,x,0.0 <= x <1.0,乘以3并截断。这应该得到0,1和2范围内的值,这取决于更大的位数。
#1
A common approach is to discard random values above the last full cycle, and just ask for a new random number.
一种常见的方法是丢弃上一个完整周期之上的随机值,只需要一个新的随机数。
#2
It might help choosing your rand() upper bound to be k*n where k is an integer. This way the outcome will be evenly distributed provided that rand() is a good random generator.
它可能有助于选择你的rand()上限为k * n,其中k是一个整数。这样,只要rand()是一个好的随机生成器,结果就会均匀分布。
If it's not possible to reduce the upper bound, you can pick k so that k*n is as close to rand() upper bound as possible and discard the results above this number trying again.
如果无法减小上限,则可以选择k,使k * n尽可能接近rand()上限,并再次尝试丢弃此数字以上的结果。
#3
See my answer to a similar question.
请参阅我对类似问题的回答。
Basically, use your RNG and discard everything above N and try again. For optimization, you can use mod, and discard everything above n * floor(MAX / n)
基本上,使用你的RNG并丢弃N以上的所有东西,然后再试一次。为了优化,您可以使用mod,并丢弃n * floor(MAX / n)以上的所有内容
#4
Generic Answer: You need to use more than just 2 bits of the number.
通用答案:您需要使用多于2位的数字。
My rule of thumb is to generate floating-point values, x, 0.0 <= x < 1.0, multiply by 3 and truncate. That should get you values in the range 0, 1 and 2 that depend on a larger number of bits.
我的经验法则是生成浮点值,x,0.0 <= x <1.0,乘以3并截断。这应该得到0,1和2范围内的值,这取决于更大的位数。