1 using System;
2 using System.Collections.Generic;
3
4 class Population {
5
6 public Population() {
7 populationDistributor_ = new PopulationDistributor(this);
8
9
10 populationDistributor_.set(new CreationWork(this));
11 populationDistributor_.doWork();
12 population_ = populationDistributor_.transferChildren();
13 numberOfGenomes_ = population_.Count;
14 process();
15 }
16
17 public bool containsSolution() {return population_[0].getFitness()==0;}
18
19 public void breed() {
20
21
22
23
24
25 populationDistributor_.set(new MutationWork(this));
26 populationDistributor_.doWork();
27 List<Genome> children = populationDistributor_.transferChildren();
28
29
30
31
32 populationDistributor_.set(new CrossoverWork(this));
33 populationDistributor_.doWork();
34 children.AddRange(populationDistributor_.transferChildren());
35
36
37 population_.RemoveRange((int)(population_.Count - parms_.reproductionSize_), parms_.reproductionSize_);
38
39 population_.AddRange(children);
40 numberOfGenomes_ += children.Count;
41 process();
42 }
43
44
45 public List<Genome> create(int min, int max1) {
46 List<Genome> children = new List<Genome>();
47 for (int k = min; k < max1; k++) children.Add(new Genome());
48 return children;
49 }
50
51 public List<Genome> mutate(int min, int max1) {
52 List<Genome> children = new List<Genome>();
53 for (int k = min; k < max1; k++) children.Add(new Genome(population_[k]));
54 return children;
55 }
56
57 public List<Genome> crossover(int min, int max1) {
58 List<Genome> children = new List<Genome>();
59 for (int k = min; k < max1; k++) children.Add(new Genome(population_[k], population_[k + 1]));
60 return children;
61 }
62
63 public override string ToString() {
64 return "\t" + generation_ + "\t" + population_[0].getFitness()
65 + "\t" + String.Format("{0:0.0}", meanFitness())
66 + "\t" + population_[population_.Count-1].getFitness()
67 + "\t" + String.Format("{0:0.##}", 100*inbreeding_/(float)population_.Count);
68 }
69
70 private float meanFitness() {
71 uint fitnessSum = 0;
72 population_.ForEach(delegate(Genome genome) { fitnessSum += genome.getFitness(); });
73 return fitnessSum / (float)population_.Count;
74 }
75
76 private void process() {
77 generation_++;
78 population_.Sort();
79
80
81
82
83 List<Genome> populationSorted = new List<Genome>();
84 populationSorted.AddRange(population_);
85 populationSorted.Sort(new ExactCompareGenome());
86
87 inbreeding_ = 0;
88 for(int k = 0; k < populationSorted.Count-1; k++)
89 if(populationSorted[k].ExactCompareTo(populationSorted[k+1])==0) inbreeding_++;
90 maximumInbreeding_ = Math.Max(maximumInbreeding_, inbreeding_);
91
92
93 if(!Program.multipleMode_) Console.WriteLine(this);
94 if(containsSolution()) {
95 if (Program.multipleMode_) {
96 double timer = timer_.getSeconds();
97 double numberOfGenomeBits = Genome.getNumberOfBits();
98 Console.WriteLine(String.Format("{0,4:0}{1,10:0.000}{2,10:###,###,##0}{3,8:###,##0}{4,11:0.0}{5,9:###,##0}"
99 + "{6,10:0.0}{7,11:0.0}{8,13:0.0}{9,9:###,##0}{10,11:0.000}",
100 Genome.N_, timer, numberOfGenomes_, generation_, meanFitness(), population_[population_.Count-1].getFitness(),
101 100 * inbreeding_/(float)population_.Count, 100 * maximumInbreeding_/(float)population_.Count,
102 1000 * timer / numberOfGenomeBits, numberOfGenomes_ / numberOfGenomeBits, generation_ / numberOfGenomeBits
103 ));
104 }
105 else Console.Write("\n" + population_[0]
106 + String.Format("\nNumber of genomes created: {0:###,###,###,##0}\n", numberOfGenomes_));
107 }
108 }
109
110 public void terminate() {populationDistributor_.requestWorkerTermination();}
111
112 public uint getNumberOfGenerations() {return generation_;}
113
114
115 private Timer timer_ = new Timer();
116 private uint generation_ = 0;
117 private int numberOfGenomes_;
118 private uint inbreeding_;
119 private uint maximumInbreeding_ = 0;
120
121 private List<Genome> population_;
122 public PopulationDistributor populationDistributor_;
123
124 public static readonly GeneticAlgorithmParameters parms_ = new GeneticAlgorithmParameters(3000, 0.8f, 0.6f);
125 }