读书人

一种不等概率随机数发作办法

发布时间: 2012-09-23 10:28:11 作者: rapoo

一种不等概率随机数产生办法

一种不等概率随机数产生办法

Java实用工具库Java.util中的Random提供了产生各种类型随机的方法,它可以产生int,long,float,double等类型的随机数。例如:

view plaincopy to clipboardprint?
Random rd = new Random();??
System.out.println("The set of random numbers:");??
System.out.println("Integer:"+rd.nextInt());??
System.out.println("Long:"+rd.nextLong());??
System.out.println("Float:"+rd.nextFloat());??
System.out.println("Double:"+rd.nextDouble());??
Random rd = new Random();
System.out.println("The set of random numbers:");
System.out.println("Integer:"+rd.nextInt());
System.out.println("Long:"+rd.nextLong());
System.out.println("Float:"+rd.nextFloat());
System.out.println("Double:"+rd.nextDouble());
?

运行结果:

view plaincopy to clipboardprint?
The set of random numbers:??
Integer:15731478?
Long:-6685918349244253815?
Float:0.45258975?
Double:0.7963162839600346?
The set of random numbers:
Integer:15731478
Long:-6685918349244253815
Float:0.45258975
Double:0.7963162839600346

下面来说说等概率随机数产生办法,其实这个很简单,如下函数就已经轻松实现了获得0--max-1之内的等概率随机整数:

view plaincopy to clipboardprint?
private static int getRandInt(int max){??
??? Random rd = new Random();??
??? return Math.abs(rd.nextInt()%max);??
}??
private static int getRandInt(int max){
??? Random rd = new Random();
??? return Math.abs(rd.nextInt()%max);
}?

在J2ME手机游戏开发中,经常会使用这种方式获得等概率随机整数。

但是有时在游戏编程中,我们可能需要所获取的随机数概率并不相同,比方说从怪物身上掉落的装备的概率往往是级别愈高,掉落的愈低,反正则愈高。好了让我来把问题抽象为如下编程任务:假定需要产生0到n之间(包括0和n)的随机数,并且要求产生0的概率最大,1次之,2又比1次之,以此类推,n的概率最低。问题清楚了,那么就来考虑一下算法问题,为简单起见,我让产生各个数字的概率等差递减,也就是说,各个随机数的概率之比为:n+1:n:n-1:n-2:......1,那么首先要构造一个区间,区间的下限为0,上限为各个比例数字之和,也就是(n+1)+n+(n-1)+......+1。那么,构造这样一个区间有什么用呢?首先把这个大区间划分为n+1个长度不等的区间,每个小区间的跨度和各个数字的产生概率对应,也就是[0,n](跨度为n+1),[n+1,2n](跨度为n),以此类推,因此这些小区间就代表了各个数字产生的概率。最后在大区间中生成一个等概率随机数x,x落在哪个小区间内,那么就产生代表该区间的那个数字。产生等差递减概率的随机数的思路有了,那么下面的代码就不难理解了:

view plaincopy to clipboardprint?
//获得0--n之内的不等概率随机整数,0概率最大,1次之,以此递减,n最小??
private static int getAnyRandInt(int n){??
??? int max = n+1;??
??? int bigend = ((1+max)*max)/2;??
??? Random rd = new Random();??
??? int x = Math.abs(rd.nextInt()%bigend);??
??? int sum = 0;??
??? for(int i = 0; i<max; i++){??
??????? sum += (max - i);??
??????? if(sum>x){??
??????????? return i;??
??????? }??
??? }??
??? return -1;??
}??
//获得0--n之内的不等概率随机整数,0概率最大,1次之,以此递减,n最小
private static int getAnyRandInt(int n){
??? int max = n+1;
??? int bigend = ((1+max)*max)/2;
??? Random rd = new Random();
??? int x = Math.abs(rd.nextInt()%bigend);
??? int sum = 0;
??? for(int i = 0; i<max; i++){
??????? sum += (max - i);
??????? if(sum>x){
??????????? return i;
??????? }
??? }
??? return -1;
}

