Skip to content

Commit caee33b

Browse files
authored
Components (#6)
* Renamed IMutationManager to IMutationProbabilityManager * Added ProbabilityUtils * Small fixes * Initial components * Added components PopulationGenerators * Added SelectKRandomNumbers method * Added K_PointCrossover * Added SinglePointCrossoverManager * Added UniformCrossoverManager * Added BitStringMutationManager * Added UniformMutationManager * Removed NumberVector project * Added documentation * Update README.md * Added GaussianMutationManager * Added DoubleVectorChromosomePopulationGenerator * Added "Int" to the int mutation managers * Added DoubleBoundaryMutationManagerTest * Added DoubleGaussianMutationManager and DoubleUniformMutationManager * Changed Bit Vector Chromosomes to use bools * Fixed bug * Added Shrink Mutation Managers
1 parent 266a2b5 commit caee33b

File tree

52 files changed

+1605
-189
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+1605
-189
lines changed

EnvironmentGui/CrossoverManager.cs

+2-4
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
1-
using System;
1+
using GeneticAlgorithm;
22
using GeneticAlgorithm.Interfaces;
33

44
namespace Environment
55
{
66
class CrossoverManager : ICrossoverManager
77
{
8-
private readonly Random random = new Random();
9-
108
public IChromosome Crossover(IChromosome chromosome1, IChromosome chromosome2)
119
{
1210
var type1 = ((MyChromosome) chromosome1).Type;
@@ -17,7 +15,7 @@ public IChromosome Crossover(IChromosome chromosome1, IChromosome chromosome2)
1715
if (type1 == ChromosomeType.Oc2Producer && type2 == ChromosomeType.Oc2Producer)
1816
return new MyChromosome(ChromosomeType.Oc2Producer);
1917

20-
return new MyChromosome(random.NextDouble() < 0.5 ? ChromosomeType.OProducer : ChromosomeType.Oc2Producer);
18+
return new MyChromosome(ProbabilityUtils.P(0.5) ? ChromosomeType.OProducer : ChromosomeType.Oc2Producer);
2119
}
2220
}
2321
}

EnvironmentGui/MyChromosome.cs

-2
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@ namespace Environment
55
{
66
class MyChromosome : IChromosome
77
{
8-
private readonly Random random = new Random();
9-
108
public ChromosomeType Type { get; private set; }
119

1210
public MyChromosome(ChromosomeType type)

EnvironmentGui/PopulationGenerator.cs

+2-3
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,17 @@
11
using System;
22
using System.Collections.Generic;
3+
using GeneticAlgorithm;
34
using GeneticAlgorithm.Interfaces;
45

56
namespace Environment
67
{
78
class PopulationGenerator : IPopulationGenerator
89
{
9-
private readonly Random random = new Random();
10-
1110
public IEnumerable<IChromosome> GeneratePopulation(int size)
1211
{
1312
var chromosomes = new IChromosome[size];
1413
for (int i = 0; i < size; i++)
15-
chromosomes[i] = new MyChromosome(random.NextDouble() < 0.5
14+
chromosomes[i] = new MyChromosome(ProbabilityUtils.P(0.5)
1615
? ChromosomeType.OProducer
1716
: ChromosomeType.Oc2Producer);
1817

GUI/BasicEvaluator.cs

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
using System.Linq;
2+
using GeneticAlgorithm.Components.Chromosomes;
3+
using GeneticAlgorithm.Components.Interfaces;
4+
using GeneticAlgorithm.Interfaces;
5+
6+
namespace GUI
7+
{
8+
class BasicEvaluator : IEvaluator
9+
{
10+
public double Evaluate(IChromosome chromosome) =>
11+
((VectorChromosome<int>) chromosome).GetVector().Sum();
12+
}
13+
}

GUI/GUI.csproj

+1-4
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
<Reference Include="System.Xml" />
4747
</ItemGroup>
4848
<ItemGroup>
49+
<Compile Include="BasicEvaluator.cs" />
4950
<Compile Include="DoubleInputBox.cs">
5051
<SubType>UserControl</SubType>
5152
</Compile>
@@ -94,10 +95,6 @@
9495
<Project>{5fadb04c-ee9d-4169-81a1-441ff61da671}</Project>
9596
<Name>GeneticAlgorithm</Name>
9697
</ProjectReference>
97-
<ProjectReference Include="..\NumberVector\NumberVector.csproj">
98-
<Project>{e84d6bd7-ff0d-4125-9e5c-36462247613a}</Project>
99-
<Name>NumberVector</Name>
100-
</ProjectReference>
10198
<ProjectReference Include="..\UserControls\UserControls.csproj">
10299
<Project>{77d37cc0-b19f-46a4-96c0-b9e49c3daf5e}</Project>
103100
<Name>UserControls</Name>

GUI/MainForm.cs

+12-5
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
using System.Windows.Forms;
22
using GeneticAlgorithm;
3-
using GreatestVectorTests;
3+
using GeneticAlgorithm.Components.CrossoverManagers;
4+
using GeneticAlgorithm.Components.MutationManagers;
5+
using GeneticAlgorithm.Components.PopulationGenerators;
46

57
namespace GUI
68
{
79
public partial class MainForm : Form
810
{
911
private const int POPULATION_SIZE = 20;
12+
private const int VECTOR_SIZE = 10;
1013
private const int GENERATION = int.MaxValue;
1114

1215

@@ -18,10 +21,14 @@ public MainForm()
1821

1922
private void InitializeEngine()
2023
{
21-
var engineBuilder = new GeneticSearchEngineBuilder(POPULATION_SIZE, GENERATION,
22-
new NumberVectorCrossoverManager(),
23-
new NumberVectorPopulationGenerator()).SetMutationProbability(MutationInputBox.GetValue)
24-
.SetElitePercentage(ElitismInputBox.GetValue);
24+
var mutationManager = new IntUniformMutationManager(0, 100);
25+
var evaluator = new BasicEvaluator();
26+
var populationGenerator =
27+
new IntVectorChromosomePopulationGenerator(VECTOR_SIZE, 0, 1, mutationManager, evaluator);
28+
var crossoverManager = new SinglePointCrossoverManager<int>(mutationManager, evaluator);
29+
var engineBuilder =
30+
new GeneticSearchEngineBuilder(POPULATION_SIZE, GENERATION, crossoverManager, populationGenerator)
31+
.SetMutationProbability(MutationInputBox.GetValue).SetElitePercentage(ElitismInputBox.GetValue);
2532
searchRunner1.SetEngineBuilder(engineBuilder);
2633
}
2734

GUI/Program.cs

-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
11
using System;
2-
using System.Collections.Generic;
3-
using System.Linq;
4-
using System.Threading.Tasks;
52
using System.Windows.Forms;
63

74
namespace GUI

GeneticAlgorithm.UnitTests/ChildrenGeneratorTests.cs

+5-5
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ public void TestMutationsHappen(double mutationProbability)
2727
var crossoverManager = A.Fake<ICrossoverManager>();
2828
A.CallTo(() => crossoverManager.Crossover(A<IChromosome>._, A<IChromosome>._))
2929
.ReturnsLazily((IChromosome c1, IChromosome c2) => c1);
30-
var childrenGenerator = new ChildrenGenerator(crossoverManager, new BassicMutationManager(mutationProbability), new RouletteWheelSelection());
30+
var childrenGenerator = new ChildrenGenerator(crossoverManager, new BassicMutationProbabilityManager(mutationProbability), new RouletteWheelSelection());
3131
childrenGenerator.GenerateChildren(population, populationSize, 0, null);
3232

3333
const double errorMargin = 0.05;
@@ -44,7 +44,7 @@ public void RetusnRightNumberOfChromosomes(int childrenCount)
4444
{
4545
const int count = 1500;
4646
var crossoverManager = A.Fake<ICrossoverManager>();
47-
var childrenGenerator = new ChildrenGenerator(crossoverManager, new BassicMutationManager(0), new RouletteWheelSelection());
47+
var childrenGenerator = new ChildrenGenerator(crossoverManager, new BassicMutationProbabilityManager(0), new RouletteWheelSelection());
4848
var children = childrenGenerator.GenerateChildren(GetPopulation(count), childrenCount, 0, null);
4949
Assert.AreEqual(childrenCount, children.Length, "Didn't get enough children");
5050
foreach (var chromosome in children)
@@ -57,7 +57,7 @@ public void RetusnRightNumberOfChromosomes(int childrenCount)
5757
[ExpectedException(typeof(BadMutationProbabilityException))]
5858
public void BadMutationProbability_ThrowException(double probability)
5959
{
60-
var mutationManager = A.Fake<IMutationManager>();
60+
var mutationManager = A.Fake<IMutationProbabilityManager>();
6161
A.CallTo(() => mutationManager.MutationProbability(A<Population>._, A<IEnvironment>._, A<int>._))
6262
.Returns(probability);
6363

@@ -71,7 +71,7 @@ public void BadMutationProbability_ThrowException(double probability)
7171
[DataRow(-1)]
7272
public void RequestBadNumberOfChildren_ThrowsException(int childrenCount)
7373
{
74-
var childrenGenerator = new ChildrenGenerator(A.Fake<ICrossoverManager>(), new BassicMutationManager(0),
74+
var childrenGenerator = new ChildrenGenerator(A.Fake<ICrossoverManager>(), new BassicMutationProbabilityManager(0),
7575
new RouletteWheelSelection());
7676
childrenGenerator.GenerateChildren(GetPopulation(1), childrenCount, 0, null);
7777
}
@@ -83,7 +83,7 @@ public void SelectionStrategyReturnsNull_ThrowsException()
8383
{
8484
var selectionStrategy = A.Fake<ISelectionStrategy>();
8585
A.CallTo(() => selectionStrategy.SelectChromosome()).Returns(null);
86-
var childrenGenerator = new ChildrenGenerator(A.Fake<ICrossoverManager>(), new BassicMutationManager(0),
86+
var childrenGenerator = new ChildrenGenerator(A.Fake<ICrossoverManager>(), new BassicMutationProbabilityManager(0),
8787
selectionStrategy);
8888
childrenGenerator.GenerateChildren(GetPopulation(1), 1, 0, null);
8989
}, typeof(GeneticAlgorithmException));
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
using System.Collections.Generic;
2+
using System.Linq;
3+
using FakeItEasy;
4+
using GeneticAlgorithm.Components.Chromosomes;
5+
using GeneticAlgorithm.Components.CrossoverManagers;
6+
using GeneticAlgorithm.Components.Interfaces;
7+
using GeneticAlgorithm.Components.PopulationGenerators;
8+
using GeneticAlgorithm.Interfaces;
9+
using Microsoft.VisualStudio.TestTools.UnitTesting;
10+
11+
namespace GeneticAlgorithm.UnitTests.Components
12+
{
13+
[TestClass]
14+
public class CrossoverManagerTests
15+
{
16+
private const int TEST_RUNS = 20;
17+
private const int SMALL_CHROMOSOME_SIZE = 10;
18+
private const int LARGE_CHROMOSOME_SIZE = 20;
19+
20+
private readonly IPopulationGenerator smallPopulationGenerator1 =
21+
new IntVectorChromosomePopulationGenerator(SMALL_CHROMOSOME_SIZE, 0, 10, A.Fake<IMutationManager<int>>(),
22+
A.Fake<IEvaluator>());
23+
private readonly IPopulationGenerator smallPopulationGenerator2 =
24+
new IntVectorChromosomePopulationGenerator(SMALL_CHROMOSOME_SIZE, 11, 20, A.Fake<IMutationManager<int>>(),
25+
A.Fake<IEvaluator>());
26+
private readonly IPopulationGenerator largePopulationGenerator =
27+
new IntVectorChromosomePopulationGenerator(LARGE_CHROMOSOME_SIZE, 21, 30, A.Fake<IMutationManager<int>>(),
28+
A.Fake<IEvaluator>());
29+
30+
[TestMethod]
31+
[DataRow(1)]
32+
[DataRow(2)]
33+
[DataRow(5)]
34+
[DataRow(SMALL_CHROMOSOME_SIZE - 1)]
35+
public void K_PointCrossoverTest(int k)
36+
{
37+
var crossoverManager = new K_PointCrossoverManager<int>(k, A.Fake<IMutationManager<int>>(), A.Fake<IEvaluator>());
38+
for (int i = 0; i < TEST_RUNS; i++)
39+
{
40+
var chromosome1 = (VectorChromosome<int>) smallPopulationGenerator1.GeneratePopulation(1).First();
41+
var chromosome2 = (VectorChromosome<int>) smallPopulationGenerator2.GeneratePopulation(1).First();
42+
var newChromosome = (VectorChromosome<int>) crossoverManager.Crossover(chromosome1, chromosome2);
43+
44+
var crossoverPoints = K_CrossoverGetCrossoverPointsAndAssertThatGenomesAreRight(newChromosome, chromosome2, chromosome1);
45+
Assert.AreEqual(k, crossoverPoints.Count,
46+
$"Found wrong number of crossoverPoints. 1: {chromosome1}; 2 {chromosome2}; newChromosome {newChromosome}");
47+
}
48+
}
49+
50+
[TestMethod]
51+
[DataRow(1)]
52+
[DataRow(2)]
53+
[DataRow(5)]
54+
[DataRow(SMALL_CHROMOSOME_SIZE - 1)]
55+
public void K_PointCrossover_ShortAndLongChromosomes(int k)
56+
{
57+
var crossoverManager = new K_PointCrossoverManager<int>(k, A.Fake<IMutationManager<int>>(), A.Fake<IEvaluator>());
58+
for (int i = 0; i < TEST_RUNS; i++)
59+
{
60+
var chromosome1 = (VectorChromosome<int>)smallPopulationGenerator1.GeneratePopulation(1).First();
61+
var chromosome2 = (VectorChromosome<int>)largePopulationGenerator.GeneratePopulation(1).First();
62+
var newChromosome = (VectorChromosome<int>)crossoverManager.Crossover(chromosome1, chromosome2);
63+
64+
var crossoverPoints = K_CrossoverGetCrossoverPointsAndAssertThatGenomesAreRight(newChromosome, chromosome2, chromosome1);
65+
Assert.AreEqual(k, crossoverPoints.Count,
66+
$"Found wrong number of crossoverPoints. 1: {chromosome1}; 2 {chromosome2}; newChromosome {newChromosome}");
67+
}
68+
}
69+
70+
[TestMethod]
71+
public void K_PointCrossover_CrossoverPointsAreDiffrent()
72+
{
73+
var crossoverPoints = new List<int>();
74+
var crossoverManager = new K_PointCrossoverManager<int>(2, A.Fake<IMutationManager<int>>(), A.Fake<IEvaluator>());
75+
for (int i = 0; i < 100; i++)
76+
{
77+
var chromosome1 = (VectorChromosome<int>)smallPopulationGenerator1.GeneratePopulation(1).First();
78+
var chromosome2 = (VectorChromosome<int>)smallPopulationGenerator2.GeneratePopulation(1).First();
79+
var newChromosome = (VectorChromosome<int>)crossoverManager.Crossover(chromosome1, chromosome2);
80+
81+
crossoverPoints.AddRange(K_CrossoverGetCrossoverPointsAndAssertThatGenomesAreRight(newChromosome, chromosome2, chromosome1));
82+
}
83+
84+
for (int i = 1; i < SMALL_CHROMOSOME_SIZE; i++)
85+
Assert.IsTrue(crossoverPoints.Contains(i), $"{nameof(crossoverPoints)} dosn't contain {i}");
86+
}
87+
88+
[TestMethod]
89+
public void SinglePointCrossoverManagerTest()
90+
{
91+
var crossoverManager = new SinglePointCrossoverManager<int>(A.Fake<IMutationManager<int>>(), A.Fake<IEvaluator>());
92+
for (int i = 0; i < TEST_RUNS; i++)
93+
{
94+
var chromosome1 = (VectorChromosome<int>)smallPopulationGenerator1.GeneratePopulation(1).First();
95+
var chromosome2 = (VectorChromosome<int>)smallPopulationGenerator2.GeneratePopulation(1).First();
96+
var newChromosome = (VectorChromosome<int>)crossoverManager.Crossover(chromosome1, chromosome2);
97+
98+
var crossoverPoints = K_CrossoverGetCrossoverPointsAndAssertThatGenomesAreRight(newChromosome, chromosome2, chromosome1);
99+
Assert.AreEqual(1, crossoverPoints.Count,
100+
$"Found wrong number of crossoverPoints. 1: {chromosome1}; 2 {chromosome2}; newChromosome {newChromosome}");
101+
}
102+
}
103+
104+
[TestMethod]
105+
public void UniformCrossoverManagerTest()
106+
{
107+
var crossoverManager = new UniformCrossoverManager<int>(A.Fake<IMutationManager<int>>(), A.Fake<IEvaluator>());
108+
for (int i = 0; i < TEST_RUNS; i++)
109+
{
110+
var chromosome1 = (VectorChromosome<int>)smallPopulationGenerator1.GeneratePopulation(1).First();
111+
var chromosome2 = (VectorChromosome<int>)smallPopulationGenerator2.GeneratePopulation(1).First();
112+
var newChromosome = (VectorChromosome<int>)crossoverManager.Crossover(chromosome1, chromosome2);
113+
114+
K_CrossoverGetCrossoverPointsAndAssertThatGenomesAreRight(newChromosome, chromosome2, chromosome1);
115+
}
116+
}
117+
118+
private static List<int> K_CrossoverGetCrossoverPointsAndAssertThatGenomesAreRight(VectorChromosome<int> newChromosome, VectorChromosome<int> chromosome2,
119+
VectorChromosome<int> chromosome1)
120+
{
121+
var crossoverPoints = new List<int>();
122+
var takingFromFirstChromosome = true;
123+
for (int i = 0; i < SMALL_CHROMOSOME_SIZE; i++)
124+
{
125+
if (takingFromFirstChromosome)
126+
{
127+
if (newChromosome[i] == chromosome2[i])
128+
{
129+
crossoverPoints.Add(i);
130+
takingFromFirstChromosome = !takingFromFirstChromosome;
131+
}
132+
else if (newChromosome[i] != chromosome1[i])
133+
Assert.Fail(
134+
$"Got Genome that dosn't seem to have came from anywhere. 1: {chromosome1}; 2 {chromosome2}; newChromosome {newChromosome} ");
135+
}
136+
else
137+
{
138+
if (newChromosome[i] == chromosome1[i])
139+
{
140+
crossoverPoints.Add(i);
141+
takingFromFirstChromosome = !takingFromFirstChromosome;
142+
}
143+
else if (newChromosome[i] != chromosome2[i])
144+
Assert.Fail(
145+
$"Got Genome that dosn't seem to have came from anywhere. 1: {chromosome1}; 2 {chromosome2}; newChromosome {newChromosome} ");
146+
}
147+
}
148+
for (int j = SMALL_CHROMOSOME_SIZE; j < LARGE_CHROMOSOME_SIZE && j < newChromosome.GetVector().Length; j++)
149+
{
150+
Assert.AreEqual(chromosome2[j], newChromosome[j]);
151+
}
152+
153+
return crossoverPoints;
154+
}
155+
}
156+
}

0 commit comments

Comments
 (0)