You can try using a navigation map with probability distribution. Unlike regular maps, NaviableMap defines the absolute order over its keys. And if the key is not on the map, it can tell you which is the closest key, or which is the smallest key, which is greater than the argument. I used ceilingEntry , which returns a map entry with the smallest key that is greater than or equal to the given key.
If you use TreeMap as your implementation of NavigableMap, then a distribution search with many classes will be faster because it performs a binary search rather than starting with the first key and then checking each key in turn.
Another advantage of NaviableMap is that you get a data class that you are directly interested in, and not an index to another array or list that can make the code clean.
In my example, I used BigDecimals, since I donβt particularly like using floating point numbers, since you cannot specify the precision you need. But you can use floats or doubles or something else.
import java.math.BigDecimal; import java.math.RoundingMode; import java.util.Arrays; import java.util.NavigableMap; import java.util.TreeMap; public class Main { public static void main(String[] args) { String[] classes = {"A", "B", "C", "D"}; BigDecimal[] probabilities = createProbabilities(classes.length); BigDecimal[] distribution = createDistribution(probabilities); System.out.println("probabilities: "+Arrays.toString(probabilities)); System.out.println("distribution: "+Arrays.toString(distribution)+"\n"); NavigableMap<BigDecimal, String> map = new TreeMap<BigDecimal, String>(); for (int i = 0; i < distribution.length; i++) { map.put(distribution[i], classes[i]); } BigDecimal d = new BigDecimal(Math.random()); System.out.println("probability: "+d); System.out.println("result: "+map.ceilingEntry(d).getValue()); } private static BigDecimal[] createDistribution(BigDecimal[] probabilities) { BigDecimal[] distribution = new BigDecimal[probabilities.length]; distribution[0] = probabilities[0]; for (int i = 1; i < distribution.length; i++) { distribution[i] = distribution[i-1].add(probabilities[i]); } return distribution; } private static BigDecimal[] createProbabilities(int n) { BigDecimal[] probabilities = new BigDecimal[n]; for (int i = 0; i < probabilities.length; i++) { probabilities[i] = F(i+1, n); } return probabilities; } private static BigDecimal F(int i, int n) {
Dunes source share