在Java中,为BirthdayParadox运行增加了100

时间:2017-02-10 16:41:17

标签: java

我正在用Java编写一个Birthday Paradox程序。我无法使用for循环来增加100的设置,以使其达到10000的最大设置。每次运行for循环时,它都会在一组中运行1000个实验。

/**
* The class  BirthdayParadox is used to
* simulated the so-called Birthday paradox, and uses
* the class Statistics to store the results of
* the experiments.
*/

public class BirthdayParadox {


/** 
    * Random generator 
    */
private static java.util.Random generator = new java.util.Random();

/**
* Instance of the class Statistics
*/
private static Statistics stats;

/** 
    * Runs the series of experiments, and stores the result into
    * a Statistics object
    * 
    * @param range the size of the set from which random number are drawn
    * @param numberOfRuns the number of experiments to run
 *
 * @return a reference to a Statistics instance that holds the result
 * of the experiment
    */
public static Statistics runExperiments(int range, int numberOfRuns) {
     for (int i=0;i<numberOfRuns;i++) {
            stats.updateStatistics(oneRun(range));
     }
     return stats;
}

/** 
    * Runs a single experiment.
    * The parameter range defines the size of the set from which
    * the experiment is drawn
    * 
    * @param range the size of the set from which random number are drawn
    *
 * @return the number of random draw in the set that the method 
 * used before drawing the same element for the second time
    */

private static int oneRun(int range){
     int counter=0;
     boolean foundTwice=false;
     int[] numberFound=new int[range];
     int number=0;
     while (foundTwice==false) {
            number=generator.nextInt(range);
            if (numberFound[number]==1) {
                foundTwice=true;
            }
            numberFound[number]++;
            counter++;
     }
     return counter;
}


/** 
 * Main method. Runs the experiments numberOfRunstimes,
 * with increasingly large sets (increment in size:step).
 * Stop once the size reaches max.
 * plots the result.
 * 
 * @param args if not empty, contains the runtime values for
 * step, max and numberOfRuns
 */

public static void main(String[] args) {
     if (args.length>1) {
            stats = new Statistics(Integer.parseInt(args[1]));
            stats = runExperiments(Integer.parseInt(args[0]), Integer.parseInt(args[1]));
            System.out.println(stats);
     }
     else {
        stats = new Statistics(10000);
        for (int i=100;i<10001;i+=100) {
            //stats = runExperiments(i,10000);
        }
            System.out.println(stats);
     }
}
}

我不断获得ArrayIndexOutOfBoundsException 10000

这是我的统计类:

/**
 * The class  Statistics accumulates the results of
 * the experiments. It know ahead of time how many experiments
 * will be run, and provides at the end the min, the max, the
 * average and the standard deviation for the data.
 *
 * this class should not use classes such as Array, 
 * Lists etc. to store the data, only prinitive types 
 * and java arrays.
 */
public class Statistics {

    public static int numberOfRuns;
    public static int[] stats;
    public static int i=0;
    public static int tmp;
    public static int minimum=999999999;
    public static int maximum=0;

    /** 
     * Constructor.
     * 
     * @param numberOfRuns the number of experiments that will be run
     */
    public  Statistics(int numberOfRuns){
        this.numberOfRuns=numberOfRuns;
        stats=new int[numberOfRuns];
    }

    /** 
     * Updates statistics after one experiment.
     * This method cannot be called more times than the 
     * paramter that was passed in the constructor. If
     * it is, an error message should be printed and
     * no change should occur.
     *   @param value the result of the new experiment
     */
    public void updateStatistics(int value) {
        stats[i]=value;
        tmp=stats[i];
        if (tmp<minimum) {
            minimum=tmp;
        }
        if (tmp>maximum) {
            maximum=tmp;
        }
        i++;
    }


    /** 
     *   @return the current average of the values passed
     * to the method updateStatistics
     */
    public double average(){
        double average=0.0;
        for (int i=0;i<numberOfRuns;i++) {
            average+=stats[i];
        }
        average/=numberOfRuns;
        average*=100;
        average=Math.round(average);
        average/=100;
        return average;
    }


    /** 
     *   @return the current standard deviation of the values passed
     * to the method updateStatistic
     */
    public double standardDeviation(){
        double standardDeviation=0.0;
        double average=average();
        for (int i=0;i<numberOfRuns;i++) {
            standardDeviation+=Math.pow(stats[i]-average, 2);
        }
        standardDeviation/=numberOfRuns;
        standardDeviation=Math.sqrt(standardDeviation);
        standardDeviation*=100;
        standardDeviation=Math.round(standardDeviation);
        standardDeviation/=100;
        return standardDeviation;
    }

    /** 
     *  @return Returns the complete statistics information:
     * current minimum, current maximim, current average and
     * current standard deviation. For the last two, only two 
     * digits decimals are shown
     */
    public String toString(){

        return "We have run " + numberOfRuns + " experiments. \nThe minimum was: "+ minimum + "\nThe maximum was: " + maximum + "\nThe mean was: "+ average() + "\nThe standard deviation was: " + standardDeviation();
    }

}

1 个答案:

答案 0 :(得分:-1)

heading1 heading2 data data data heading1 heading2 heading1 heading2 data data data - 您是否为10000个元素创建数组?如果是 - 我猜你从0到9999将它们编入索引。 按照你的stats = new Statistics(10000);循环,最后一个要处理的元素是10000,但你还没有这样的元素。

可能for会解决问题

UPD: 如果stats = new Statistics(10001);大于或等于range(在numberOfRuns方法中),您也可以获得异常,您可能需要在此处添加验证/先决条件。

oneRun(10000)可能返回值2..10001(含)(!)

可能你想在这里打破循环:

runExperiments