2015-01-15 77 views
0

我有一些奇怪的错误,我无法理解它来自哪里。我在Google Script环境中将它写入js。在javascript中从pdf中选择一个随机变量

function tester() { 
    var pdf = [[0,5],[1,5],[2,40],[3,50]]; // some pdf as a 2d array 
    var tuple = [0,0,0,0]; //the resulting pdf from the test 
    var rand = 0; 

    for (var i = 0; i<100; i++){ //100 times initialize a random variable and then catch the result into the tuple 
    rand = getRandomN(pdf); 
    if (rand==0){tuple[0]+=1} //if the outcome==0 then add 1 to the first element of the tuple 
     else if (rand==1){tuple[1]+=1} 
     else if (rand==2){tuple[2]+=1} 
     else if (rand==3){tuple[3]+=1} 
    } 

    Logger.log(tuple); 
} 

getRandomN(pdf)返回根据PDF

问题的一个结果是,元组始终返回1全零的一些地方。它看起来像随机发生器工作得很好,但循环只经过一次。 有没有人有提示?

UPDATE:

function getRandomN(pdf) { 
    var result = 0; 
    var rand = getRandomInt(0,10000)/100; 

    for (var i=1; i<pdf.length; i++){ 
    pdf[i][1] = pdf[i][1] + pdf[i-1][1]; 

    } 

    if (pdf[pdf.length-1][1] != 100){return undefined} 

    //Logger.log(rand); 
    for (var i=0; i<pdf.length; i++){ 
    if (rand<=pdf[i][1]){result=pdf[i][0]; break} 

    } 
    Logger.log(pdf); 
return result; 
} 

而且从Mozilla的

function getRandomInt(min, max) { 
    return Math.floor(Math.random() * (max - min)) + min; 
} 
+0

其中getRandomN如果可能的话也显示这部分。 – 2015-01-15 15:20:05

+0

我会立即添加它。这只是它工作得很好,如果我简单地测试它没有循环,但循环有点跳过。 – AVX 2015-01-15 15:23:33

+1

你的循环对我来说看起来很好......你写了getRandomN()吗?我们可以看到那个代码吗?另外,如果你知道getRandomN()只会返回与你的元组索引相匹配的值,你可以用一行代替整个循环的内部: 'tuple [getRandomN(pdf)] + = 1; ' – 2015-01-15 15:25:55

回答

1

这样做的原因标准功能是:

if (pdf[pdf.length-1][1] != 100){return undefined;} 

这里你返回undefined如果你return 0 or any of rand first index那么它将显示正确的tuple,您可以看到循环算。

试运行以下命令:

 function tester() { 
 
    \t var pdf = [[0,5],[1,5],[2,40],[3,50]]; // some pdf as a 2d array 
 
    \t var tuple = [0,0,0,0]; //the resulting pdf from the test 
 
    \t var rand = 0; 
 
    
 
    \t for (var i = 0; i<100; i++){ //100 times initialize a random variable and then catch the result into the tuple 
 
    \t  rand = getRandomN(pdf); 
 
    \t  tuple[rand] += 1; 
 
    \t } 
 
    
 
    \t console.log(tuple); 
 
     document.write(tuple); 
 
    \t } 
 
    
 
    function getRandomN(pdf) { 
 
    \t var result = 0; 
 
    \t var rand = getRandomInt(0,10000)/100; 
 
    \t // console.log(rand); 
 
    \t for (var i=1; i<pdf.length; i++){ 
 
    \t  pdf[i][1] = pdf[i][1] + pdf[i-1][1]; 
 
    
 
    \t  } 
 
    
 
    \t if (pdf[pdf.length-1][1] != 100){return 0;}//return any of 0,1,2,3 to test your code. 
 
    
 
    \t for (var i=0; i<pdf.length; i++){ 
 
    \t  if (rand<=pdf[i][1]){result=pdf[i][0]; break} 
 
    
 
    \t } 
 
    \t // console.log(pdf); 
 
    \t return result; 
 
    \t } 
 
    
 
    function getRandomInt(min, max) { 
 
    \t return Math.floor(Math.random() * (max - min)) + min; 
 
    \t } 
 
    tester();

+0

哇。谢谢你Suchit!但为什么这样呢?如果一个pdf的所有概率之和等于100,即cdf的最后一个元素,因为我没有重命名它,但重写了pdf,所以我只是在这个片段中检查。我评论了该部分,它的工作原理。但为什么? – AVX 2015-01-15 15:47:21

+0

我想我知道为什么。由于pdf的范围完全是全局的,我正在改变它在getRandomN(pdf)中,因此它一直在增加,并且在第一次运行后它会被更新,并且我正在从一个新的pdf中计算,最后一个pdf(即cdf)的元素将永远不会等于100. – AVX 2015-01-15 16:01:37

+0

没有你,我就无法解决它。谢谢你的提示! – AVX 2015-01-15 16:03:53

0

我想我知道这是为什么。由于pdf的范围在tester()内完全是全球性的,因此我在getRandomN(pdf)内更改它,因此它一直在增加,第一次运行后它会更新,我已经从一个新的pdf中计算出来,最后一个pdf(即cdf)的元素将永远不会等于100. 更新: 只要您对正在工作的正确代码感兴趣即可。将PDF映射到cdf的部分并不是最美的一部分。我会欣赏改进提示,但它工作得很好。感谢贡献者指出正确的方向。

function getRandomN(pdf) { 
    var result = 0; 
    var rand = getRandomInt(0,10000)/100; 
    var cdf = []; 

    //construct the cdf 
    for (var i=1; i<pdf.length; i++){ 
    //handle the first unchanged element 
    cdf[0]=[]; 
    cdf[0][1] = pdf[0][1]; 
    cdf[0][0] = pdf[0][0]; 

    cdf[i]=[]; 
    cdf[i][1] = pdf[i][1] + cdf[i-1][1]; 
    cdf[i][0] = pdf[i][0];//add all outcomes to the array's first column 
    } 

    if (cdf[cdf.length-1][1] != 100){return undefined} 

    //Logger.log(rand); 
    for (var i=0; i<cdf.length; i++){ 
    if (rand<=cdf[i][1]){result=cdf[i][0]; break} 
    } 

    //Logger.log(cdf); 
return result; 
}