We've now got all of the necessary pieces to complete the "Hello World" example
      application.  Assuming that you've already created the
      StringEvaluator class (defined above) in a separate file,
      the code needed to create the evolution engine looks like this:
    
// Create a factory to generate random 11-character Strings. char[] chars = new char[27]; for (char c = 'A'; c <= 'Z'; c++) { chars[c - 'A'] = c; } chars[26] = ' '; CandidateFactory<String> factory = new StringFactory(chars, 11); // Create a pipeline that applies cross-over then mutation. List<EvolutionaryOperator<String>> operators = new LinkedList<EvolutionaryOperator<String>>(); operators.add(new StringMutation(chars, new Probability(0.02))); operators.add(new StringCrossover()) EvolutionaryOperator<String> pipeline = new EvolutionPipeline<String>(operators); FitnessEvaluator<String> fitnessEvaluator = new StringEvaluator(); SelectionStrategy<Object> selection = new RouletteWheelSelection(); Random rng = new MersenneTwisterRNG(); EvolutionEngine<String> engine = new GenerationalEvolutionEngine<String>(factory, pipeline, fitnessEvaluator, selection, rng);
      The listing above only creates the evolution engine, it does not perform any
      evolution.  For that we need to call the evolve method.
      The evolve method takes three parameters.  The first
      is the size of the population.  This is the number of candidate solutions that
      exist at any time.  A bigger population will often result in a satisfactory
      solution being found in fewer generations.  On the other hand, the processing
      of each generation will take longer because there are more individuals to deal
      with.  For the "Hello World" program, a population size of 10 is fine.
    
The second parameter is concerned with elitism. Elitism is explained in Chapter 3, Selection Strategies & Elitism. For now, just use a value of zero. The final varargs parameter specifies one or more termination conditions.
        Termination conditions make the evolution stop.  There are a few reasons why
        we would like the evolution to stop.  The most obvious is because we have found the
        solution that we are looking for.  In the case of the "Hello World" program, that
        is when we have found the target string.  The target string has a fitness score of
        11 so we use the TargetFitness condition.
      
To complete the evolutionary "Hello World" application, add the following two lines:
String result = engine.evolve(10, 0, new TargetFitness(11)); System.out.println(result);
          When we move on to less trivial evolutionary programs, we will rarely be able to
          specify the outcome so precisely.  The
          org.uncommons.watchmaker.framework.termination package includes
          other termination conditions that can be used.  For example, we may want the program
          to run for a certain period of time, or a certain number of generations, and then
          return the best solution it has found up until that point.  The
          ElapsedTime and GenerationCount
          conditions provide this functionality.  Alternatively, we may want the program to
          continue as long as it is finding progressively better solutions.  The
          Stagnation condition will terminate the evolution after a
          set number of generations pass without any improvement in the fitness of the fittest
          candidate.
          If multiple termination conditions are specified, the evolution will stop as soon
          as any one of them is satisfied.
        
Compile and run the above code and, perhaps after a brief pause, you'll see the following output:
  HELLO WORLD
        
        This is quite probably the most convoluted "Hello World" program you'll ever write.
        It also gives no hints as to its evolutionary nature.  We can make the program more
        interesting by adding an EvolutionObserver to report
        on the progress of the evolution at the end of each generation.  Add the following
        code to your program before the call to the evolve method:
      
engine.addEvolutionObserver(new EvolutionObserver<String>()
{
    public void populationUpdate(PopulationData<? extends String> data)
    {
        System.out.printf("Generation %d: %s\n",
                          data.getGenerationNumber(),
                          data.getBestCandidate());
    }
});
        Re-compile the program and run it again. This time you'll see all of the steps taken to arrive at the target string:
  Generation 0: JIKDORHOQZJ
  Generation 1: ULLLFQWZPXG
  Generation 2: UEULKFVFZLS
  Generation 3: KLLLFKZGRLS
  Generation 4: HLLLFKZGRLS
  Generation 5: HEDPOYWOZLS
  Generation 6: HEULKIWWZLD
  Generation 7: HPRLOYWOZLS
  Generation 8: HEULOYWOZLS
  Generation 9: HEULOYWORLS
  Generation 10: HEULOYWORLS
  Generation 11: HPLLK WQRLH
  Generation 12: HEBLOYWQRLS
  Generation 13: HEULOYWOBLA
  Generation 14: HEBLOIWMRLD
  Generation 15: HEBLOIWMRLD
  Generation 16: HEYLFNWQRLD
  Generation 17: HEBLOIWORLS
  Generation 18: HEBLOIWORLT
  Generation 19: HEBLOKWGRLD
  Generation 20: HELLAYWORLS
  Generation 21: HELHOIWORLT
  Generation 22: HEWLOIWORLS
  Generation 23: HEBLOYCORLD
  Generation 24: HELLKQWORLD
  Generation 25: HELLOIWORLT
  Generation 26: HELLOIWORLS
  Generation 27: HELLKQWORLD
  Generation 28: HELLFYWORLD
  Generation 29: HELLOIWORLD
  Generation 30: HELLOIWORLD
  Generation 31: HELLOIWORLD
  Generation 32: HELLOIWORLD
  Generation 33: HELLOIWORLD
  Generation 34: HELLOIWORLD
  Generation 35: HELLOIWDRLD
  Generation 36: HELLOIWORLD
  Generation 37: HELLOIWORLD
  Generation 38: HELLOPWORLD
  Generation 39: HELLOIWORLD
  Generation 40: HELLO WORLD
  HELLO WORLD