Custom probability distribution in Java

I have a set of integers, each of which has a certain probability obtained from earlier experiments, for example:

0 = 0.5
1 = 0.2
2 = 0.3

According to the specifications of the probability distribution, these weights add up to 1.0. Now I'm looking for an effective way to select one of the values ​​when taking these probabilities into account, for example. (Pseude code):

Distribution distribution = new CustomDistribution(new double[]{0.5, 0.3, 0.2});
distribution.sample();

This should result in half the time according to the given numbers. However, do not assume any patterns or patterns between them.

I used Apache Commons Math for my previous experiments, but it doesn't seem to provide a solution for this scenario, Colt .

, , . , . .

+4
3

:

class Distribution<T>{
    List<Double> probs = new ArrayList<>();
    List<T> events = new ArrayList<>();
    double sumProb;
    Random rand = new Random();

    Distribution(Map<T,Double> probs){
        for(T event : probs.keySet()){
            sumProb += probs.get(event);
            events.add(event);
            this.probs.add(probs.get(event));
        }
    }

    public T sample(){
        T value;
        double prob = rand.nextDouble()*sumProb;
        int i;
        for(i=0; prob>0; i++){
            prob-= probs.get(i);
        }
        return events.get(i-1);
    }
}

, , . . , , , , , .

+1

, .

r [0, 1),

if (r <= 0.5/*micro-optimisation: most likely case first*/){
    return 0;
} else if (r <= 0.8/*then the next most likely case*/){
    return 2;
} else {
    return 1;
}

, , .

( , - , , ).

+4

The challenge Random.nextDouble()is a rather expensive operation. You better use Random.nextInt(n)in this case

int num = rand.nextInt(10);
return num <= 5 ? 0 : num <= 8 ? 1 : 2;
+2
source

All Articles