最后给出我写得一个等概率随机数与不等概率随机数测试与验证程序代码:

view plaincopy to clipboardprint?
import java.util.*;??
?
public class RandomTest {??
?public static void main(String[] args){??
? Random ran1 = new Random();??
? Random ran2 = new Random(12345);??
????
? System.out.println("The 1st set of random numbers:");??
? System.out.println("Integer:"+ran1.nextInt());??
? System.out.println("Long:"+ran1.nextLong());??
? System.out.println("Float:"+ran1.nextFloat());??
? System.out.println("Double:"+ran1.nextDouble());??
????
? System.out.println("The 2nd set of random numbers:");??
? for(int i = 0; i<20; i++){??
?? if(i%5 == 0){??
??? System.out.println();??
?? }??
?? System.out.print(ran2.nextInt()+ " ");??
? }??
????
? int[] rate = new int[10];??
? System.out.println();??
? int n = 0;??
? for(int i = 0; i<200; i++){??
?? if(i%40 == 0){??
??? System.out.println();??
?? }??
?? n = getRandInt(10);??
?? rate[n]++;??
?? System.out.print(n+ " ");??
? }??
????
? displayRandRate(rate, "getRandInt等概率随机数0--9依次出现次数:");??
????
? Arrays.fill(rate, 0);??
? for(int i = 0; i<200; i++){??
?? if(i%40 == 0){??
??? System.out.println();??
?? }??
?? n = getAnyRandInt(9);??
?? rate[n]++;??
?? System.out.print(n+ " ");??
? }??
????
? displayRandRate(rate, "getAnyRandInt不等概率随机数0--9依次出现次数:");??
?}??
???
?//获得0--max-1之内的等概率随机整数??
?private static int getRandInt(int max){??
? Random rd = new Random();??
? return Math.abs(rd.nextInt()%max);??
?}??
???
?//获得0--n之内的不等概率随机整数,0概率最大,1次之,以此递减,n最小??
?private static int getAnyRandInt(int n){??
? int max = n+1;??
? int bigend = ((1+max)*max)/2;??
? Random rd = new Random();??
? int x = Math.abs(rd.nextInt()%bigend);??
? int sum = 0;??
? for(int i = 0; i<max; i++){??
?? sum += (max - i);??
?? if(sum>x){??
??? return i;??
?? }??
? }??
? return -1;??
?}??
???
?private static void displayRandRate(int rate[], String description){??
? System.out.println();??
? System.out.println();??
? System.out.println(description);??
? for(int i = 0; i<rate.length; i++){??
?? System.out.print(rate[i]+ " ");??
? }??
? System.out.println();??
?}??
}?
import java.util.*;

public class RandomTest {
?public static void main(String[] args){
? Random ran1 = new Random();
? Random ran2 = new Random(12345);
?
? System.out.println("The 1st set of random numbers:");
? System.out.println("Integer:"+ran1.nextInt());
? System.out.println("Long:"+ran1.nextLong());
? System.out.println("Float:"+ran1.nextFloat());
? System.out.println("Double:"+ran1.nextDouble());
?
? System.out.println("The 2nd set of random numbers:");
? for(int i = 0; i<20; i++){
?? if(i%5 == 0){
??? System.out.println();
?? }
?? System.out.print(ran2.nextInt()+ " ");
? }
?
? int[] rate = new int[10];
? System.out.println();
? int n = 0;
? for(int i = 0; i<200; i++){
?? if(i%40 == 0){
??? System.out.println();
?? }
?? n = getRandInt(10);
?? rate[n]++;
?? System.out.print(n+ " ");
? }
?
? displayRandRate(rate, "getRandInt等概率随机数0--9依次出现次数:");
?
? Arrays.fill(rate, 0);
? for(int i = 0; i<200; i++){
?? if(i%40 == 0){
??? System.out.println();
?? }
?? n = getAnyRandInt(9);
?? rate[n]++;
?? System.out.print(n+ " ");
? }
?
? displayRandRate(rate, "getAnyRandInt不等概率随机数0--9依次出现次数:");
?}
?
?//获得0--max-1之内的等概率随机整数
?private static int getRandInt(int max){
? Random rd = new Random();
? return Math.abs(rd.nextInt()%max);
?}
?
?//获得0--n之内的不等概率随机整数,0概率最大,1次之,以此递减,n最小
?private static int getAnyRandInt(int n){
? int max = n+1;
? int bigend = ((1+max)*max)/2;
? Random rd = new Random();
? int x = Math.abs(rd.nextInt()%bigend);
? int sum = 0;
? for(int i = 0; i<max; i++){
?? sum += (max - i);
?? if(sum>x){
??? return i;
?? }
? }
? return -1;
?}
?
?private static void displayRandRate(int rate[], String description){
? System.out.println();
? System.out.println();
? System.out.println(description);
? for(int i = 0; i<rate.length; i++){
?? System.out.print(rate[i]+ " ");
? }
? System.out.println();
?}
}

