简体   繁体   中英

Generate random numbers with different probabilities within given ranges

Is there a simple algorithm that will print results of rolling a die such that the probability of getting 1,2,3,4,5 is 1/9 and the probability of getting a 6 is 3/9.

I would like to implement this in Java and intentionally only use Math.random(), if statements, for/ while loops.

As others suggested to make the sum of all events equal to 1, then number 9 will have a probability of 4/9 to be chosen.

Generate a random number between 1 and 9, inclusive on both ends. If the number be 1 to 5, you rolled that number, otherwise, you rolled 6. Note that there are 4 chances in this scheme to roll a 6, and 5 total chances to roll 1 through 5.

Random random = new Random();
int roll = random.nextInt(9) + 1; // create a random number

if (roll > 5) {
    System.out.println("You rolled a 6");
}
else {
    System.out.println("You rolled a " + roll);
}

To simulate more dice rolls you can add the above logic inside a for loop that runs for as many loops as you want.

Generating values for random variables with a certain distribution usually works like this:

  • You have a function which generates a random 0 <= q < 1 ,
  • You apply the quantile function and you obtain the value of your variable.

In your case you have a discrete random variable. You need an instance of Random :

private static final Random random = new Random();

the values assumed by the variable:

private static final double[] values = {1.0, 2.0, 3.0, 4.0, 5.0, 6.0};

Compute the cumulative distribution function (sum of probabilities of the values up to the specific value) for these values:

private static final double[] cdf = {1.0 / 9, 2.0 / 9, 3.0 / 9, 4.0 / 9, 5.0 / 9, 1.0};

You random generating function will return the last value for which the cdf is not greater than q :

   public static double randomValue() {
      double q = random.nextDouble();
      for (int i = 0; i < values.length; i++) {
         if (q > cdf[i]) continue;
         return values[i];
      }
      throw new IllegalStateException();
   }

Seems pretty straightforward:

// Pass in an instance of class Random
public static int gen(Random r) { 
  int i = r.nextInt(9); // uniformly generate 0,...,8 inclusive
  if (i < 5) {
    return i + 1;       // returns 1,...,5 w/ probability 1/9
  } else {
    return 6;           // returns 6 w/ probability 4/9
  }
}

Warning, I no longer have a Java compiler on my machine, so I haven't compiled this. However, the algorithm is valid as confirmed in another language.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM