/*
* This file is part of JGAP.
*
* JGAP offers a dual license model containing the LGPL as well as the MPL.
*
* For licensing information please see the file license.txt included with JGAP
* or have a look at the top of class org.jgap.Chromosome which representatively
* includes the JGAP license policy applicable for any file delivered with JGAP.
*/
package org.jgap.impl;
import java.util.*;
import java.io.*;
import org.jgap.*;
/**
* Gaussian deviation serving as basis for randomly finding a number.
*
* @author Klaus Meffert
* @since 1.1
*/
public class GaussianRandomGenerator
implements RandomGenerator {
/** String containing the CVS revision. Read out via reflection!*/
private final static String CVS_REVISION = "$Revision: 1.21 $";
//delta for distinguishing whether a value is to be interpreted as zero
private static final double DELTA = 0.0000001;
private Random m_rn;
/**
* Standard deviation of the gaussian deviation
*/
private double m_standardDeviation;
public GaussianRandomGenerator() {
this(1.0d);
}
/**
* Constructor speicifying the (obliagtory) standard deviation.
*
* @param a_standardDeviation the standard deviation to use
*/
public GaussianRandomGenerator(final double a_standardDeviation) {
super();
init();
setGaussianStdDeviation(a_standardDeviation);
}
/**
* Initializations on construction.
*/
private void init() {
m_rn = new Random();
}
public void setGaussianStdDeviation(final double a_standardDeviation) {
if (a_standardDeviation <= DELTA) {
throw new IllegalArgumentException(
"Standard deviation must be greater 0!");
}
m_standardDeviation = a_standardDeviation;
}
public double getGaussianStdDeviation() {
return m_standardDeviation;
}
/**
* @return positive integer value
*/
public int nextInt() {
return Math.abs(Math.min(Integer.MAX_VALUE - 1,
(int) Math.round(nextGaussian()
* Integer.MAX_VALUE)));
}
/**
* @param a_ceiling the upper boundary excluded
* @return positive integer value between 0 and (ceiling - 1)
*/
public int nextInt(final int a_ceiling) {
return Math.min(a_ceiling - 1,
(int) Math.round(nextGaussian() * a_ceiling / (5.8d * 2)));
}
/**
* @return positive long value
*/
public long nextLong() {
long result = Math.min(Long.MAX_VALUE,
(long) (nextGaussian() * Long.MAX_VALUE / (5.8d * 2)));
return result;
}
public double nextDouble() {
return nextGaussian();
}
public float nextFloat() {
return (float) (nextGaussian());
}
public boolean nextBoolean() {
return nextGaussian() >= 0.5d;
}
/**
* @return the next randomly distributed gaussian with current standard
* deviation, will be greater/equal zero
*/
private double nextGaussian() {
//scale to [0..1[
double r = (m_rn.nextGaussian() + 5.8d) / (5.8d * 2.0d);
return r;
}
/**
* When deserializing, initialize the seed because otherwise we could get
* duplicate evolution results when doing distributed computing!
*
* @param a_inputStream the ObjectInputStream provided for deserialzation
*
* @throws IOException
* @throws ClassNotFoundException
*
* @author Klaus Meffert
* @since 3.01
*/
private void readObject(ObjectInputStream a_inputStream)
throws IOException, ClassNotFoundException {
//always perform the default de-serialization first
a_inputStream.defaultReadObject();
m_rn.setSeed(System.currentTimeMillis());
}
}