给定一个随机给出0或1的函数random01Generator(),实现一个利用该函数并生成0到6(包括0和6)之间的数字的函数。所有数字的发生概率都应该相同。
例如:
on multiple runs, it gives 3 2 3 6 0
方法: 这里的想法是找到大于给定范围的最小数的范围。这里,因为范围是6,所以决定2^3是大于6的最小数。因此,这里的k是3。
因此,尝试每次形成一个包含3个字符的二进制数,一旦获得所有3个字符,查找该二进制数对应的十进制表示形式并返回该值。
例如,如果它在第一次random01调用中给出0,然后在下一次调用中给出1,最后在下一次调用中再次给出1,那么可以说这样形成的二进制数是011,这是数字3的十进制表示,因此返回3。如果在这种情况下,它给出111,这是7,这超出了范围。所以,只需丢弃这个数字,然后再次重复整个过程,直到给出所需范围内的数字。
调用random01Generator()6次后,数字出现的概率将不同。例如,首次出现0的概率为1/2。第二次,概率是1/2,总概率是1/4。如果通过调用随机函数6次重复此过程6次,则0的出现概率将为1/(2^6)。类似地,1的出现概率将大于0,2的出现概率将大于1,依此类推,遵循二项分布模式。
这样做将确保所有概率都相等,因为它只考虑一个人可以生成这些数字的范围,并拒绝任何结果大于最大指定范围的情况。因此,采用了上述方法。
显然,如果有其他随机生成器,比如random0mGenerator(),并且需要生成0到n之间的数字,其中n>m,那么这个想法可以扩展。在这种情况下,修改下面的函数以合并m和n。
先决条件: Java中的BigInteger。
JAVA
// Java code to generate random numbers import java.math.BigInteger; import java.util.Random; public class RandomImp{ public int random01Generator() { Random rand = new Random(); return rand.nextInt( 2 ); } // function will use the above // method and return numbers // between 0 and 6 inclusive. public void random06Generator(){ Random rand = new Random(); int val = 7 ; while (val >= 7 ) { String res = "" ; for ( int i = 0 ; i < 3 ; i++) res += String.valueOf(random01Generator()); BigInteger bg = new BigInteger(res, 2 ); val = bg.intValue(); } System.out.println(val); } // Driver Code public static void main(String[] args){ RandomImp r = new RandomImp(); r.random06Generator(); } } |
3 2 4 1
这个问题的灵感来源于此 堆栈溢出链路