这是我在百度看到的一个题。要实现一个算法:生成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]); 

}

解决方案 »

  1.   

    import java.util.*; 
    /*
    这是我在百度看到的一个题。要实现一个算法:生成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]);
        }
    }
      

  2.   

    public static void test(int n){
      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
      

  3.   

    开始的时候想说既然都是随机数,怎么可能还规定和==1。呵呵。
    看了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);

    }
      

  4.   

    既然前面n-1个是随机的,他们总和是定值,所以最后一个也算是随机的了~1-m 其中m是变值,难道你能说1-m是定值吗?
      

  5.   

    看看这个吧,我觉得没问题,都是随机的,不过计算好多次要,我的内存小,就没有等它试完,估计这样可以的。import java.util.Random;
    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() ;
        }
    }
      

  6.   

    double sum = 0;
            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 );
            }
      

  7.   

    接分
    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);
      

  8.   


    ls方法不错~先生成N个随机数,然后求和sum,
    那么最终的n个随机数就是Ni/sum~
      

  9.   

    先随便生成N个随即数,
    然后求和,得SUM
    再将每个数除以SUM
    得到的就是和为1的N个随即数。
      

  10.   

    public static double [] getRandom(int 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;
        }