1  using System.Collections.Generic;
   2  
   3  class PopulationDistributor : Distributor {
   4      public PopulationDistributor(Population population) {population_ = population;}
   5  
   6      public List<Genome> transferChildren() {
   7          List<Genome> result = new List<Genome>();
   8          foreach(List<Genome> list in children_) {
   9              result.AddRange(list);
  10              list.Clear();  // Prepare for next generation
  11              }
  12          return result;
  13          }
  14  
  15      private Population population_;
  16      public List<Genome>[] children_ = new List<Genome>[(int)numberOfThreads_];
  17  }
  18  
  19  // ----------------------- PopulationWork ------------------------------
  20  // All member functions except constructors execute in worker threads.
  21  
  22  abstract class PopulationWork : Work {
  23      protected PopulationWork(Population population, int workSize) { 
  24          population_ = population; 
  25          workSize_ = workSize;
  26          numberOfIndicesPerThread_ = (int)(workSize_/(float)PopulationDistributor.numberOfThreads_);
  27          }
  28  
  29      abstract public void execute(uint workerNumber);
  30  
  31      protected int min(uint workerNumber)
  32          {return (int)(workerNumber * numberOfIndicesPerThread_);}
  33  
  34      protected int max1(uint workerNumber)
  35          {return workerNumber + 1 == PopulationDistributor.numberOfThreads_ ? workSize_ :
  36              (int)((workerNumber + 1) * numberOfIndicesPerThread_);}
  37  
  38      protected void set(uint workerNumber, List<Genome> children) 
  39          {population_.populationDistributor_.children_[workerNumber] = children;}
  40  
  41      protected Population population_;
  42      private int workSize_;
  43      private int numberOfIndicesPerThread_;
  44  }
  45  
  46  class CreationWork : PopulationWork {
  47      public CreationWork(Population population) : base(population, (int)Population.parms_.populationSize_) { }
  48  
  49      public override void execute(uint workerNumber) {
  50          Genome.initializeRandom(workerNumber);
  51          set(workerNumber, population_.create(min(workerNumber), max1(workerNumber)));
  52          }
  53  }
  54  
  55  class MutationWork : PopulationWork {
  56      public MutationWork(Population population) : base(population, Population.parms_.mutationSize_) {}
  57  
  58      public override void execute(uint workerNumber) 
  59          {set(workerNumber, population_.mutate(min(workerNumber), max1(workerNumber)));}
  60  }
  61  
  62  class CrossoverWork : PopulationWork {
  63      public CrossoverWork(Population population) : base(population, Population.parms_.crossoverSize_) { }
  64  
  65      public override void execute(uint workerNumber) 
  66          {set(workerNumber, population_.crossover(min(workerNumber), max1(workerNumber)));}
  67  }