题目:随机产生5个数,这5个数每个数的范围都在[10,35]之间,5个数的和是定值100,尽量让5个数的概率随机,写出算法??
如,原来a,b,c,d,e都是20,随机后变成a=34b=29c=11d=10e=16,但是他们之和还是100,再次随机后a=11b=21c=13d=28e=27,他们的和还是100。
我的解决思路是,第一个数和第二个数在[10,35]中随机,后面的数随机要满足一定的条件:保证它之后的数随机后能在[10,35]之间,极端不满足的情况是前两个数都随机到35,那么后面的三个数只能都是10了,所以第三个数随机的时候要满足(100-a-b-c)/2>10||(100-a-b-c)/2<35,否则就要重新随机。第四个数跟第三个数的处理方式一样,第五个数是个用100减去前四个数就行。以下是我的实现:
public static void random(){
Random r = new Random();
int b,c,d,e;
int a = r.nextInt(25)+10;
b = r.nextInt(25)+10;
c = r.nextInt(25)+10;
while((100-a-b-c)/2<10||(100-a-b-c)/2>35){
c = r.nextInt(25)+10;
}
d = r.nextInt(25)+10;
while((100-a-b-c-d)<10||(100-a-b-c-d)>35){
d = r.nextInt(25)+10;
}
e = 100-a-b-c-d;
System.out.println("a="+a+"b="+b+"c="+c+"d="+d+"e="+e);
}
这里又想起一个有关随机的题目:给定一个函数rand5(),该函数可以随机生成1-5的整数,且生成概率一样。现要求使用该函数构造函数rand7(),使函数rand7()可以随机等概率的生成1-7的整数。
要保证rand7的等概率,就不能利用rand5() + rand()%3来实现rand7()函数,可以这样思考,首先构造一个1到n的等概率随机函数randn(),其中n>7,这样在randn函数内1-7之间的数肯定也是等概率的,把大于7的数丢弃就ok了。以下是我的代码:
//通过rand5随机1-7之间的数
public static int rand7(){
int t = rand5()+(rand5()-1)*5;
while(t>22){
t = rand5()+(rand5()-1)*5;
}
return t%7+1;//这里把7的整数倍也用求余的方式映射到1-7.
}
//随机1-5之间的数
public static int rand5(){
Random r = new Random();
int i = r.nextInt(5)+1;
return i;
}
这里又有一个更普遍的题目,通过randn()函数随机randm()函数,randn是等概率随机1-n之间的数,randm是等概率随机1-m之间的数。跟上面的思路一样,很容易写出代码:
//通过randn随机1-m之间的数。
public static int randm(int n,int m){
int t = n*n;
int i=1;
int max = (t/m)*m;
int s = randn(n)+(randn(n)-1)*n;
while(s>(max+1)){
s = randn(n)+(randn(n)-1)*n;
}
return s%m+1;
}
//随机1-n之间的数
public static int randn(int n){
Random r = new Random();
int i = r.nextInt(n)+1;
return i;
}