2015-01-15 90 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; 
}