text: /* ----------------------------------------------------------------------------
    ex12.C
    mbwall 13apr95
    Copyright (c) 1995-1996  Massachusetts Institute of Technology
  
   DESCRIPTION:
     This example shows how to use an order-based string genome.
  ---------------------------------------------------------------------------- */
  #include <stdio.h>
  #include <stdlib.h>
  #include <ga/ga.h>
  #include <ga/std_stream.h>
  
  #define cout STD_COUT
  
  #define INSTANTIATE_STRING_GENOME
  #include <ga/GAStringGenome.h>
  
  // This is the declaration of the objective function that we will use in this
  // example.
  float objective(GAGenome &);
  
  // Every genome must have an initializer.  Here we declare our own initializer
  // that will be used in this example.
  void AlphabetInitializer(GAGenome &);
  
  int main(int argc, char *argv[])
  {
      cout << "Example 12\n\n";
      cout << "This program illustrates the use of order-based strings.  The\n";
      cout << "string in this problem contains 26 letters, a to z.  It tries\n";
      cout << "to put them in alphabetic order.\n\n";
      cout.flush();
  
      // See if we've been given a seed to use (for testing purposes).  When you
      // specify a random seed, the evolution will be exactly the same each time
      // you use that seed number.
  
      for (int ii = 1; ii < argc; ii++) {
          if (strcmp(argv[ii++], "seed") == 0) {
              GARandomSeed((unsigned int)atoi(argv[ii]));
          }
      }
  
      // Set the default values of the parameters then parse for command line changes
  
      int i;
      GAParameterList params;
      GASteadyStateGA::registerDefaultParameters(params);
      params.set(gaNpopulationSize, 25); // population size
      params.set(gaNpCrossover, 0.9);    // probability of crossover
      params.set(gaNpMutation, 0.01);    // probability of mutation
      params.set(gaNnGenerations, 4000); // number of generations
      params.parse(argc, argv, gaFalse);
  
      // Now create the GA and run it.  We first create a genome with the
      // operators we want.  Since we're using a template genome, we must assign
      // all three operators.  We use the order-based crossover site when we assign
      // the crossover operator.
  
      GAStringAlleleSet alleles;
      for (i = 0; i < 26; i++)
          alleles.add('a' + i);
  
      GAStringGenome genome(26, alleles, objective);
      genome.initializer(AlphabetInitializer);
      genome.mutator(GAStringSwapMutator);
  
      GASteadyStateGA ga(genome);
      ga.parameters(params);
      ga.crossover(GAStringPartialMatchCrossover);
      ga.evolve();
  
      genome = ga.statistics().bestIndividual();
      cout << "the ga generated the following string (objective score is ";
      cout << genome.score() << "):\n" << genome << "\n";
      cout << genome.className() << "\n";
  
      return 0;
  }
  
  /* ----------------------------------------------------------------------------
  Objective function
    The objective function gives one point for every number in the correct
  position.  We're trying to get a sequence of numbers from n to 0 in descending
  order.
  ---------------------------------------------------------------------------- */
  float objective(GAGenome &c)
  {
      GAStringGenome &genome = (GAStringGenome &)c;
  
      float score = 0;
      for (int i = 0; i < genome.size(); i++)
          score += (genome.gene(i) == 'a' + i);
      return score;
  }
  
  /* ----------------------------------------------------------------------------
  AlphabetInitializer
    This initializer creates a string genome with the letters a-z as its
  elements.  Once we have assigned all the values, we randomize the string.
  ---------------------------------------------------------------------------- */
  void AlphabetInitializer(GAGenome &c)
  {
      GAStringGenome &genome = (GAStringGenome &)c;
      int i;
      for (i = 0; i < genome.size(); i++)
          genome.gene(25 - i, 'a' + i);
  
      for (i = 0; i < genome.size(); i++)
          if (GARandomBit())
              genome.swap(i, GARandomInt(0, genome.size() - 1));
  }
  