给定函数rand7(),写一个rand10()统一的函数

时间:2011-03-19 23:09:30

标签: algorithm data-structures

我是否可以针对上述问题找到有效的解决方案....我试图从这个网站找出问题http://www.ihas1337code.com/2010/11/rejection-sampling.html 但无法理解 idx = col +(row-1)* 7;他们为什么会乘以7 ......

我们也可以这样做(rand7()* rand7())%10 ...或乘以任何其他数字,因为最后我们必须做mod 10,它将仅在10内给出结果。 ..

为什么他们让解决方案变得如此困难..请解释一下你的想法......

问题中统一意味着什么?

谢谢..

3 个答案:

答案 0 :(得分:7)

(rand7() * rand7()) % 10

不会这样做,因为某些值比其他值更有可能。

让我们比较获得1和获得2的概率

获得1:

  • rand7() * rand7()需要等于1,11,21,31或41。
  • 这可以通过以下方式实现:1 * 1,3 * 7或7 * 3.
  • 也就是说,49次中有3次你会得到1

获得2:

  • rand7() * rand7()需要等于2个,12个,22个,32个或42个。
  • 这可以通过以下方式实现:1 * 2,2 * 1,3 * 4,4 * 3,2 * 6,6 * 2,6 * 7,7 * 6。
  • 也就是说,49个中有8个你会得到2个!

他们的解决方案通过让每个数字(从1到10)同样可能来解决这个问题:在49个可能的结果中每个数字出现4次(9个结果被丢弃并导致重新采样)。


事实上,Random.nextInt(int n)的实施做了类似的事情:

int bits, val;
do {
    bits = next(31);
    val = bits % n;
} while (bits - val + (n-1) < 0);    // re-sample until in range.
return val;

这实际上使用rand2来实现randN

答案 1 :(得分:3)

这是将两位数的基数为7的数字转换为基数为10的数字。这正是你将其扩展到

的解决方案的方式

广义问题

使用randA()实现randB()功能,B,A&gt; 1。

解决方案

  1. 生成足够多的(ceil(ln(A)/ln(B)))base-B数字

  2. 确保均匀分布:如果数字> A*floor(pow(B,ceil(ln(A)/ln(B)))/A)拒绝并继续1,否则继续3

  3. Base将得到的数字转换为base-A,选择最低有效数字作为randA()的结果

  4. JavaScript的实施例

    // This function returns a randN function. Usage 
    // example rand7=randn(7); rand7(); rand7()
    function randn(i) {
        return function () {return Math.floor(Math.random() * i);};
    }
    
    // Given a random generator for numbers 0..b-1 this
    // function returns a random generator for numbers 0..a-1
    
    function randA(b, randB, a) {
        var digits=Math.ceil(Math.log(a)/Math.log(b));
        var maxNum=a*Math.floor(Math.pow(b, digits)/a)-1;
        return function() {
            var s;
            var number;
            do {
                s="";
    
                // Step 1
                for ( var i=0; i<digits; i++ )
                    s += randB();
    
                number=parseInt(s, b);
    
            } while (number>maxNum); // Step 2
    
            return number%a; // Step 3
        };
    }
    // generates a rand8() number generator
    rand8=randA(2,randn(2),8);
    // generates array containing random numbers 0..7
    [rand8(), rand8(), rand8()] 
    

答案 2 :(得分:0)

统一意味着每个结果同样频繁发生。如果你拨打rand7()七百万次,你将获得大约一百万次的结果。

但请尝试计算(rand7() * rand7()) % 10的结果。你会惊讶地发现其中一个结果与其他结果相比更频繁。