您的位置:首页 > 编程语言

编程珠玑:取样问题

2012-08-15 16:00 344 查看
1.问题描述

程序的输入包含两个整数m和n,其中m<n。输出是0~n-1范围内m个随机整数的有序列表,不允许重复。从概率的角度说,我们希望得到没有重复的有序选择,其中每个选择出现的概率相等。

2.解决思路与代码实现

编程珠玑上给出了四个函数

1).genknuth():算法依次考虑整数0,1,2,...,n-1,并通过一个适当的随机测试对每个整数进行选择。通过按序访问整数,可以保证输出结果是有序的

代码C++实现:

void genknuth(int m, int n)
{
for(int i = 0;i < 0;i++)
{
if((bigrand() % (n-i)) < m)
{
cout << i << "\n";
m--;
}
}
}


2).gensets():一种解决方案是在一个初始为空的集合里面插入随机整数,直到个数足够,这里利用C++ set容器

void gensets(int m, int n)
{
set<int> S;

while(S.size() < m)
S.insert(bigrand() % n);
set<int>::iterator i;

for(i = S.begin(); i != S.end(); ++i)
cout << *i << endl;
}


3).genshuffle():生成随机整数的有序子集的另一种方法是把包含整数0~n-1的数组的前m个元素打乱,然后把前m个元素排序输出。

void genshuf(int m, int n)
{
int i,j;
int *x = new int
;

for(i = 0; i < n; i++)
x[i] = i;
for(i = 0; i < m; i++)
{
j = randint(i, n-1);
int t = x[i];
x[i] = x[j];
x[j] = t;
}

sort(x , x+m);
for(i = 0; i < m; i++)
cout << x[i] << endl;
}


4).genfloyd():m和n接近的时候,基于2)的改进,并能在m个步骤之内就可以按要求等概率地生成有序随机数

void genfloyd(int m, int n)
{
set<int> S;
set<int>::iterator i;

for(int j = n-m; j < n; j++)
{
int t = bigrand() % (j+1);
if(S.find(t) == S.end())
S.insert(t);            //t not in S
else
S.insert(j);            //t in S
}

for(i = S.begin(); i != S.end(); ++i)
cout << *i << endl;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: