rt,不要产生太多的0值

解决方案 »

  1.   

    N>5000,N个数的和为1?N个大于5000的数之合怎么会为1,不明白?
      

  2.   

    /**
     * 2005-12-18
     */
    package com.beihehuaiyu.csdn;/**
     * @author 被褐怀玉
     * @author [email protected]
     * @author 做一个幸福的人,甘于辛勤、奋斗一生,最后可以温暖地死去
     *
     */
    public class NRandomNum {
    private static final int N = 5000;

    private int n;
    private double sum;


    public int getN() {
    return n;
    }
    public void setN(int n) {
    this.n = n;
    }
    public double getSum() {
    return sum;
    }
    public void setSum(double sum) {
    this.sum = sum;
    }

    private double getNextNum(){


    double result = 0;



    result = Math.random();
    boolean sumIsSmallerThanOne = ((getSum() + result) < 1);
    boolean sumIsNotBiggerOne = ((getSum() + result) <= 1);

    /**
     * 如果小于5000个随机数,则新随机数与现所有随机数之和的和必须要小于1
     */
    if(getN()<N){
    while(!sumIsSmallerThanOne){
    result = Math.random();

    sumIsSmallerThanOne = ((getSum() + result) < 1);

    }
    }
    /**
     * 如果大于5000个随机数,则新随机数与现所有随机数之和的和必须要小于或者等于1
     */
    else{
    while(!sumIsNotBiggerOne){
    result = Math.random();

    sumIsNotBiggerOne = ((getSum() + result) <= 1);

    }

    }


    return result;
    }

    public void getAllNums(){
    int line = 0;
    boolean sumIsOne = (getSum()==1);
    while(!sumIsOne){
    /**
     * 更新计数器
     */
    setN(n + 1);

    /**
     * 取得新随机数
     */
    double nextNum = getNextNum();

    /**
     * 将新随机数的值加到sum中来
     */
    setSum(getSum() + nextNum);

    /**
     * 判断这些随机数的和是否为1
     */
    sumIsOne = (getSum()==1);

    System.out.print(nextNum + "  ");

    line += 1;

    if((line % 10) == 0){
    System.out.println();
    }


    }

    }
    /**
     * @param args
     */
    public static void main(String[] args) {
    NRandomNum nr = new NRandomNum();

    nr.getAllNums(); }

    }
      

  3.   

    生成一个随机数a[1]a[1]<1,生成第n个随机数
    a[n] < 1-(a[1]+a[2]+a[3]+...+a[n-1])然后最后一个随机数等于1减去前面4999个的差当然,这个不是完全随机的,
    这5000个数,你再打乱顺序,就OK了
      

  4.   

    谢谢 beihehuaiyu(被褐怀玉(甘吾食 美吾服 安吾居 乐吾俗)) 
    我就是这个意思。等ok了就送分。
      

  5.   

    再补充一种改进策略。
    a[0]=random;
    a[1]取1-random中的random;
    重复直到a[4998];
    最后的a[4999]=1-a[0]-……-a[4998];这样可能更符合你的要求,收敛速度也应该会让人满意,只要注意这个随机数不要无规律地随便取,结果都会不错。
      

  6.   

    第一个随机用Random生成,然后其后的N2-N4998自己写个随机的规则(比如取时间什么的)生成一个数n,用1/n乘以前一个数得到新的随机数。由于第一个数是随机的,后4998个数也是根据随机规则生成的小数乘以前一个数得到,故可以保证其和必然小于1,最后用1减,保证5000个数的合必然等于1。就这么简单
      

  7.   

    先生成N-1个随机数,第N个数自己求(1-前N-1个数的和),这样效率高点。
    因为前N-1个数为随机数,所以(1-前N-1个数的和)也是随机的(当然了,在前N-1个数确定的情况下就不随机了)
      

  8.   

    算法如下
    a[1] = random  //random 产生0到1的随机数
    sum = a[1]
    a[2] = random*(1-sum)
    sum += a[2]a[r] = random*(1-sum)
    sum += a[r]a[n-1] = random*(1-sum)
    sum += a[n-1];a[n] = 1-sum
      

  9.   

    package src;import java.util.Arrays;public class NewFrequency { private final static long multiplier = 0x5DEECE66DL;
    private final static long adder = 0xBL;
    private final static long mask = (1L<<48)-1;
    /**
     * @param args
     */
    long seed = System.currentTimeMillis();
    public int randomon(int n){

    if (n <= 0)
    throw new IllegalArgumentException("n must be positive");
    seed = (seed * multiplier + adder) & mask;
    return ((int)(seed >>> 17) % n);
    }

    public int[] NewFrequency1(int column_card,int table_card){
    int list_frq[] = new int[column_card];
    int table_card1 = (int)(table_card/10);  int column_card1= (int)(column_card/10);
    for(int i=0;i<column_card1;i++){
    list_frq[i] = randomon(table_card);
    } for(int i=column_card1;i<column_card;i++){

    list_frq[i]=randomon(table_card1);
    } Arrays.sort(list_frq);
    return list_frq;
    }

    public static void main(String[] args) {
    int a = 500;
    int b = 10000;
    int[] num_list = new int[a];
    NewFrequency aa = new NewFrequency();
    num_list = aa.NewFrequency1(a,b); long sum = 0;
    for(int i=0;i<a;i++){
    sum = sum + num_list[i];
    System.out.println(num_list[i]);
    }
    System.out.println(sum);
    System.out.println((float)num_list[0]/(float)sum);
    float[] freq = new float[a];
    float ttt=0;
    for(int i =0;i<a;i++){
    freq[i]=(float)((float)num_list[i]/(float)sum);
    System.out.println(freq[i]);
    ttt = ttt+freq[i];
    }

    System.out.println(ttt);
    }}自己写的一个。不过生成的数字都很平均
      

  10.   

    必须严格控制随机数的选取规则,否则一定会溢出,我按照我的第二种策略去测试,发现在取237个数的时候,剩下来的和已经不到E-100,而double型最小值为E-308,估计在第800个数左右就会只能取0了。第一种很有效,不过结果却很平均。
      

  11.   

    public class Sandbox
    {
        static int MAX = 5001;
        public static void main(String[] args)
        {
            double[] numbers = new double[MAX];
            double count = 0;
            for(int i = 0; i < MAX - 1; i ++){
                numbers[i] = Math.random() / (MAX - 1);
                count += numbers[i];
            }
            numbers[MAX - 1] = 1 - count;
        }
    }