hjvgy
10/11/2018 - 6:25 AM

DistributedRandomValueGenerator

import java.util.LinkedHashMap;

public class Main
{
    public static void main(String[] args)
    {
        DistributedRandom random = new DistributedRandom();
        LinkedHashMap<Integer, Integer> test = new LinkedHashMap<>();
        int threshold = 10000;
        int ab_max = 10;
        test.put(1, 0);
        
        for (int ab = 2; ab <= ab_max; ab++)
        {
            for(int n=1; n<=ab; n++)
                random.addValue(n, (float) 2 * n / (ab * (ab + 1)));
            
            while (test.getOrDefault(ab, 0) < threshold)
            {
                int value = random.getDistributedRandomValue();
                test.put(value, test.getOrDefault(value, 0) + 1);
            }
        }
        System.out.println(test.toString());
    }
}
import java.util.HashMap;

public class DistributedRandom
{
    private HashMap<Integer, Float> distribution = new HashMap<>();
    private float probability_sum;

    public void addValue(int value, float probability)
    {
        if (distribution.containsKey(value))
            probability_sum -= distribution.get(value);
        distribution.put(value, probability);
        probability_sum += probability;
    }

    public int getDistributedRandomValue()
    {
        float norm_random = (float) Math.random() * probability_sum;
        float current_sum = 0;
        for (int i : distribution.keySet())
        {
            current_sum += distribution.get(i);
            if (norm_random <= current_sum) return i;
        }
        return 0;
    }
}
import java.util.HashMap;

public class Example
{
    public static void main(String[] args)
    {
        DistributedRandom dr = new DistributedRandom();
        dr.addValue(1, 0.2f);
        dr.addValue(2, 0.3f);
        dr.addValue(3, 0.5f);
        
        int testCount = 1000000;
        HashMap<Integer, Float> test = new HashMap<>();
        for (int i = 0; i < testCount; i++)
        {
            int value = dr.getDistributedRandomValue();
            test.put(value, test.getOrDefault(value, 0f) + 1f / testCount);
        }
        System.out.println(test.toString());
    }
}