这是我在百度看到的一个题。要实现一个算法:生成n个0~1之间的随机数,并且它们的和为1,不知道怎么弄?我写了一个算法是这样的,但是老是算不出来,看来要指定和为1的确很难找到。
我的程序源码如下(谁有更好的方法?感觉我的算法不太科学): import java.util.*;
public class random
{
public static void main(String[] args)
{ double random=0.0,sum=0.0;
double a[]=new double[10];//这里的n为10
for(int i=0;i<9;i++)//先算前面9个
{ do
{
sum-=random;//如果sum>=1,则减去random
random = Math.random();
sum+=random;
}while(sum>=1);
a[i]=random;
sum+=random; //进入上面的do-while循环时要减去random,所以在这要先加上一个random
} do
{
sum-=random;//for循环退出之时多加了一次random
random = Math.random();
sum+=random;
}while(sum!=1);
a[9]=random;
for(int i=0;i<10;i++)
System.out.println(a[i]);
}
}
我的程序源码如下(谁有更好的方法?感觉我的算法不太科学): import java.util.*;
public class random
{
public static void main(String[] args)
{ double random=0.0,sum=0.0;
double a[]=new double[10];//这里的n为10
for(int i=0;i<9;i++)//先算前面9个
{ do
{
sum-=random;//如果sum>=1,则减去random
random = Math.random();
sum+=random;
}while(sum>=1);
a[i]=random;
sum+=random; //进入上面的do-while循环时要减去random,所以在这要先加上一个random
} do
{
sum-=random;//for循环退出之时多加了一次random
random = Math.random();
sum+=random;
}while(sum!=1);
a[9]=random;
for(int i=0;i<10;i++)
System.out.println(a[i]);
}
}
/*
这是我在百度看到的一个题。要实现一个算法:生成n个0~1之间的随机数,并且它们的和为1,不知道怎么弄?我写了一个算法是这样的,但是老是算不出来,看来要指定和为1的确很难找到。
我的程序源码如下(谁有更好的方法?感觉我的算法不太科学):
*/
public class random {
public static void main(String[] args) {
double random=0.0,sum=0.0;
double a[]=new double[10];//这里的n为10
int k=a.length-1,i=0;
for(i=0;i<k;i++) {//先算前面 n-1 个
a[i] = Math.random()/k;
sum+=a[i];
}
a[k] =1-sum;
for(i=0;i<a.length;i++)
System.out.println(a[i]);
}
}
double sum = 0.0d;
for (int i = 0; i < n-1; i ++){
double d = Math.random();
double d1 = 1.0d/((double)n);
while (Math.abs(d - d1) > 10E-5){
d = Math.random();
}
sum += d;
System.out.println(d);
}
double lastDouble = 1.0d-sum;
System.out.println(lastDouble);
}给你一种方法:
首先声称前n-1个随机数,
但确保他们大小在double d1 = 1.0d/((double)n)附近,
因此while (Math.abs(d - d1) > 10E-5){
d = Math.random();
}
最后取double lastDouble = 1.0d-sum;
测试结果的其中一种结果如下:
test(100);0.005401852415736985
0.007238905733729428
0.00914994521089374
0.0065726320346013445
0.006262056640117364
0.009149772079639407
0.009124828145384067
0.008329519083124404
1.9036469814825985E-5
0.003411262096715495
0.0016568489695042432
0.0036205781538289905
0.003606200935273529
0.0017377213770860545
0.001276435750549032
8.571387283955456E-4
0.0022025691822334936
0.0051338969075483964
9.414137566280401E-4
0.005871339571385303
1.4989237384233078E-4
0.008602899512980988
0.00824695336219583
0.006216640347343594
0.0015003250946344915
0.007625928635693446
0.0064554355825349186
0.0010700600267189442
0.004446857557857897
0.006335653676885156
0.001607710220158598
0.006495481647227019
9.550474587349811E-5
0.002284763342130791
0.004006786631776338
0.00784946523152541
0.0020822982289318004
3.026600176821992E-4
0.003291027047611861
0.006256367239282579
8.661340847533339E-4
0.001880560169257084
0.0025748051859726395
0.00605089005025905
0.005341771155117914
0.0076730194538707774
0.006374652673799108
2.6492932226518384E-4
0.0010660204960371011
0.0055545271440001764
8.693380312798649E-4
0.008503342267232927
0.0046163841713543485
0.009765792535789575
0.0015545709379274353
0.008274187154220902
0.0069417585848583485
0.008876606470033077
0.004889775613995173
2.1708128145681016E-4
0.002835273682963879
0.0028216285514347517
0.003259711506303109
0.0073621113821504824
0.009038050561268607
0.002077086578478715
0.0056721666637779
0.008823303586495301
0.0037689644780261045
0.0017323140115800273
2.955332116146847E-4
0.0015064218632779847
0.0030227464503282953
0.004439607509985843
7.363739183016138E-4
0.0018832629173352045
0.0040537347422342496
0.006249811021215912
0.0019425499296972237
0.002948476107037301
0.006923864505900212
0.005172521108589567
0.009158628168512095
0.0030965753117928596
0.0090712354012088
0.0021350401458178903
0.008222143176345509
0.0036884101734798724
0.009142766718656659
0.006153674019508393
0.006873941834077968
0.005998028599803029
0.0036993026298905995
0.00589953784150421
4.38828064218022E-4
0.005386599506964518
0.008674927424776602
0.0035245590093201384
0.009302124199223938
0.5443253529383437
看了daniel_kaka(卡卡) 的说明才想说这可能是变通的方法,呵呵,不过这样最后一个值就不算是随机是生成了。
public void genRan(int n)
{
double d,d1,sum=0.0;
for(int i=0;i<n-1;i++)
{
d = Math.random();
d1 = (1.0/((double)n))*d;
sum += d1;
System.out.println("d1:"+d1);
}
//System.out.println("sum:"+sum);
d = 1.0 - sum;
//System.out.println("d:"+d);
}
public class Test
{
int count=0;
Random randomobj;
Test()
{
randomobj = new Random() ;
}
void display()
{
double sum =0.0;
int i ;
double num[] = new double[10];
do{
for( i=0;i<num.length ;i++)
{
num[i] = randomobj.nextDouble() ;
}
for(i = 0;i<num.length ;i++)
{
sum += num[i];
}
count++;
System.out.println("共计算 "+count+" 次");
for(i = 0;i<num.length ;i++)
{
System.out.println(num[i]);
}
}while(sum != 1); }
public static void main(String[] args) {
Test numberobj = new Test() ;
numberobj.display() ;
}
}
double temp = 0.0;
int count = 0;
while(sum < 1) {
temp = Math.random();
sum += temp;
if( sum <= 1 ) {
System.out.println( " count = " + count + ", temp = " + temp );
}
count++;
}
if(sum > 1) {
sum = sum - temp;
double lastdouble = 1 - sum;
System.out.println( " count = " + --count + ", lastdouble = " + lastdouble );
}
final int n = 10; int[] intAry = new int[n];
double[] ary = new double[n];
Random rand = new Random(); final int MAX = 1000000; double total = 0;
for (int i = 0; i < n; i++) {
intAry[i] = rand.nextInt(MAX);
total += intAry[i];
} for (int i = 0; i < n; i++) {
ary[i] = 1.0 * intAry[i] / total;
} for (int i = 0; i < n; i++)
System.out.println(ary[i]); double x = 0;
for (int i = 0; i < n; i++) {
x += ary[i];
}
System.out.println("total=" + x);
ls方法不错~先生成N个随机数,然后求和sum,
那么最终的n个随机数就是Ni/sum~
然后求和,得SUM
再将每个数除以SUM
得到的就是和为1的N个随即数。
double remain = 1.0d;
double [] result = new double[n];
for(int i=0;i<n - 1;i++){
double random = Math.random();
result[i] = random * remain;
remain -= result[i];
}
result[n-1] = remain;
return result;
}