假设我要递归创建一个数字列表,方法是随机选择一个从0到9的数字以开始,然后(可选)随机选择另一个x + 1和9之间的数字,其中x是最后选择的数字,并可以选择重复此操作处理。这样,您可以获得诸如1,3,63,4,8,92,7之类的列表。这是我真正想做的事情的简化。

出于我的目的,我不想只是从列表中挑选一堆随机数字,删除重复的数字然后对其进行排序。这需要递归完成。问题在于,以我所描述的方式简单地进行操作不会给所有数字以均等的机会。与较小的数字相比,它将选择更多的数字。我尝试了一些措施来抵消这种情况,但随后它偏爱少量数字。

这是使用Lo-Dash中的随机整数函数的javascript:

function randomlist(index) {
    if (index > 8) return;
    var range = _.random(9 - index);
    var randex = [_.random(index, index + range)];
    if (_.random(10) < 6) randex = randex.concat(randomlist(randex[0] + 1));
    return randex
}

tally = [0,0,0,0,0,0,0,0,0,0]
for (i=0;i<1000;i++) {
    var list = randomlist(0);
    list.forEach(function(x){tally[x]+=1});
}


在这里,不只是选择x到9之间的随机数,而是首先选择一个较小的随机范围,然后选择该范围内的随机数。我以为它可以解决问题,但是当我运行上面的代码时,tally最终看起来像[278, 262, 224, 189, 217, 180, 185, 179, 156, 61],显然倾向于较小的数字。如果我调整递归的机会,那么平衡会有所变化。我希望可能存在一些公式,该公式可以调整递归的机会并设法生成均匀采样所有数字的列表。

最佳答案

根据您的描述,只有少量的“列表”适合该描述。因此,假设您创建一个包含所有元素的数组,然后从该数组中随机选择某些内容?这里:

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8" />
  <title>test-page</title>
 <script type="text/javascript">
//<!--

var lists, und, tmp, dv, pkd, i, q,r,s,t,u,v,w,x,y,z;

function begin()
{ lists=[];
  for(i=0,q=0; q<10; q++)
    for(r=q+1;r<10;r++)
    { lists[i++]=[q,r];
      for(s=r+1;s<10;s++)
      { lists[i++]=[q,r,s];
        for(t=s+1;t<10;t++)
        { lists[i++]=[q,r,s,t];
          for(u=t+1;u<10;u++)
          { lists[i++]=[q,r,s,t,u];
            for(v=u+1;v<10;v++)
            { lists[i++]=[q,r,s,t,u,v];
              for(w=v+1;w<10;w++)
              { lists[i++]=[q,r,s,t,u,v,w];
                for(x=w+1;x<10;x++)
                { lists[i++]=[q,r,s,t,u,v,w,x];
                  for(y=x+1;y<10;y++)
                  { lists[i++]=[q,r,s,t,u,v,w,x,y];
                    for(z=y+1;z<10;z++)
                      lists[i++]=[q,r,s,t,u,v,w,x,y,z];
    } } } } } } } }
  for(j=0; j<i; j++)
  { tmp=document.createElement("span");
    tmp.innerHTML=lists[j]+"<br />";
    document.body.appendChild(tmp);
  }
  tmp=document.createElement("span");
  tmp.innerHTML="<br />Total: " + i + " lists. <br />";  //1013
  document.body.appendChild(tmp);
  pkd=[];
  i=0;
  dv=document.getElementById("pks");
  return;
}

function Pick()
{ if(lists==und)
    return;
  q=Math.floor(Math.random()*1013);
  for(r=0; r<i; r++)
    if(pkd[r]==q)  //check this array for previously-picked list
      break;
  if(r==i)         //not previously picked?
  { pkd[i++]=q;    //add to array
    tmp=document.createElement("span");
    tmp.innerHTML=lists[q]+"<br />";
    dv.appendChild(tmp);  //display this list
  }
  else
    Pick();  //try again to pick an unpicked list
    //DON'T click the button more than 1013 times!
  return;
}

 // -->
 </script>
</head>
<body>
<input type="button" value="create lists" onclick="begin();" />&nbsp; &nbsp;
<input type="button" value="random pick" onclick="Pick();" /><br />
<br />
<div id="pks">
</div>
<br />
</body>
</html>

07-28 07:19