The GA Example
In this document, I attempt to develop a reasonable object oriented framework for creating genetic algorithms. I accomplish this by breaking down are algorithm into simple manageable units. Each title links to the java source, but before you sit here and download the whole thing filie by file, here is link to a zip file with all the files.
First let's consider the individual. The individual has several requirements layed out in the previous page. These requirements are met by the following functions
- constructor - sets the parent and offspring arrays to empty
- abstract getRandomIndividual - returns a random individual
- abstract getOffspringWith - returns an array of two individuals which are the crossover of this and the Individual passed as parameter
- abstract getMutation - returns a mutation of the current individual
- abstract getFitness - returns an int representing the fitness of the individual
- abstract getMaxFitness - returns the maximum possible fitness of the individual
- final setParents - sets the parents of the individual
- final addOffspring - adds an offspring to the individual
- final isOffspringOf - returns true if this is an offspring of the parameter individual
- final isParentOf - returns true if this is the parent of the parameter individual
- static functions - wrap calls to the abstract functions above
Many of the methods above are abstract because they should be implemented by a specific type individual (an implementation). I provide an example of an individual implementation in the BooleanIndividual class below.
The generation is nothing more than a an array of individuals. This class is provided more for convenience than any other reason. Its functions include
- constructor - sets the size of the generation
- getFitnessArray - returns a vector containing the fitness of all individuals
- getIndividualAt - returns the individual at the specified index
- getNumIndividuals - returns the number of individuals in the generation
- setIndividualAt - sets the individual at the specified index
- lastIndexOf - returns the last index of the specified individual
The generation container merely contains generation; it might have been more aptly named population. This class contains current and past generations. This class mainly serves to provide a historical record of the evolution of our population. This class is by no means a necessity for creating a genetic algorithm. This class is one of the most complex, because the necessity to free old generations to prevent massive memory consumption. Its functions include
- constructor - sets the maximum number of generations the container can hold
- addGeneration - adds a generation to the container
- getLastGeneration - returns the last generation in the container
- getLastGenerationNumber - returns the number of the last generation in the container
- getLowestGenerationNumber - returns the number of the first generation in the container
- getGenerationByNumber - returns a generation based on its number in the container
- getNumGenerations - returns the number of generations in the container
- getGenerationAt - returns a generation based on its list index
- setMaxCapacity - sets the maximum number of generations the container can hold
- getFittestIndividual - returns the fittest individual in the container
- other functions - are convenience functions or are used by the graphical user interface
Yes, here is class that actually does something. This class uses a base individual to generate random generations and offspring. The need for base individual stems from the need to have access to the getRandomIndividual function of the Individual class (which is not static). This class is also passed a crossoverRate and mutationRate at time of construction. These are used to determine how often individuals should reproduce sexually and assexually. This class uses the AIMath class to do most of its vector work, but does choose individuals with respect to their fitness. The crossoverRate and mutationRate mentioned above govern the generation of offspring. As the name indicates this class generates whole generations not single individuals. This class utilizes the AIMath class discussed below for vector operations. This class includes the following functions include
- constructor - sets the crossover probability, mutation probability, generation size, and base individual
- setCrossoverProbability - sets the probability of sexual reproduction
- getCrossoverProbability - returns the crossoverProbability
- setMutationProbability - sets the probability of assexual reproduction
- setGenSize - sets the size of the generated generations
- getGenSize - returns the size of the generated generations
- getBaseIndividual - returns the baseIndividual
- getInitialGeneration - returns the an initial generation of random individuals
- getNextGeneration - returns a new generation that is the offspring of the generation passed as parameter
This class is the highest level of the genetic algorithm hierarchy. This class controls the loop governing the creation individuals. This class implements java.lang.Runnable so it may be attached to thread. This prevents the genetic algorithm from eating all processor time of application. The run method does all the necessary looping for the genetic algorithm. Functions of this class include
This class does simple vector manipulations. It provides the following functions for both int vectors and float vectors.
- maximum - returns the maximum value of the vector
- minimum - returns the minimum value of the vector
- average - returns the average value of the vector
- indexOfMaximum - returns the index of the maximum value of the vector
- indexOfMinimum - returns the index of the minimum value of the vector
- normalize - returns the normal float vector of the vector
- summation - returns the sum of all itmes in the vector
- chooseItem - returns an index based on their normalized probabilities
- scale - returns the vector scaled by a number
- getRandomInt - returns an int within a maximum and minimum value
- getRandomFloat - returns a random float between 0 and 1
The BooleanIndividual class provides an implementation of the Individual class. It's chromosome is a simple boolean vector. The class provides all the necessary functionality for an Individual. This class implements all of the abstract functions of the Individual class. Their implementations are described below.
- getRandomIndividual - returns a random BooleanIndividual whose chromosome is random array of bits with length 25
- getOffspringWith - returns two BooleanIndividuals whose chromosomes are the arrays resulting from swapping all bits above a random index
- getFitness - returns the number of trues in the chromosome
- getMaxFitness - returns the maximum fitness = 25
- getMutation - returns a BooleanIndividual whose chromsome has approximately 10% of the this BooleanIndividuals bits notted (reversed)
This is just loader applet that takes an optional parameter Individual. If you decide to expand upon this framework it might be worth your time (at least initially) to use this load and run your genetic algorithm. An example use this class is shown below.
< applet height=25 height=150 class=GeneticAlgorithms >
< param name=Individual value=YourIndividualClass >
</applet>
The class also runs as a stand alone, but does not provide the class loading capability this way.
Other classes in the example
The other classes in the example only exist to aid in the creation of a nice graphical interface. None of these classes are necessities to creating a genetic algorithm. For your convenience, I list them and link to their source below.
- Generic GUI Classes
- CloseableDialog - a dialog that closes when a window close event is throw
- CloseableFrame - a frame that closes when a window close event is throw
- MultiLineLabel - a multi line label awt component from O'Reilly Book's Java Examples in a Nutshell by Flanagan
- DialogLayout - a dialog layout adapted from the generated source from Microsoft J++
- ExceptionDialog - a dialog that displays the toString of an exception
- Grapher - a graphing awt component (has fairly limited reusability)
- Graph - an abstract graph renderable by the Grapher component
- GraphicsWrapper - a class doing a coordinate transform using a GraphWindow
- GraphicsWindow - A graphic coordinate conversion class
- GraphPoint - a simple point object used by GraphWindow, Grapher, and Graph
- Renderer - an awt component that displays Renderable objects
- Renderable - an abstract class defining graphical depiction functions (Note this is really bad OOP)
- Genetic Algorithms GUI Classes
- That's all folks! (for now)
If you would like to download the whole thing, here is a convenient zip file.
Let's see it
Please be patient. This is a large applet and takes awhile to load.
Using the Genetic Algorithm Example
|