从列表中选择n个随机条目

时间:2011-08-26 11:24:49

标签: random

我有一个N个项目的数组,我希望能够从中选择M个不同的随机项目,其中M< N.

我目前通过选择一个随机索引,检查它是否已经被选中,以及是否在我的子集中使用它来实现这一点。问题是,这需要我存储已经选择的项目列表,以便我知道我是否已经使用过一个。

有没有办法生成跨越一组索引的随机数,但在循环回到开头之前不重复?

提前干杯

3 个答案:

答案 0 :(得分:0)

如果您可以销毁原始数组:

选择0和N-1之间的随机元素位置,得到所选元素。将数组的最后一个元素移动到所选元素的位置。现在,数组中只有一个元素。您可以重复此过程M次。

答案 1 :(得分:0)

第一个元素有M/N被选中的机会,所以用这个概率选择它并递归或迭代地进行。

在伪代码中,rand(k)会给出在1k之间统一选择的随机整数:

for (i = N to 1)
{
   if (rand(i) <= M)
   {
      choose i;
      M--;
   }
}

答案 2 :(得分:0)

有N选择M = N! /((N-M)!M!)可供选择的子集,因此选择这些子集的某些排序,然后选择1和N之间的随机数选择M,然后使用该子集。

例如,如果N = 3且M = 2,您的排序可能是{1,2},{1,3},{2,3},因此您可以从1中选择一个随机数到3然后取相应的元素(1 - &gt; {1,2},2 - &gt; {1,3},3 - &gt; {2,3})。