zoukankan      html  css  js  c++  java
  • 67. 总结篇:面试中随机数"等概率"vs"不等概率"生成问题[random generator with equal or unequal probability]

    【本文链接】

    http://www.cnblogs.com/hellogiser/p/random-generator-with-equal-or-unequal-probability.html

    1. 等概率生成

    (1) rand5生成rand3

    现在有一个Rand5函数,可以生成等概率的[0, 5)范围内的随机整数,要求利用此函数写一个Rand3函数(除此之外,不能再使用任何能产生随机数的函数或数据源),生成等概率的[0, 3)范围内的随机整数。

     C++ Code 
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
     
    /*
        version: 1.0
        author: hellogiser
        blog: http://www.cnblogs.com/hellogiser
        date: 2014/6/3
    */

    // use rand5 to generate rand3
    int Rand3()
    {
        
    int x;
        
    do
        {
            x = Rand5();
        }
        
    while (x >= 3);
        
    return x;
    }

    (2) rand3生成rand5

     C++ Code 
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
     
    /*
        version: 1.0
        author: hellogiser
        blog: http://www.cnblogs.com/hellogiser
        date: 2014/6/3
    */

    // use rand3 to generate rand5
    int Rand5()
    {
        
    int x;
        
    do
        {
            x = Rand3() * 
    3 + Rand3();
        }
        
    while (x >= 5);
        
    return x;
    }

    (3) rand5生成rand7

     C++ Code 
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
     
    /*
        version: 1.0
        author: hellogiser
        blog: http://www.cnblogs.com/hellogiser
        date: 2014/6/3
    */

    // use rand5 to generate rand7
    int Rand7()
    {
        
    int x;
        
    do
        {
            x = Rand5() * 
    5 + Rand5();
        }
        
    while (x >= 21);
        
    return x % 7;
    }

    (4) rand7生成rand10

     C++ Code 
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
     
    /*
        version: 1.0
        author: hellogiser
        blog: http://www.cnblogs.com/hellogiser
        date: 2014/6/3
    */

    // use rand7 to generate rand10
    int Rand10()
    {
        
    int x;
        
    do
        {
            x = Rand7() * 
    7 + Rand7();
        }
        
    while (x >= 40);
        
    return x % 10;
    }

    (5) rand_m生成rand_n

     归纳总结:将这个问题进一步抽象,已知random_m()随机数生成器的范围是[0, m) 求random_n()生成[0, n)范围的函数,m < n && n <= m *m。

    设t为n的最大倍数,且满足t<m*m,即 t = ((m*m)/n)*n;

     C++ Code 
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
     
    /*
        version: 1.0
        author: hellogiser
        blog: http://www.cnblogs.com/hellogiser
        date: 2014/6/3
    */

    // use rand_m to generate rand_n
    int Rand_n()
    {
        
    int x;
        
    do
        {
            t = ((m * m) / n) * n;
            x = Rand_m() * m + Rand_m ();
        }
        
    while (x >= t);
        
    return x % n;
    }

    2. 不等概率生成

    (1) 如何产生如下概率的随机数?0出1次,1出现2次,2出现3次,n-1出现n次?

     C++ Code 
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
     
    /*
        version: 1.0
        author: hellogiser
        blog: http://www.cnblogs.com/hellogiser
        date: 2014/6/3
    */

    int random(int size)
    {
        
    while(1)
        {
            
    int m = rand(size);
            
    int n = rand(size);
            
    if(m + n < size)
                
    return m + n;
        }
    }

    (2) rand以不等概率生成01, 如何以1/n的等概率产生1~n之间的任意一个数?

    已知随机函数rand(),以p的概率产生0,以1-p的概率产生1,现在要求设计一个新的随机函数newRand(),使其以1/n的等概率产生1~n之间的任意一个数。

    解决思路:

    可以通过已知随机函数rand()产生等概率产生0和1的新随机函数Rand(),然后调用k(k为整数n的二进制表示的位数)次Rand()函数,得到一个长度为k的0和1序列,以此序列所形成的整数即为1--n之间的数字。

    注意:从产生序列得到的整数有可能大于n,如果大于n的话,则重新产生直至得到的整数不大于n。

    第一步:由rand()函数产生Rand()函数,Rand()函数等概率产生0和1。

     C++ Code 
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
     
    /*
        version: 1.0
        author: hellogiser
        blog: http://www.cnblogs.com/hellogiser
        date: 2014/6/3
    */

    int Rand()
    {
        
    while(1)
        {
            
    int i1 = rand();
            
    int i2 = rand();
            
    if(i1 == 0 && i2 == 1)
                
    return 1;
            
    else if(i1 == 1 && i2 == 0)
                
    return 0;
        }
    }

    第二步:计算整数n的二进制表示所拥有的位数k,k = 1 +log2n(log以2为底n)

    第三步:调用k次Rand()产生随机数,产生的k个01序列表示1-n之间的数。

     C++ Code 
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
     
    /*
        version: 1.0
        author: hellogiser
        blog: http://www.cnblogs.com/hellogiser
        date: 2014/6/3
    */

    int newRand()
    {
        
    while(1)
        {
            
    int result = 0;
            
    for(int i = 0 ; i < k ; ++i)
            {
                
    if(Rand() == 1)
                    result |= (
    1 << i);
            }
            
    if(result <= n)
                
    return result;
        }
    }

    【本文链接】

    http://www.cnblogs.com/hellogiser/p/random-generator-with-equal-or-unequal-probability.html

    个人学习笔记,欢迎拍砖!---by hellogiser

    Author: hellogiser
    Warning: 本文版权归作者和博客园共有,欢迎转载,但请保留此段声明,且在文章页面明显位置给出原文连接。Thanks!
    Me: 如果觉得本文对你有帮助的话,那么【推荐】给大家吧,希望今后能够为大家带来更好的技术文章!敬请【关注】
  • 相关阅读:
    (四)STL中的算法
    (三)openssl库实现对称和非对称加密
    (十一)etcd项目
    (十二)插件之dlopen/dlsym/dlclose 加载动态链接库
    (十一)访问权限关键字publi/private/protected
    RESTful架构
    (零)TCP/IP详解综述
    (二)辗转相除法求最大公约数
    (一)简单的TcpServer
    SpringMVC异常处理
  • 原文地址:https://www.cnblogs.com/hellogiser/p/random-generator-with-equal-or-unequal-probability.html
Copyright © 2011-2022 走看看