从 javascript 中的 pdf 中选取一个随机变量

Picking a random variable from a pdf in javascript

我有一些奇怪的错误,我无法理解它的来源。我正在 Google 脚本环境中用 js 编写它。

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) returns 一个结果根据 pdf

问题是元组总是 returns 在某些地方全为 1。看起来随机发生器工作得很好,但循环只经过一次。 有人有提示吗?

更新:

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;
}

这样做的原因是:

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

如果你return 0 or any of rand first index这里你返回未定义然后它会正确显示tuple并且你可以看到循环计数。

尝试运行这个:

     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);
         tuple[rand] += 1;
       }
    
       console.log(tuple);
       document.write(tuple);
     }
    
     function getRandomN(pdf) {
       var result = 0;
       var rand = getRandomInt(0,10000)/100;
      // console.log(rand);
       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 0;}//return any of 0,1,2,3 to test your code.
    
       for (var i=0; i<pdf.length; i++){
         if (rand<=pdf[i][1]){result=pdf[i][0]; break}
    
       }
     //  console.log(pdf);
     return result;
     }
    
     function getRandomInt(min, max) {
       return Math.floor(Math.random() * (max - min)) + min;
     }
     tester();

我想我知道为什么了。因为 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;
}