Random number with Probabilities

前端 未结 12 2232
醉梦人生
醉梦人生 2020-11-27 02:56

I am wondering what would be the best way (e.g. in Java) to generate random numbers within a particular range where each number has a certain probability to occur or not?

12条回答
  •  醉酒成梦
    2020-11-27 03:29

    Some time ago I wrote a helper class to solve this issue. The source code should show the concept clear enough:

    public class DistributedRandomNumberGenerator {
    
        private Map distribution;
        private double distSum;
    
        public DistributedRandomNumberGenerator() {
            distribution = new HashMap<>();
        }
    
        public void addNumber(int value, double distribution) {
            if (this.distribution.get(value) != null) {
                distSum -= this.distribution.get(value);
            }
            this.distribution.put(value, distribution);
            distSum += distribution;
        }
    
        public int getDistributedRandomNumber() {
            double rand = Math.random();
            double ratio = 1.0f / distSum;
            double tempDist = 0;
            for (Integer i : distribution.keySet()) {
                tempDist += distribution.get(i);
                if (rand / ratio <= tempDist) {
                    return i;
                }
            }
            return 0;
        }
    
    }
    

    The usage of the class is as follows:

    DistributedRandomNumberGenerator drng = new DistributedRandomNumberGenerator();
    drng.addNumber(1, 0.3d); // Adds the numerical value 1 with a probability of 0.3 (30%)
    // [...] Add more values
    
    int random = drng.getDistributedRandomNumber(); // Generate a random number
    

    Test driver to verify functionality:

        public static void main(String[] args) {
            DistributedRandomNumberGenerator drng = new DistributedRandomNumberGenerator();
            drng.addNumber(1, 0.2d);
            drng.addNumber(2, 0.3d);
            drng.addNumber(3, 0.5d);
    
            int testCount = 1000000;
    
            HashMap test = new HashMap<>();
    
            for (int i = 0; i < testCount; i++) {
                int random = drng.getDistributedRandomNumber();
                test.put(random, (test.get(random) == null) ? (1d / testCount) : test.get(random) + 1d / testCount);
            }
    
            System.out.println(test.toString());
        }
    

    Sample output for this test driver:

    {1=0.20019100000017953, 2=0.2999349999988933, 3=0.4998739999935438}
    

提交回复
热议问题