最后给出该程序某次运行的结果:

The 1st set of random numbers:??
Integer:-158150616?
Long:8776385264218048298?
Float:0.22843891?
Double:0.6794943450281173?
?
The 2nd set of random numbers:??
?
1553932502 -2090749135 -287790814 -355989640 -716867186???
161804169 1402202751 535445604 1011567003 151766778???
1499439034 -51321412 1924478780 -370025683 -1554121271???
496460768 679749574 -301730690 -992618231 1128070351???
?
7 7 5 8 8 6 9 5 6 4 5 4 3 8 2 2 3 1 4 0???
2 4 9 9 6 5 4 6 1 4 4 0 3 8 8 7 4 2 6 6???
3 1 7 8 5 1 0 3 9 4 8 6 1 5 7 7 7 8 0 9???
7 1 2 4 4 5 8 1 9 0 7 0 8 2 4 7 9 1 6 7???
4 8 9 4 4 5 2 0 2 5 2 3 4 2 2 9 1 4 7 6???
3 4 8 5 6 6 2 9 1 4 7 2 6 1 8 5 7 4 0 1???
8 2 9 4 9 3 3 6 2 8 2 6 5 0 9 3 4 6 0 1???
8 6 7 8 7 6 7 0 0 9 5 8 2 6 5 7 2 5 1 3???
9 8 7 4 7 2 2 3 1 0 4 2 0 6 1 1 4 7 4 0???
2 8 8 9 6 6 2 1 5 2 4 9 2 6 3 1 3 2 9 5???
?
getRandInt等概率随机数0--9依次出现次数:??
15 19 26 14 27 17 22 21 21 18???
?
2 5 6 9 5 2 1 3 0 4 2 4 2 8 1 3 5 0 5 7???
2 2 8 5 4 9 8 0 2 0 8 0 0 2 0 2 9 5 0 0???
2 3 1 5 0 2 1 4 2 0 7 1 0 5 8 4 3 3 7 7???
3 1 3 0 3 3 3 0 0 6 1 1 0 0 6 0 4 6 5 9???
2 0 0 4 2 6 1 3 7 2 0 1 1 3 5 1 0 4 0 4???
2 7 0 3 6 0 6 2 7 0 9 5 3 0 2 8 5 9 1 1???
1 0 5 3 4 2 5 2 1 1 4 2 2 7 7 2 8 5 0 4???
8 1 2 3 4 3 1 4 6 5 3 2 2 9 6 0 0 1 2 5???
2 9 6 2 2 2 0 2 6 5 6 8 0 0 0 1 0 3 2 6???
3 7 5 2 2 1 0 3 0 2 1 0 2 7 2 4 1 3 7 3?
?
getAnyRandInt不等概率随机数0--9依次出现次数:??
39 24 38 23 15 19 13 12 9 8??


本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/loomman/archive/2009/02/03/3861240.aspx

读书人网 >软件架构设计

热点推荐