/* * (c) 2008- RANDI2 Core Development Team * * This file is part of RANDI2. * * RANDI2 is free software: you can redistribute it and/or modify it under the * terms of the GNU General Public License as published by the Free Software * Foundation, either version 3 of the License, or (at your option) any later * version. * * RANDI2 is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along with * RANDI2. If not, see <http://www.gnu.org/licenses/>. */ package de.randi2.simulation.distribution; import java.io.Serializable; import java.util.ArrayList; import java.util.List; import lombok.Getter; import de.randi2.utility.Pair; /** * Represented the concrete distribution. The elements you get with the * getNextValue() method are concrete distributed. * * @author Daniel Schrimpf <ds@randi2.de> * * @param <E> The type of the elements. */ public class ConcreteDistribution<E extends Serializable> extends AbstractDistribution<E> { @Getter private int[] ratio; private int all = 0; /** * This constructor takes an array of Element-Ratio pairs and a seed value. * @param seed The seed value. * @param elementRatioPairs A list of pairs with a ration and an element. */ public ConcreteDistribution(long seed, Pair<E, Integer>... elementRatioPairs) { super(seed); elements = new ArrayList<E>(); ratio = new int[elementRatioPairs.length]; int i = 0; for (Pair<E, Integer> pair : elementRatioPairs) { elements.add(pair.first()); all += pair.last(); ratio[i] = pair.last(); i++; } } /** * This constructor takes an array of Element-Ratio pairs. * @param elementRatioPairs * A list of pairs with a ration and an element. */ public ConcreteDistribution(Pair<E, Integer>... elementRatioPairs) { elements = new ArrayList<E>(); ratio = new int[elementRatioPairs.length]; int i = 0; for (Pair<E, Integer> pair : elementRatioPairs) { elements.add(pair.first()); all += pair.last(); ratio[i] = pair.last(); i++; } } /** * The mapping between the list of elements and the array of ratios is * sequential (thirst element of the list <-> thirst element of the array) * * @param seed The seed value. * @param elements A list of all elements. * @param ratio A list of the ratios */ public ConcreteDistribution(long seed, List<E> elements, int... ratio) { super(elements, seed); this.ratio = ratio; for (int i : ratio) { all += i; } } /** * The mapping between the list of elements and the array of ratios is * sequential (thirst element of the list <-> thirst element of the array) * * @param elements * A list of all elements. * @param ratio * A list of the ratios. */ public ConcreteDistribution(List<E> elements, int... ratio) { super(elements); this.ratio = ratio; for (int i : ratio) { all += i; } } @Override public E getNextValue() { double number = random.nextDouble(); boolean found = false; int i = 0; double sum = 0.0; while (!found && i < ratio.length) { sum += ratio[i]; if ((sum / all) >= number) { found = true; } else { i++; } } return elements.get(i); } }