等概率选取问题 Random Pick
2014-05-03 13:33
246 查看
选取问题是:从元素个数为N的集合中随机选取K个,这里要求是不重复的选取。等概率选取问题要求保证选取的随机性,即集合中每个元素被选取的概率都相等。下面是两个常见的方法。
方法一:保证了按顺序选取,即把被选出的K个元素从左到右的顺序依次选出。当然N是事先已知的。
方法二:保证了在事先不知道N为多少的情况下,只扫描一遍就选出K个元素。当然没有保证选出的K个元素是按原顺序排列的。
方法一:对于整数m和n,其中m<n,输出0~n-1范围的整数中m个随机值的有序列表,不允许重复。
0被选取的概率:m/n1被选取的概率,分别看0被选中或不被选中的情况:(n-m)/n * m/(n-1) + m/n * (m-1)/(n-1) = m/n
2被选取的概率,分别看0,1是否被选中的情况:(m-2)/(n-2) * m/n * m/n + (m-1)/(n-2) * m/n * (n-m)*2/m + m/(n-2) * (n-m)/n * (n-m)/n = m/n
……
从0~n-1依次计算每个i被输出的概率,发现都是m/n,因此是等概率的随机选取。
方法二:有一个长度为N的链表,N未知。要求只遍历一次链表,就从链表中等概率的挑出K个数(K<N),不允许重复。
首先选出前k个数,保存在pick[1...k]中。
然后从第k+1个开始遍历:
i = k+1
while(p != NULL)
r = random(1, i);
if (1 <= r <= k);
pick[r] = i;
i++;
p = p->next;
1号结点被选取的概率,遍历到1号结点时被选中,且之后不会被覆盖:k/(k+1) * (k+1)/(k+2) * … * (N-1)/N = K/N
2号结点被选取的概率,遍历到2号结点时被选中,且之后不会被覆盖:k/(k+1) * (k+1)/(k+2) * … * (N-1)/N = K/N
……
k+1号结点被选取的概率,遍历到k+1号结点时被选中,且之后不会被覆盖:k/(k+1) * (k+1)/(k+2) * … * (N-1)/N = K/N
……
最后一个结点被选取的概率,遍历到N号结点时被选中:K/N
从1~N依次计算每个i被最终选取的概率,发现都是K/N。
方法一:保证了按顺序选取,即把被选出的K个元素从左到右的顺序依次选出。当然N是事先已知的。
方法二:保证了在事先不知道N为多少的情况下,只扫描一遍就选出K个元素。当然没有保证选出的K个元素是按原顺序排列的。
方法一:对于整数m和n,其中m<n,输出0~n-1范围的整数中m个随机值的有序列表,不允许重复。
void GenRandom(int m, int n) { for(int i=0; i<n; ++i) { if((bigrand()%(n-i)) < m) { cout<<i<<endl; --m; //只有被选中时m才自减 } } }
0被选取的概率:m/n1被选取的概率,分别看0被选中或不被选中的情况:(n-m)/n * m/(n-1) + m/n * (m-1)/(n-1) = m/n
2被选取的概率,分别看0,1是否被选中的情况:(m-2)/(n-2) * m/n * m/n + (m-1)/(n-2) * m/n * (n-m)*2/m + m/(n-2) * (n-m)/n * (n-m)/n = m/n
……
从0~n-1依次计算每个i被输出的概率,发现都是m/n,因此是等概率的随机选取。
方法二:有一个长度为N的链表,N未知。要求只遍历一次链表,就从链表中等概率的挑出K个数(K<N),不允许重复。
首先选出前k个数,保存在pick[1...k]中。
然后从第k+1个开始遍历:
i = k+1
while(p != NULL)
r = random(1, i);
if (1 <= r <= k);
pick[r] = i;
i++;
p = p->next;
1号结点被选取的概率,遍历到1号结点时被选中,且之后不会被覆盖:k/(k+1) * (k+1)/(k+2) * … * (N-1)/N = K/N
2号结点被选取的概率,遍历到2号结点时被选中,且之后不会被覆盖:k/(k+1) * (k+1)/(k+2) * … * (N-1)/N = K/N
……
k+1号结点被选取的概率,遍历到k+1号结点时被选中,且之后不会被覆盖:k/(k+1) * (k+1)/(k+2) * … * (N-1)/N = K/N
……
最后一个结点被选取的概率,遍历到N号结点时被选中:K/N
从1~N依次计算每个i被最终选取的概率,发现都是K/N。
相关文章推荐
- 海量数据等概率选取问题
- 单次遍历,等概率随机选取问题
- 海量数据等概率选取问题
- 单次遍历,等概率随机选取问题
- 一次遍历,等概率随机排列数组与带权随机选取问题
- 单次遍历,等概率随机选取问题
- 海量数据等概率选取问题
- 海量数据等概率随机选取问题
- KMP算法与一个经典概率问题
- 面试题——出界概率问题
- 详解Android7.0及以上版本拍照或者相册选取照片包括裁剪照片时时App崩溃问题
- 概率问题的求解
- 又是一道随机问题,问题是说:写一个函数返回0,1,2,3这几个数字中的一个数,其中0概率是10%,1是20%,2是30%,3是40%
- 解决等概率随机抽样问题
- 一道经典概率问题
- 对于一类离散的概率DP问题的总结(第一次)
- 关于ListView中加入并选取checkbox错位的问题
- 【趣题】非常具有启发性的概率问题
- 概率与随机函数问题
- 搜狐2017实习生笔试题_概率问题