objective-c – 如何使用错误的生成器获取随机数

前端之家收集整理的这篇文章主要介绍了objective-c – 如何使用错误的生成器获取随机数前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
问题:假设您有一个随机生成器randn(),它返回0到n-1之间的均匀分布的随机数.给定任意数m,写一个随机生成器,返回0到m-1之间的均匀分布的随机数.

我的答案:

  1. -(int)randm() {
  2. int k=1;
  3. while (k*n < m) {
  4. ++k;
  5. }
  6. int x = 0;
  7. for (int i=0; i<k; ++i) {
  8. x += randn();
  9. }
  10. if (x < m) {
  11. return x;
  12. } else {
  13. return randm();
  14. }
  15. }

它是否正确?

解决方法

你很接近,但你的答案的问题是,有一种方法可以将一个数字写成另外两个数字的总和.

如果m 方法可以将数字写成另外两个数字的总和.例如,只有一种方法可以获得0但是有很多方法可以获得m="" 2,因此概率不会相等.="" 示例:n="2且m" =="" 3="" <="">

  1. 0 = 0+0
  2. 1 = 1+0 or 0+1
  3. 2 = 1+1

所以你方法的概率分布是

  1. P(0)=1/4
  2. P(1)=1/2
  3. P(2)=1/4

哪个不统一.

解决此问题,您可以使用唯一分解.在基数n中写m,跟踪所需的最大指数,例如e.然后,找到小于n ^ e的m的最大倍数,称之为k.最后,用randn()生成e数,将它们作为某个数x的基数n展开,如果x <1. k * m,返回x,否则再试一次. 假设m

  1. int randm() {
  2.  
  3. // find largest power of n needed to write m in base n
  4. int e=0;
  5. while (m > n^e) {
  6. ++e;
  7. }
  8.  
  9. // find largest multiple of m less than n^e
  10. int k=1;
  11. while (k*m < n^2) {
  12. ++k
  13. }
  14. --k; // we went one too far
  15.  
  16. while (1) {
  17. // generate a random number in base n
  18. int x = 0;
  19. for (int i=0; i<e; ++i) {
  20. x = x*n + randn();
  21. }
  22. // if x isn't too large,return it x modulo m
  23. if (x < m*k)
  24. return (x % m);
  25. }
  26. }

猜你在找的C&C++相关文章