我有一个N个项目的数组,我希望能够从中选择M个不同的随机项目,其中M< N.
我目前通过选择一个随机索引,检查它是否已经被选中,以及是否在我的子集中使用它来实现这一点。问题是,这需要我存储已经选择的项目列表,以便我知道我是否已经使用过一个。
有没有办法生成跨越一组索引的随机数,但在循环回到开头之前不重复?
提前干杯
答案 0 :(得分:0)
如果您可以销毁原始数组:
选择0和N-1之间的随机元素位置,得到所选元素。将数组的最后一个元素移动到所选元素的位置。现在,数组中只有一个元素。您可以重复此过程M次。
答案 1 :(得分:0)
第一个元素有M/N
被选中的机会,所以用这个概率选择它并递归或迭代地进行。
在伪代码中,rand(k)
会给出在1
和k
之间统一选择的随机整数:
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})。