产生不等概率随机数的简单方法
2006-09-18 22:58
363 查看
在编写程序的时候,经常要用到随机数。JAVA自带了一个产生随机数的方法,该方法能够较好的等概率的产生某个区间之内的随机数。但是有些时候,我们需要在一个区间内产生不等概率的随机数。比如一个数组,我想随机的取出一个元素,如果元素靠前则取出的概率大些,如果元素靠后则取出的概率小些,这里就要用到不等概率随机数来作为数组的下标来从数组中取出数字。下面我们就来探讨一个简单的算法。
我们先把问题叙述的更详细一点,就是在一个[0, n]的区间中,产生一个随机数,0的概率最大,1的概率比0稍小,2的概率比1稍小,以此类推,产生n的概率是最小的,这就是所谓的不等概率随机数。
问题叙述清楚了,下面说说算法。我们简单起见,让产生各个数字的概率等差递减,也就是说,各个随机数的概率之比为“n+1:n:n-1:……1”。那么,我们首先要构造一个区间,区间的下限为0,上限为各个比率数字之和,也就是(n+1)+n+(n-1)+(n-2)+……+1。那么,构造这样一个区间有什么用呢?我们首先把这个大区间划分为n+1个长度不等的小区间,每个小区间的跨度和各个数字的产生概率对应,也就是[0, n](跨度为n+1),[n+1, 2n](跨度为n),以此类推。因此,这些小区间就代表了各个数字产生的概率。最后在大区间中生成一个等概率随机数x,x落在哪个小区间内,那么就产生该区间代表的那个数字。算法大概就是这样,下面给出一个具体的实现:
//产生0~n之间的随机数,0的概率最大,n的概率最小
private static int myRandom(int n) ...{
int max = n+1; //0~n共有n+1个数字
int bigend = ((1+max)*max)/2; //大区间的上限(1+2+……+max)
int x = (int)(Math.random()*bigend); //产生一个区间内的随机数x
int sum = 0; //sum表示了各个小区间的上限
for(int i=0; i<max; i++) ...{
sum += (max-i); //sum每次增长的长度为各个小区间的跨度
if(sum > x) //如果sum>x,就表明x落在了第i个小区间内
return i; //因此,i就是我们要产生的随机数
}
return -1;
}
当然,这篇文章只是告诉大家一个简单的思路,那就是首先设置大区间,再将大区间划分为小区间,小区间的长度代表了各个数字产生的概率,因此,如果你对哪个数字的概率有特殊的要求,只要适当调节小区间的跨度即可实现。
我们先把问题叙述的更详细一点,就是在一个[0, n]的区间中,产生一个随机数,0的概率最大,1的概率比0稍小,2的概率比1稍小,以此类推,产生n的概率是最小的,这就是所谓的不等概率随机数。
问题叙述清楚了,下面说说算法。我们简单起见,让产生各个数字的概率等差递减,也就是说,各个随机数的概率之比为“n+1:n:n-1:……1”。那么,我们首先要构造一个区间,区间的下限为0,上限为各个比率数字之和,也就是(n+1)+n+(n-1)+(n-2)+……+1。那么,构造这样一个区间有什么用呢?我们首先把这个大区间划分为n+1个长度不等的小区间,每个小区间的跨度和各个数字的产生概率对应,也就是[0, n](跨度为n+1),[n+1, 2n](跨度为n),以此类推。因此,这些小区间就代表了各个数字产生的概率。最后在大区间中生成一个等概率随机数x,x落在哪个小区间内,那么就产生该区间代表的那个数字。算法大概就是这样,下面给出一个具体的实现:
//产生0~n之间的随机数,0的概率最大,n的概率最小
private static int myRandom(int n) ...{
int max = n+1; //0~n共有n+1个数字
int bigend = ((1+max)*max)/2; //大区间的上限(1+2+……+max)
int x = (int)(Math.random()*bigend); //产生一个区间内的随机数x
int sum = 0; //sum表示了各个小区间的上限
for(int i=0; i<max; i++) ...{
sum += (max-i); //sum每次增长的长度为各个小区间的跨度
if(sum > x) //如果sum>x,就表明x落在了第i个小区间内
return i; //因此,i就是我们要产生的随机数
}
return -1;
}
当然,这篇文章只是告诉大家一个简单的思路,那就是首先设置大区间,再将大区间划分为小区间,小区间的长度代表了各个数字产生的概率,因此,如果你对哪个数字的概率有特殊的要求,只要适当调节小区间的跨度即可实现。
相关文章推荐
- 不等概率产生随机数产生
- VC++中产生为随机数的简单方法
- VS2010中的C++产生各种“随机数”的方法(第2讲)——等概率随机量
- 一种不等概率随机数产生办法
- 给定一个函数rand()能产生0到n-1之间的等概率随机数,问如何产生0到m-1之间等概率的随机数?
- 实际中常用的一个随机数产生器(分类别概率随机)
- Lua的系统学习(杂)_通过Lua调用C#方法(热更新最直观的原理理解)_简单的随机数实现
- C# 获取一定区间的随即数 0、1两个值除随机数以外的取值方法(0、1两个值被取值的概率相等)
- C#实现的简单随机数产生器功能示例
- Python之产生泊松分布随机数,并进行矩阵的简单运算
- 用最简单的方法来为自己的软件产生序列号.
- 随机数产生方法
- 产生随机数的两种方法
- linux下 C语言随机数生成方法rand(产生随机数)
- c语言产生随机数的方法
- dos下使用汇编产生一个随机数方法
- 产生随机数的方法
- 简单生成随机数id的方法
- 随机数产生方法小知识点
- C/C++如何产生随机数方法整理