jeudi 24 mars 2016

Selecting a value based on percentages

I need to select a value based on a percentage chance of that value being selected. For example:

  • 10% of the time increment value a
  • 20% of the time increment value b
  • 30% of the time increment value c
  • 40% of the time increment value d

The percentages will always add up to exactly 100%

I have encountered several solutions like this one, but have determined that they cannot possibly be correct. Here is a sample program built using the solution mentioned:

import java.util.Random;

public class Main {

    private static Random r = new Random();

    public static void main(String[] args) {
        final int iterations = 1000000;
        System.out.println("Testing percentage based random, " + iterations + " iterations");
        int onePercent = 0;
        int sixPercent = 0;
        int sevenPercent = 0;
        int thirtySixPercent = 0;
        int fiftyPercent = 0;
        // Those values add up to 100% overall
        for (int i = 0; i < iterations; i++) {
            int random = r.nextInt(100);
            if (random < 1) {
                onePercent++;
                continue;
            }
            if (random < 6) {
                sixPercent++;
                continue;
            }
            if (random < 7) {
                sevenPercent++;
                continue;
            }
            if (random < 36) {
                thirtySixPercent++;
                continue;
            }
            if (random < 50) {
                fiftyPercent++;
                continue;
            }
            // That can't be right because if random > 50 then nothing at all happens
        }
        System.out.println("One percent happened about " + (onePercent / Float.valueOf(iterations)) * 100 + "% of the time");
        System.out.println("Six percent happened about " + (sixPercent / Float.valueOf(iterations)) * 100 + "% of the time");
        System.out.println("Seven percent happened about " + (sevenPercent / Float.valueOf(iterations)) * 100 + "% of the time");
        System.out.println("Thirty six percent happened about " + (thirtySixPercent / Float.valueOf(iterations)) * 100 + "% of the time");
        System.out.println("Fifty percent happened about " + (fiftyPercent / Float.valueOf(iterations)) * 100 + "% of the time");
    }
}

Output:

Testing percentage based random, 1000000 iterations
One percent happened about 0.99649996% of the time
Six percent happened about 4.9925% of the time
Seven percent happened about 1.0029999% of the time
Thirty six percent happened about 29.001299% of the time
Fifty percent happened about 14.0191% of the time

Expected output:

Testing percentage based random, 1000000 iterations
One percent happened about 0.99649996% of the time
Six percent happened about 6.9925% of the time
Seven percent happened about 7.0029999% of the time
Thirty six percent happened about 36.001299% of the time
Fifty percent happened about 50.0191% of the time

I believe I need to use some sort of algorithm to convert the percentages into a scale from 0 to 99 so that the random number generator can select a value accurately. I cannot think of how to do that, though.




Aucun commentaire:

Enregistrer un commentaire