next up previous
Next: Extending GAGS Up: Doing GAs with Previous: Computing fitness

Population

 

A population has got a list of chromosomes to evaluate, an usually ranked list of evaluated chromosomes, and a list of operators; since they are all lists, they can be changed in runtime. Creating a population is just a matter, then, of giving parameters to the creation of those list. The easiest way of creating a population is as follows

    const unsigned NUMGENES = 10;
    const bitLength_t SIZEGENES = 4;
    const unsigned NUMCHROMS= 20;
    Population<float> 
       people( NUMCHROMS, SIZEGENES, NUMGENES, NUMGENES, 1.0/(SIZEGENES*NUMGENES) );
i.e., default parameters are number of chromosomes in the population, the size of each gene, and the max and min number of genes in each chromosome; remember that GAGS by default works with variable-size chromosomes. Next parameter is the mutation probability, that is, the number of bits that will be flipped each time a chromosome is selected for mutation. Besides, Population is a class template that must be instantiated with the fitness type; in this case fitness is simply a floating-point number, but it could be something more complex; in any case, Population will be instantiated with fitness_t, which must have been defined in advance as the type returned by the fitness evaluation function.

At the same time, since a Population is a container class, it must have iterators to run on it. Instead of defining an iterator by default for each Population object, as it is done in the standard template library, it must be created by hand (but this might change in the future). In any case, there are three iterator classes defined for the population, corresponding to the three lists defined before.

All in all, here is an example of how to use the Population class

#include <gagspop.hpp>          // For Population class and iterators
#include <gagsview.hpp>         // For views
main () {
  const unsigned NUMGENES = 10;
  const bitLength_t SIZEGENES = 4;
  const unsigned GENERATIONS = 100;
  const unsigned numChroms= 20;
  seed_random( time( (time_t) 0 ) ); // From randcl
  // Set up population
  Population<float> 
    people( numChroms, SIZEGENES, NUMGENES, NUMGENES, 1.0/(SIZEGENES*NUMGENES) );
  people.setElite( 0.6 );       // Sets Elite rate
  genOp adder( SIZEGENES, genOp::DUP); // Creates gene duplicationn operator...
  people.addOp( &adder, 0.1 );  // ...and adds it to the population
  // Starts GA
  popIter<float> censo( people ); // Creates iterator
  view<float> vista( SIZEGENES, -1.0, 2.0 ); // View with range -1.0, 1.0
  for ( unsigned i = 0; i < GENERATIONS; i ++ ) {
    censo.reset( Iter::FIRST);          // Resets iterator
    while( censo ) {            // Evaluates fitness
      float val = 0.0;
      chrom* tmp = censo.current(); // Chromosome to evaluate
      for ( unsigned j = 0; j <  tmp->getLength()/SIZEGENES; j ++ ) {
        val += vista( tmp, j);
      } 
      censo.setFitness( val ); // This erases it from censo
      censo++;                 // Ahead to the next chromosome
    }

    evalIter<float> eval( people ); // Iterator on evaluated chromosomes
    for ( unsigned j = 0; 
          j < eval.current().mapItem->getLength()/SIZEGENES; j ++ ) {
      cout << vista(eval.current().mapItem, j) << " ";
    }
    cout << " = " << eval.current().key << endl;
    if ( i < GENERATIONS - 1) 
      people.newGeneration();   // Performs selection and genetic op application
  }
}
At the same time, it is an example of how to run a complete genetic algorithm. The Population class, which could be actually a Genetic Algorithm class, is defined in three steps,

The genetic algorithm part of the program is just a for loop over the number of generations that has been selected in advance, with an inner loop to evaluate each member of the population in turn. Note that the loop uses the non-evaluated population, which means that each chromosome is only evaluated once; using the setFitness function moves the chromosome from the non-evaluated list to the evaluated list. Finally, the best chromosome, that is, the one which is biggerThan any other, is printed using the evaluated-population iterator.

This is more or less how far you can go by using GAGS in your own programs. However, as any good-behaviored class library, you should be able to extend GAGS to adapt it to your own purposes. Next section explains how to do it.


next up previous
Next: Extending GAGS Up: Doing GAs with Previous: Computing fitness

J.J. Merelo Guervos
Fri Aug 22 12:58:28 MDT 1997