抽样问题的解决方案

来源:互联网 发布:mastercam9.1编程全集 编辑:程序博客网 时间:2024/06/14 05:23

问题: 输入整个整数m和n(0<m<n)

输出:要求按顺序输出m个随机整数,整数的值的范围是0~n-1。

例如:输入5和100,

输出: 3,8,34,55,77

 

解决方案1. 按顺序考虑整数0,1,2,...,n-1,并通过核实的随机测试选择每个元素, 通过按需访问整数,就能保证输出结果是有序的。

 

该方案的c语言实现程序:假设有一个生成随机整数的函数bigrand()

void getSortedRandomArray(int m, int n)

{

int index;

for(index = 0; index < n; index++)

{

if(bigrand()%(n-index) < m)

{

printf("%d/n", index);

m--;

}

}

}

 

该程序能很好的运行,并生成预期的结果,但是当n非常大时,该程序可能运行的非常慢。

我们发现,无论如何,循环内部的代码会运行n次,当n非常大时,这个速率是非常慢的。

那么有没有改进的措施呢?很显然,当m已经减为0时,程序已经不需要再运行下去了,那么我们在判断m为零时便应该返回,这种办法确实能有效的提高运行速率,但是效果并不是很明显。

 

那么有没有更好的办法呢?

解决方案2: 在一个初始为空的集合中插入随机整数,直到填入足够的整数。

该方法的伪代码如下:

initialize set s to empty

size = 0

while size < m do

t = bigrand()%n

if t is not in S

insert t into S

size++

print the element of S in sorted order

 

该算法在选择元素时嫩巩固保证所有的元素都具有相同的选中的概率,他的输出是随机的,但是还有一个问题,那就是集合S的实现,所以必须要考虑使用合适的数据结构。在这里我们选用C++标准模板库中现有的东西set。

 

然而,上述方法又产生了另一个问题,该算法的空间复杂度太大。当m特别大时,需要占用很多的内存,这在机器配置较低的情况下,很明显是不允许的。

 

解决方案3:

产生随机整数的排序子集的另一个方法是弄乱一个n个元素数据,这个数组包含数值的范围是0,n-1,然后排序前m个元素并输出。

对于我们来说,只需要弄乱数组的前m个元素,然后排序输出。

但是,如果我们使用bitmap或者bloom filter方法的话,连排序所耗费的值都可以省略掉。

 

over 啦