【发布时间】:2011-08-26 11:24:49
【问题描述】:
我有一个包含 N 个项目的数组,我希望能够从中选择 M 个不同的随机项目,其中 M
我目前通过选择一个随机索引来实现这一点,检查它是否已经被选择,如果没有在我的子集中使用它。问题是,这需要我存储一个已选择项目的列表,以便我知道我是否已经使用过一个。
有没有办法生成跨越一组索引但不重复直到它们循环回到开头的随机数?
提前干杯
【问题讨论】:
标签: random
我有一个包含 N 个项目的数组,我希望能够从中选择 M 个不同的随机项目,其中 M
我目前通过选择一个随机索引来实现这一点,检查它是否已经被选择,如果没有在我的子集中使用它。问题是,这需要我存储一个已选择项目的列表,以便我知道我是否已经使用过一个。
有没有办法生成跨越一组索引但不重复直到它们循环回到开头的随机数?
提前干杯
【问题讨论】:
标签: random
如果你可以破坏原始数组:
选择0到N-1之间的随机元素位置,获取选中的元素。将数组的最后一个元素移动到所选元素的位置。现在您在数组中少了一个元素。你可以重复这个过程 M 次。
【讨论】:
第一个元素有M/N被选中的机会,因此以这个概率选择它并递归或迭代地进行。
在伪代码中,rand(k) 会给出一个在1 和k 之间统一选择的随机整数:
for (i = N to 1)
{
if (rand(i) <= M)
{
choose i;
M--;
}
}
【讨论】:
有N个选择M = N! / ((N-M)!M!) 可能的子集选择,所以选择这些子集的一些排序,然后选择 1 和 N 之间的随机数选择 M,然后使用该子集。
例如,如果 N = 3 且 M = 2,您的排序可能是 {1,2}、{1,3}、{2,3},因此您可以从 1 到 3 中选择一个随机数然后取对应的元素 (1 -> {1,2}, 2 -> {1,3}, 3 -> {2,3})。
【讨论】: