java概率随机_java产⽣不等概率随机数的简单⽅法
java编程的时候常要⽤到随机数。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
sum += (max-i); //sum每次增长的长度为各个⼩区间的跨度
if(sum > x) //如果sum>x,就表明x落在了第i个⼩区间内
return i; //因此,i就是我们要产⽣的随机数
}
return -1;
java生成随机数的方法}