/* * #! * Ontopia Vizigator * #- * Copyright (C) 2001 - 2013 The Ontopia Project * #- * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * !# */ package net.ontopia.topicmaps.viz; import java.util.Iterator; import java.util.Map; import java.util.Random; import java.util.TreeMap; import net.ontopia.utils.OntopiaRuntimeException; /** * Manages probability values for given keys, so that all probability values * always add up to 1. If a new probability value is added, the other values * are added. This can be used to build up a probability distribution * incrementally while ensuring that the probabilities never add up to more * than 1, i.e. 100%. * Currently not used anywhere. * Should add a method that guesses a 0.0 ... 1.0 number and returns a * corresponding key. */ public class ProbabilityManager { private Map probabilities; Random random; boolean keysInOrder; public ProbabilityManager(Object key) { probabilities = new TreeMap(); probabilities.put(key, new Double(1)); random = new Random(); keysInOrder = false; } /** * Set key to be compKey * compFactor and adjust all values so that they still * add up to 1 and at the same time, the value of compKey remains the same * relative to other values. * @param key The key to add (may be there already, in which case it's changed * @param compKey Use the value of 'compKey' to create the value for 'key' * @param compFactor Let 'key' = 'compFactor' * 'compKey'. */ public void addProbability(Object key, Object compKey, double compFactor) { if (compFactor < 0) throw new OntopiaRuntimeException("Internal error, received negative" + " probability factor."); Double compValue = (Double)probabilities.get(compKey); double compVal = compValue.doubleValue(); // The new value of key before adjustment. double newVal = compVal * compFactor; // The old value of key. double oldVal = 0; Double oldValue = (Double)probabilities.get(key); if (oldValue != null) oldVal = oldValue.doubleValue(); // The temporarily new sum before adjusting. double sum = 1 + newVal - oldVal; // Factor that all old values should be multiplied by. double factor = 1 / sum; // Set this probability. probabilities.put(key, new Double(newVal)); // Update all other probability values so they add up to 1. Iterator keysIt = probabilities.keySet().iterator(); while (keysIt.hasNext()) { Object currentKey = keysIt.next(); Double currentValue = (Double)probabilities.get(currentKey); probabilities.put(currentKey, new Double(currentValue.doubleValue() * factor)); } } public Object guessKey() { double valueGuess = random.nextDouble(); return guessKey(valueGuess); } public Object guessKey(double valueGuess) { double cummulator = 0; Iterator keysIt = probabilities.keySet().iterator(); Object currentKey = null; while (keysIt.hasNext()) { currentKey = keysIt.next(); Double currentValue = (Double)probabilities.get(currentKey); cummulator += currentValue.doubleValue(); if (valueGuess < cummulator) return currentKey; } return currentKey; } public Double getProbability(Object key) { return (Double)probabilities.get(key); } public double getProbabilityValue(Object key) { Double probability = getProbability(key); if (probability == null) return 0; return probability.doubleValue(); } public static void test() { System.out.println("Testing ProbabilityMnager"); String key1 = "key1: "; String key2 = "key2: "; String key3 = "key3: "; String key4 = "key4: "; ProbabilityManager man = new ProbabilityManager(key1); System.out.println("-----------------------------"); System.out.println(key1 + man.getProbabilityValue(key1)); System.out.println(key2 + man.getProbabilityValue(key2)); System.out.println(key3 + man.getProbabilityValue(key3)); System.out.println(key4 + man.getProbabilityValue(key4)); man.addProbability(key2, key1, 3); System.out.println("-----------------------------"); System.out.println(key1 + man.getProbabilityValue(key1)); System.out.println(key2 + man.getProbabilityValue(key2)); System.out.println(key3 + man.getProbabilityValue(key3)); System.out.println(key4 + man.getProbabilityValue(key4)); man.addProbability(key2, key1, 2); System.out.println("-----------------------------"); System.out.println(key1 + man.getProbabilityValue(key1)); System.out.println(key2 + man.getProbabilityValue(key2)); System.out.println(key3 + man.getProbabilityValue(key3)); System.out.println(key4 + man.getProbabilityValue(key4)); man.addProbability(key3, key2, 2); System.out.println("-----------------------------"); System.out.println(key1 + man.getProbabilityValue(key1)); System.out.println(key2 + man.getProbabilityValue(key2)); System.out.println(key3 + man.getProbabilityValue(key3)); System.out.println(key4 + man.getProbabilityValue(key4)); System.out.println("0.0: " + man.guessKey(0.0)); System.out.println("0.1: " + man.guessKey(0.1)); System.out.println("0.2: " + man.guessKey(0.2)); System.out.println("0.3: " + man.guessKey(0.3)); System.out.println("0.4: " + man.guessKey(0.4)); System.out.println("0.5: " + man.guessKey(0.5)); System.out.println("0.6: " + man.guessKey(0.6)); System.out.println("0.7: " + man.guessKey(0.7)); System.out.println("0.8: " + man.guessKey(0.8)); System.out.println("0.9: " + man.guessKey(0.9)); System.out.println("1: " + man.guessKey(1)); System.out.println("0.0: " + man.guessKey(0.0)); System.out.println("0.1: " + man.guessKey(0.1)); System.out.println("0.2: " + man.guessKey(0.2)); System.out.println("0.3: " + man.guessKey(0.3)); System.out.println("0.4: " + man.guessKey(0.4)); System.out.println("0.5: " + man.guessKey(0.5)); System.out.println("0.6: " + man.guessKey(0.6)); System.out.println("0.7: " + man.guessKey(0.7)); System.out.println("0.8: " + man.guessKey(0.8)); System.out.println("0.9: " + man.guessKey(0.9)); System.out.println("1: " + man.guessKey(1)); int key1Count = 0; int key2Count = 0; int key3Count = 0; int iterations = 1000000; for (int i = 0 ; i < iterations; i++) { if (man.guessKey() == key1) key1Count++; if (man.guessKey() == key2) key2Count++; if (man.guessKey() == key3) key3Count++; } System.out.println("Key1Count: " + key1Count + ", " + ((double)key1Count)/iterations); System.out.println("Key2Count: " + key2Count + ", " + ((double)key2Count)/iterations); System.out.println("Key3Count: " + key3Count + ", " + ((double)key3Count)/iterations); } }