Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to implement the Gaussian mutation operator for a genetic algorithm in Java

I try to learn and implement a simple genetic algorithm library for my project. At this time, evolution, selection of population is ready, and I'm trying to implement a simple good mutation operator like the Gaussian mutation operator (GMO) for my genetic evolution engine in Java and Scala.

I find some information on Gaussian mutation operator (GMO) into the paper A mutation operator based on a Pareto ranking for multi-objective evolutionary algorithms (P.M. Mateo, I. Alberto), page 6 and 7.

But I have some problem to find other information on how to implement this Gaussian mutation operator and other useful variants of this operator in Java. What should I do?

I'm using the random.nextGaussian() function of random Java util, but this method only returns a random number between 0 and 1.

So,

a) How can I modify the precision of the return number in this case? (For example, I want to get a random double number between 0 and 1 with step equal to 0.00001.)

b) and how can I specify mu and sigma for this function, because I want to search locally about a value of my genome, not between -1 and 1. How can I ajust that local research around my genome value?

After research, I found an answer for the b) question. It seems I can displace the Gaussian random number like this:

 newGenomeValue = oldGenomeValue + (( gaussiandRndNumber * sigma ) + mean )

where mean = my genome value.

(Cf. method of bottom page in How can I generate random numbers with a normal or Gaussian distribution?.)

like image 856
reyman64 Avatar asked Jun 08 '11 07:06

reyman64


People also ask

What is mutation operator in genetic algorithm?

Mutation is an asexual operator, which needs only one chromosome in order to generate a child chromosome. These operators make it possible to maintain the random aspect in the evolution of the population in order to avoid premature convergence.

How do you select mutation in genetic algorithm?

A common method of implementing the mutation operator involves generating a random variable for each bit in a sequence. This random variable tells whether or not a particular bit will be flipped. This mutation procedure, based on the biological point mutation, is called single point mutation.

What is crossover and mutation in genetic algorithm?

The crossover of two parent strings produces offspring (new solutions) by swapping parts or genes of the chromosomes. Crossover has a higher probability, typically 0.8-0.95. On the other hand, mutation is carried out by flipping some digits of a string, which generates new solutions.


2 Answers

To answer question a, all you have to do is round to the nearest 0.00001 to get your answer in those units. For example:

  step = 0.00001;
  quantized_x = step * Math.rint(x / step);

Now for part b, you have the right idea and the code you presented should work. All you need to do is rescale your variable to the desired range. The only thing I can add is that the underlying reason this works is the change of variables theorem from calculus: http://en.wikipedia.org/wiki/Integration_by_substitution

If you work out this formula in the case of a Gaussian distribution with 0 mean and standard deviation 1 being transformed by a linear shift and a rescaling, then you will see that what you wrote out was indeed correct.

Putting it all together, here is some code that should do the trick:

double next_gaussian()
{
    double x = rng.nextGaussian();  //Use whichever method you like 
                                    //here to generate an initial [-1,1] gaussian distribution

    y = (x * 0.5) + 0.5;                //Rescale to [0,1]

    return Math.rint(y * 100000.0) * 0.00001; //Quantize to step size 0.00001
}
like image 187
Mikola Avatar answered Oct 17 '22 03:10

Mikola


I strongly suggest to DO NOT use the Java's random number generator. It uses the linear congruential generator, which has known limitations:

If higher quality random numbers are needed, and sufficient memory is available (~ 2 kilobytes), then the Mersenne twister algorithm provides a vastly longer period (219937-1) and variate uniformity.[9] The Mersenne twister generates higher-quality deviates than almost any LCG.[citation needed] A common Mersenne twister implementation, interestingly enough, uses an LCG to generate seed data.* (From Wikipedia)

Accordingly, I suggest you to consider a Mersenne twister implementation. In particular, I'm using the ECJ's implementation, which also has the ability to generate Gaussian numbers.

If you need compatibility with Java's Random interface use http://code.google.com/p/ecj/source/browse/trunk/ecj/ec/util/MersenneTwister.java.

http://code.google.com/p/ecj/source/browse/trunk/ecj/ec/util/MersenneTwisterFast.java is faster, but it does not implement the Random interface.

like image 20
Matteo Avatar answered Oct 17 '22 05:10

Matteo