Mega Code Archive

 
Categories / Java / Development Class
 

A predictable random number generator

/*  * Encog(tm) Core v3.0 - Java Version  * http://www.heatonresearch.com/encog/  * http://code.google.com/p/encog-java/    * Copyright 2008-2011 Heaton Research, Inc.  *  * 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.  *     * For more information on Heaton Research copyrights, licenses   * and trademarks visit:  * http://www.heatonresearch.com/copyright  */ /**  * A predictable random number generator. This is useful for unit tests and  * benchmarks where we want random numbers, but we want them to be the same each  * time. This class exists on both Java and C# so it can even provide consistent  * random numbers over the two platforms.  *   * Random numbers are created using a LCG.  *   * http://en.wikipedia.org/wiki/Linear_congruential_generator  */ public class LinearCongruentialGenerator {   /**    * First part of default mod.    */   public static final long DEFAULT_MOD1 = 2L;      /**    * Second part of default mod.    */   public static final long DEFAULT_MOD2 = 32L;      /**    * Default mult.    */   public static final long DEFAULT_MULT = 1103515245L;      /**    * Default inc.    */   public static final long DEFAULT_INC = 12345L;      /**    * The modulus.    */   private final long modulus;   /**    * The multiplier.    */   private final long multiplier;   /**    * The amount to increment.    */   private final long increment;   /**    * The current seed, set to an initial value and always holds the value of    * the last random number generated.    */   private long seed;   /**    * The maximum rand number that the standard GCC based LCG will generate.    */   public static final long MAX_RAND = 4294967295L;   /**    * Construct the default LCG. You need only specify a seed.    *     * @param theSeed    *            The seed to use.    */   public LinearCongruentialGenerator(final long theSeed) {     this((long) Math.pow(DEFAULT_MOD1, DEFAULT_MOD2),          DEFAULT_MULT, DEFAULT_INC, theSeed);   }   /**    * Create a LCG with the specified modulus, multiplier and increment. Unless    * you REALLY KNOW WHAT YOU ARE DOING, just use the constructor that just    * takes a seed. It will set these values to the same as set by the GCC C    * compiler. Setting these values wrong can create fairly useless random    * numbers.    *     * @param theModulus    *            The modulus for the LCG algorithm.    * @param theMultiplier    *            The multiplier for the LCG algorithm.    * @param theIncrement    *            The increment for the LCG algorithm.    * @param theSeed    *            The seed for the LCG algorithm. Using the same seed will give    *            the same random number sequence each time, whether in Java or    *            DotNet.    */   public LinearCongruentialGenerator(final long theModulus,       final long theMultiplier, final long theIncrement,        final long theSeed) {     super();     this.modulus = theModulus;     this.multiplier = theMultiplier;     this.increment = theIncrement;     this.seed = theSeed;   }   /**    * @return The LCG increment.    */   public final long getIncrement() {     return this.increment;   }   /**    * @return The LCG modulus.    */   public final long getModulus() {     return this.modulus;   }   /**    * @return The LCG multiplier.    */   public final long getMultiplier() {     return this.multiplier;   }   /**    * @return The current seed. Set to a constant to start, thereafter the    *         previously generated random number.    */   public final long getSeed() {     return this.seed;   }   /**    * @return The next random number as a double between 0 and 1.    */   public final double nextDouble() {     return (double) nextLong() / LinearCongruentialGenerator.MAX_RAND;   }   /**    * @return The next random number as a long between 0 and MAX_RAND.    */   public final long nextLong() {     this.seed = (this.multiplier * this.seed + this.increment)         % this.modulus;     return this.seed;   }   /**    * Generate a random number in the specified range.    *     * @param min    *            The minimum random number.    * @param max    *            The maximum random number.    * @return The generated random number.    */   public final double range(final double min, final double max) {     final double range = max - min;     return (range * nextDouble()) - min;   }   /**    * Set the seed value. Setting a seed to a specific value will always result    * in the same sequence of numbers, whether on Java or DotNet.    *     * @param theSeed    *            The seed value.    */   public final void setSeed(final long theSeed) {     this.seed = theSeed;   } }