/
Evolve.cs
124 lines (112 loc) · 3.96 KB
/
Evolve.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
using System;
using System.Collections.Generic;
namespace gen{
internal class Evolve{
public const int INF = 99999999;
private readonly int _height;
private readonly int _mutationChance;
private readonly int _popSize;
private readonly int _freshSize;
private readonly SortedList<float, Network> _rated = new SortedList<float, Network>();
private readonly int _survivedSize;
private float _best = INF;
private readonly List<float[]> _tests = new List<float[]>();
private Network[] _population;
public Evolve(){
_popSize = 2000;
_freshSize = 500;
_survivedSize = 500;
_mutationChance = 50;
InitPopulation();
}
public void AddTest(float[] test){
_tests.Add(test);
}
public void Iteration(){
Rate();
//System.Console.Out.WriteLine(_best);
for (int i = 0; i < _popSize; i++){
//System.Console.Out.Write(_population[i].Height());
//System.Console.Out.Write(" ");
}
//System.Console.Out.WriteLine();
//System.Console.In.ReadLine();
Select();
//System.Console.In.ReadLine();
Breed();
}
private void InitPopulation(){
_population = new Network[_popSize];
for (int i = 0; i < _popSize; i++){
_population[i] = new Network();
}
}
private bool AddToRated(float rating, Network n){
try{
_rated.Add(rating, n);
return true;
}
catch (Exception e){
return false;
}
}
private void Rate(){
_rated.Clear();
for (int i = 0; i < _popSize; i++){
float rating = RateNetwork(_population[i]);
if (rating < _best){
if(_best - rating > 1){
System.Console.Out.WriteLine(rating);
}
_best = rating;
}
AddToRated(rating, _population[i]);
}
}
private float RateNetwork(Network network){
float rating = 0;
foreach (var test in _tests){
float eval = network.Calculate(test) - test[0];
rating += Math.Abs(eval);
}
return rating;
}
private void Select(){
IEnumerator<KeyValuePair<float, Network>> it = _rated.GetEnumerator();
int i = 0;
while (it.MoveNext() && i++ <= _survivedSize){
_population[i] = it.Current.Value;
}
}
private int RandomParentId(int secondParent, bool best){
double parent = Program.RandomGenerator.NextDouble();
if (best) {
parent *= _survivedSize;
} else{
parent *= (_population.Length - 1);
}
int result = (int) parent;
if (result == secondParent){
result = (result + 1)%_survivedSize;
}
return result;
}
private void Breed(){
for (int i = _survivedSize; i + 1 < _popSize - _freshSize; i += 2){
int p1 = RandomParentId(INF,true);
int p2 = RandomParentId(p1,false);
_population[i] = new Network(_population[p1]);
_population[i + 1] = new Network(_population[p2]);
Network.Crossover(_population[i], _population[i + 1]);
}
for (int i = _popSize - _freshSize; i < _popSize; i++){
_population[i] = new Network();
}
for (int i = 0; i < _popSize - _freshSize; i++){
if (Program.RandomGenerator.Next()%100 < _mutationChance){
_population[i].Mutate();
}
}
}
}
}