从i到j(i<j)中随机取n个数的随机算法
2014-01-09 14:57
169 查看
想法:假设我们有一个集合A(a_1,…,a_n), 对于数m,0≤m≤n, 如何从集合A中等概率地选取m个元素呢?
通过计算古典概率公式可以得到, 每个元素被选取的概率为m/n,即为抽签概率
简单证明:
设两个元素(2<=m<=n),概率p
1) 设p(a_i=1)表示a_i被选中的概率。显而易见, p(a_1=1)=m/n, p(a_1=0)为(n-m)/n;
2)第二个元素被选中的概率为
p(a_2=1)= p(a_2=1,a_1=1)+p(a_2=1,a_1=0)
= p(a_1=1)*p(a_2=1│a_1=1)+ p(a_1=0)* p(a_2=1│a_1=0)
= m/n * (m-1)/(n-1) + (n-m)/n*m/(n-1)
= m/n
java代码实现:
m数组中前COUNT个数即为随机数
通过计算古典概率公式可以得到, 每个元素被选取的概率为m/n,即为抽签概率
简单证明:
设两个元素(2<=m<=n),概率p
1) 设p(a_i=1)表示a_i被选中的概率。显而易见, p(a_1=1)=m/n, p(a_1=0)为(n-m)/n;
2)第二个元素被选中的概率为
p(a_2=1)= p(a_2=1,a_1=1)+p(a_2=1,a_1=0)
= p(a_1=1)*p(a_2=1│a_1=1)+ p(a_1=0)* p(a_2=1│a_1=0)
= m/n * (m-1)/(n-1) + (n-m)/n*m/(n-1)
= m/n
java代码实现:
public void getRandomIntegers(int low, int high, int count){ if(count > high - low) return; int size = high-low+1; int [] m = new int[size]; for(int i=0;i<size;++i){ m[i] = low+i; } Random r = new Random(); for(int i=0;i<count;++i){ int randomIndex = r.nextInt(size-1)%(size-i)+i; int t = m[randomIndex]; m[randomIndex] = m[i]; m[i] = t; } }
m数组中前COUNT个数即为随机数
相关文章推荐
- 对List<T> 随机排序
- VS2010使用扩展方法对List<T>进行随机排序
- 黑马程序员_<<IO扩展对象和编码(序列化,管道流,字节(符)数组),随机访问文件>>
- 随机生成[0,n)(n<=RAND_MAX)的数
- 在0~N(不包括N)范围内随机生成一个长度为M(M <= N)且内容不重复的数组
- 假设有一个rand(0,1)的0,1随机生成器,如何对于给定的(a,b),随机生成一个x, 其中 a <= x <= b
- 如何设计一个高效算法从N个正整数中,随机选取n个不同的随机数 n<=N
- 黑马程序员_<<IO扩展对象和编码(序列化,管道流,字节(符)数组),随机访问文件>>
- #error WINDOWS.H already included. MFC apps must not #include <windows.h>
- _java基础<一>_Java开发前奏
- 加上#include<windows.h>后出现的奇葩错误
- 常用AWT监听器接口,事件和事件源(摘自Java 2 核心技术<卷一:基础知识>(第七版)》)
- 六十六 位操作 0x1 << 3
- 使用<a>标签提交action会执行两次后台方法的原因(反射机制小实例问题的解决)
- <c:foreach><c:forTokens>
- 通过<frameset>和<iframe>看JavaScript中window对象parent、self、top的区别
- 前面所有input时间的最大时间<时间<后边所有Input时间的最小时间
- <<数学>>柏拉图多面体---定积分(一)
- c语言深入理解<1>static理解
- seq<打印出一串有序的数字>