/* XXL: The eXtensible and fleXible Library for data processing Copyright (C) 2000-2011 Prof. Dr. Bernhard Seeger Head of the Database Research Group Department of Mathematics and Computer Science University of Marburg Germany This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; If not, see <http://www.gnu.org/licenses/>. http://code.google.com/p/xxl/ */ package xxl.core.cursors.sources; import xxl.core.cursors.AbstractCursor; import xxl.core.util.random.DiscreteRandomWrapper; import xxl.core.util.random.JavaDiscreteRandomWrapper; /** * A cursor providing a finite or finite stream of randomly distributed integer * values given by the wrapped <i>pseudo random number generator</i> * {@link xxl.core.util.random.DiscreteRandomWrapper} for discrete numbers. XXL * provides two kinds of PRNG, namley, the first based on * {@link java.util.Random Java}'s random number generator and the second based * on Colt's random number generator * (<code>cern.jet.random.AbstractDiscreteDistribution</code>). * * <p><b>Example usage (1):</b> * <code><pre> * DiscreteRandomNumber drn = new DiscreteRandomNumber( * new JavaDiscreteRandomWrapper(), * 200 * ); * * drn.open(); * * long i = 0; * while (drn .hasNext()) * System.out.println((i++) + "\t:\t" + drn.next()); * System.out.println(); * * drn.close(); * </pre></code> * This example produces a finite stream of randomly distributed integer values * delivered by a {@link xxl.core.util.random.JavaDiscreteRandomWrapper PRNG}, * i.e., Java's random number generator is used for the provision of randomly * distributed integer values. The returned stream of integer objects contains * 200 elements as specified in the constructor.</p> * * @see java.util.Iterator * @see xxl.core.cursors.Cursor * @see xxl.core.cursors.AbstractCursor * @see java.util.Random */ public class DiscreteRandomNumber extends AbstractCursor<Integer> { /** * The random number generator wrapper delivering integer values according * to the wrapped PRNG. */ protected DiscreteRandomWrapper discreteRandomWrapper; /** * A flag signaling if the returned stream of integer values should be * infinite. */ protected boolean infiniteStream; /** * If the returned stream of integer elements is finite, this long value * defines the number of elements to be returned. */ protected long numberOfElements; /** * An internal used counter counting the elements that are yet returned by * this iteration. */ protected long count; /** * Constructs a new discrete random number cursor delivering randomly * distributed discrete numbers (integer values). If the given number of * elements is greater than or equal to <code>0</code> the cursor provides * a <b>finite</b> number of elements otherwise an <b>infinite</b> number * of elements is provided. * * @param discreteRandomWrapper the random number generator wrapper to be * used for the provision of random integer values. * @param numberOfElements the number of elements to be returned. If the * given number is greater than or equal to <code>0</code> the * cursor provides a <b>finite</b> number of elements otherwise an * <b>infinite</b> number of elements is provided. */ public DiscreteRandomNumber(DiscreteRandomWrapper discreteRandomWrapper, long numberOfElements) { this.discreteRandomWrapper = discreteRandomWrapper; this.infiniteStream = numberOfElements < 0; this.numberOfElements = numberOfElements; this.count = 0; } /** * Constructs a new discrete random number cursor delivering an * <b>infinite</b> number of randomly distributed discrete numbers (integer * values). * * @param discreteRandomWrapper the random number generator wrapper to be * used for the provision of random integer values. */ public DiscreteRandomNumber(DiscreteRandomWrapper discreteRandomWrapper) { this(discreteRandomWrapper, -1); } /** * Constructs a new discrete random number cursor delivering randomly * distributed discrete numbers (integer values). If the given number of * elements is greater than or equal to <code>0</code> the cursor provides * a <b>finite</b> number of elements otherwise an <b>infinite</b> number * of elements is provided. Java's random number generator is is used for * the provision of random integer values. * * @param numberOfElements the number of elements to be returned. If the * given number is greater than or equal to <code>0</code> the * cursor provides a <b>finite</b> number of elements otherwise an * <b>infinite</b> number of elements is provided. */ public DiscreteRandomNumber(long numberOfElements) { this(new JavaDiscreteRandomWrapper(), numberOfElements); } /** * Constructs a new discrete random number cursor delivering an * <b>infinite</b> number of randomly distributed discrete numbers (integer * values). Java's random number generator is is used for the provision of * random integer values. */ public DiscreteRandomNumber() { this(new JavaDiscreteRandomWrapper()); } /** * Returns <code>true</code> if the iteration has more elements. (In other * words, returns <code>true</code> if <code>next</code> or * <code>peek</code> would return an element rather than throwing an * exception.) * * @return <code>true</code> if the discrete random number cursor has more * elements. */ protected boolean hasNextObject() { return infiniteStream || ++count <= numberOfElements; } /** * Returns the next element in the iteration. This element will be * accessible by some of the discrete random number cursor's methods, e.g., * <code>update</code> or <code>remove</code>, until a call to * <code>next</code> or <code>peek</code> occurs. This is calling * <code>next</code> or <code>peek</code> proceeds the iteration and * therefore its previous element will not be accessible any more. * * @return the next element in the iteration. */ protected Integer nextObject() { return discreteRandomWrapper.nextInt(); } /** * Resets the discrete random number cursor to its initial state such that * the caller is able to traverse the iteration again without constructing * a new discrete random number cursor (optional operation). * * <p>Note, that this operation is optional and might not work for all * cursors.</p> * * @throws UnsupportedOperationException if the <code>reset</code> * operation is not supported by the discrete random number cursor. */ public void reset() { super.reset(); this.count = 0; } /** * Returns <code>true</code> if the <code>reset</code> operation is * supported by the discrete random number cursor. Otherwise it returns * <code>false</code>. * * @return <code>true</code> if the <code>reset</code> operation is * supported by the discrete random number cursor, otherwise * <code>false</code>. */ public boolean supportsReset() { return true; } }