-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathIsland.cs
More file actions
132 lines (111 loc) · 4.37 KB
/
Island.cs
File metadata and controls
132 lines (111 loc) · 4.37 KB
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
125
126
127
128
129
130
131
132
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
[System.Serializable]
public class Island
{
public int id;
public List<Individual> population;
public GeneticOperations geneticOps;
public System.Random random;
public SimulatedAnnealingGP simAnneal;
public AdaptiveParameterController adaptiveController;
public float mutationRate;
public float complexityWeight;
public int initialMaxDepth;
private List<float> recentBestFitness;
public Island(int islandId, int popSize, float mutRate, float compWeight, int maxDepth)
{
id = islandId;
mutationRate = mutRate;
complexityWeight = compWeight;
initialMaxDepth = maxDepth;
random = new System.Random(islandId * 1000);
geneticOps = new GeneticOperations(islandId * 1000);
simAnneal = new SimulatedAnnealingGP();
simAnneal.Initialize();
adaptiveController = new AdaptiveParameterController();
recentBestFitness = new List<float>();
population = new List<Individual>();
for (int i = 0; i < popSize; i++)
{
ExpressionNode tree = geneticOps.GenerateRandomTree(initialMaxDepth);
population.Add(new Individual(tree));
}
}
public void EvolveGeneration(float[] inputData, float[] outputData, float deathRate, int eliteCount)
{
foreach (Individual ind in population)
{
ind.CalculateFitness(inputData, outputData, complexityWeight);
}
population.Sort();
population.Reverse();
recentBestFitness.Add(population[0].fitness);
if (recentBestFitness.Count > 20)
recentBestFitness.RemoveAt(0);
if (recentBestFitness.Count >= 5 && recentBestFitness.Count % 5 == 0)
{
float diversity = adaptiveController.MeasureDiversity(population);
float progress = adaptiveController.MeasureProgress(recentBestFitness);
mutationRate = adaptiveController.AdaptMutationRate(mutationRate, diversity, progress);
float avgComplexity = population.Average(ind => ind.complexity);
complexityWeight = adaptiveController.AdaptComplexityWeight(
complexityWeight, avgComplexity, initialMaxDepth * 2);
}
int killCount = Mathf.FloorToInt(population.Count * deathRate);
int surviveCount = population.Count - killCount;
List<Individual> nextGen = new List<Individual>();
for (int i = 0; i < eliteCount && i < surviveCount; i++)
{
nextGen.Add(population[i].Clone());
}
while (nextGen.Count < population.Count)
{
double reproductionType = random.NextDouble();
Individual child;
if (reproductionType < 0.7)
{
Individual parent1 = TournamentSelection(5);
Individual parent2 = TournamentSelection(5);
child = geneticOps.Crossover(parent1, parent2);
}
else
{
Individual parent = TournamentSelection(5);
child = parent.Clone();
if (random.NextDouble() < mutationRate)
{
ApplyRandomMutation(child);
}
}
child.CalculateFitness(inputData, outputData, complexityWeight);
nextGen.Add(child);
}
simAnneal.CoolDown();
population = nextGen;
}
private void ApplyRandomMutation(Individual child)
{
double mutType = random.NextDouble();
if (mutType < 0.25)
geneticOps.MutateConstant(child.root, 1f);
else if (mutType < 0.5)
geneticOps.MutateSubtree(child.root, 3);
else if (mutType < 0.75)
geneticOps.MutateDelete(child.root);
else
geneticOps.MutateSimplify(child.root);
}
private Individual TournamentSelection(int tournamentSize)
{
Individual best = null;
for (int i = 0; i < tournamentSize; i++)
{
Individual candidate = population[random.Next(population.Count)];
if (best == null || candidate.fitness > best.fitness)
best = candidate;
}
return best;
}
}