Skip to content

Commit 43b4376

Browse files
committed
Replaced Dictionary with IList and Adapted Code to it
This is because the HashTables in the Dictionary are auto-adjusting the Keys in a way that it could mess up the Algorithm, and when using foreach to, for example, read out the best 10 networks to display them or so, it would then sometimes return random 10 networks in the foreach
1 parent ee60cde commit 43b4376

File tree

7 files changed

+38
-36
lines changed

7 files changed

+38
-36
lines changed

NeuralBotMasterFramework/NeuralBotMasterFramework/Interfaces/IBreedingPoolGenerator.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,6 @@ namespace NeuralBotMasterFramework.Interfaces
88
{
99
public interface IBreedingPoolGenerator
1010
{
11-
List<IWeightedNetwork> GenerateBreedingPool(Dictionary<IWeightedNetwork, double> networksAndFitness);
11+
List<IWeightedNetwork> GenerateBreedingPool(IList<KeyValuePair<IWeightedNetwork, double>> networksAndFitness);
1212
}
1313
}

NeuralBotMasterFramework/NeuralBotMasterFramework/Interfaces/IGeneticAlgorithm.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ public interface IGeneticAlgorithm
2424
double[][] CurrentInput { get; }
2525
double[][] CurrentExpected { get; }
2626

27-
Dictionary<IWeightedNetwork, double> NetworksAndFitness { get; }
27+
IList<KeyValuePair<IWeightedNetwork, double>> NetworksAndFitness { get; }
2828
void SetupTest(double[][] input, double[][] expected);
2929
void PropagateAllNetworks();
3030
void SortByFitness();

NeuralBotMasterFramework/NeuralBotMasterFramework/Logic/Algorithms/GeneticAlgorithm.cs

Lines changed: 24 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ public class GeneticAlgorithm : IGeneticAlgorithm
1717
public int RandomNetworkAmount { get; set; }
1818
public double MutationRate { get; set; }
1919
public double MutationChance { get; set; }
20-
public Dictionary<IWeightedNetwork, double> NetworksAndFitness { get; private set; } = new Dictionary<IWeightedNetwork, double>();
20+
public IList<KeyValuePair<IWeightedNetwork, double>> NetworksAndFitness { get; private set; } = new List<KeyValuePair<IWeightedNetwork, double>>();
2121
public int InputNodes { get; }
2222
public int HiddenNodes { get; }
2323
public int HiddenLayers { get; }
@@ -51,7 +51,7 @@ private void AddNewNetworks(int amount)
5151

5252
private void AddNewNetwork()
5353
{
54-
NetworksAndFitness.Add(new WeightedNetwork(InputNodes, HiddenLayers, HiddenNodes, OutputNodes) { ID = internalIdCounter}, 0);
54+
NetworksAndFitness.Add(new KeyValuePair<IWeightedNetwork, double>(new WeightedNetwork(InputNodes, HiddenLayers, HiddenNodes, OutputNodes) { ID = internalIdCounter }, 0));
5555
++internalIdCounter;
5656
}
5757

@@ -66,10 +66,10 @@ public void PropagateAllNetworks()
6666
ResetAllFitnesses();
6767
for (int inputIndex = 0; inputIndex < CurrentInput.Length; inputIndex++)
6868
{
69-
foreach (IWeightedNetwork network in NetworksAndFitness.Keys)
69+
foreach (KeyValuePair<IWeightedNetwork, double> networkAndFitness in NetworksAndFitness)
7070
{
71-
network.SetInput(CurrentInput[inputIndex]);
72-
network.Propagate();
71+
networkAndFitness.Key.SetInput(CurrentInput[inputIndex]);
72+
networkAndFitness.Key.Propagate();
7373
}
7474
if (CurrentExpectedIsSet())
7575
{
@@ -85,17 +85,17 @@ private bool CurrentExpectedIsSet()
8585

8686
private void ResetAllFitnesses()
8787
{
88-
Dictionary<IWeightedNetwork, double> tempNetworkAndFitness = new Dictionary<IWeightedNetwork, double>();
89-
foreach (IWeightedNetwork network in NetworksAndFitness.Keys)
88+
IList<KeyValuePair<IWeightedNetwork, double>> tempNetworkAndFitness = new List<KeyValuePair<IWeightedNetwork, double>>();
89+
foreach (KeyValuePair<IWeightedNetwork, double> networkAndFitness in NetworksAndFitness)
9090
{
91-
tempNetworkAndFitness.Add(network, 0);
91+
tempNetworkAndFitness.Add(new KeyValuePair<IWeightedNetwork, double>(networkAndFitness.Key, 0));
9292
}
9393
NetworksAndFitness = tempNetworkAndFitness;
9494
}
9595

9696
private void CalculateFitnesses(double[] expected)
9797
{
98-
Dictionary<IWeightedNetwork, double> tempNetworkAndFitness = new Dictionary<IWeightedNetwork, double>();
98+
IList<KeyValuePair<IWeightedNetwork, double>> tempNetworkAndFitness = new List<KeyValuePair<IWeightedNetwork, double>>();
9999
foreach (KeyValuePair<IWeightedNetwork, double> networkAndFitness in NetworksAndFitness)
100100
{
101101
double fitness = networkAndFitness.Value;
@@ -104,14 +104,14 @@ private void CalculateFitnesses(double[] expected)
104104
{
105105
fitness += 1 / (Math.Pow(output[i] - expected[i], 2) + 1);
106106
}
107-
tempNetworkAndFitness.Add(networkAndFitness.Key, fitness);
107+
tempNetworkAndFitness.Add(new KeyValuePair<IWeightedNetwork, double>(networkAndFitness.Key, fitness));
108108
}
109109
NetworksAndFitness = tempNetworkAndFitness;
110110
}
111111

112112
public void SortByFitness()
113113
{
114-
NetworksAndFitness = NetworksAndFitness.OrderByDescending(x => x.Value).ToDictionary(x => x.Key, x => x.Value);
114+
NetworksAndFitness = NetworksAndFitness.OrderByDescending(x => x.Value).ToList();
115115
}
116116

117117
public void BreedBestNetworks()
@@ -123,13 +123,13 @@ public void BreedBestNetworks()
123123

124124
private void RemoveUnneccessaryNetworks()
125125
{
126-
List<KeyValuePair<IWeightedNetwork, double>> tempNetworkAndFitnessToKeep = NetworksAndFitness.Take(NetworksToKeep).ToList();
127-
NetworksAndFitness = tempNetworkAndFitnessToKeep.ToDictionary(x => x.Key, x => x.Value);
126+
IList<KeyValuePair<IWeightedNetwork, double>> tempNetworkAndFitnessToKeep = NetworksAndFitness.Take(NetworksToKeep).ToList();
127+
NetworksAndFitness = tempNetworkAndFitnessToKeep.ToList();
128128
}
129129

130130
private void BreedNewNetworks()
131131
{
132-
List<IWeightedNetwork> networkAndLikelinesToBreed = GetBreedingPool();
132+
IList<IWeightedNetwork> networkAndLikelinesToBreed = GetBreedingPool();
133133
AddNewNetworks(RandomNetworkAmount);
134134
BreedNetworks(networkAndLikelinesToBreed);
135135
}
@@ -139,13 +139,13 @@ private List<IWeightedNetwork> GetBreedingPool()
139139
return PoolGenerator.GenerateBreedingPool(NetworksAndFitness);
140140
}
141141

142-
private void BreedNetworks(List<IWeightedNetwork> networkAndLikelinesToBreed)
142+
private void BreedNetworks(IList<IWeightedNetwork> networkAndLikelinesToBreed)
143143
{
144144
while (NetworksAndFitness.Count < TotalNetworks)
145145
{
146146
int networkIndex = RandomNumberGenerator.GetNextNumber(0, networkAndLikelinesToBreed.Count - 1);
147147
IWeightedNetwork network = BreedNewNetwork(networkAndLikelinesToBreed[networkIndex]);
148-
NetworksAndFitness.Add(network, 0);
148+
NetworksAndFitness.Add(new KeyValuePair<IWeightedNetwork, double>(network, 0));
149149
}
150150
}
151151

@@ -214,18 +214,18 @@ private void MutateNetwork(IWeightedNetwork network)
214214

215215
public double[] GetFitnesses()
216216
{
217-
return NetworksAndFitness.Values.ToArray();
217+
return NetworksAndFitness.Select(x => x.Value).ToArray();
218218
}
219219

220220
public void SetFitnesses(double[] fitnesses)
221221
{
222222
ThrowIfArgumentDoesNotHaveCorrectLength(fitnesses, TotalNetworks);
223223

224-
Dictionary<IWeightedNetwork, double> tempFitnessAndValues = new Dictionary<IWeightedNetwork, double>();
224+
IList<KeyValuePair<IWeightedNetwork, double>> tempFitnessAndValues = new List<KeyValuePair<IWeightedNetwork, double>>();
225225
for (int i = 0; i < fitnesses.Length; ++i)
226226
{
227227
IWeightedNetwork network = NetworksAndFitness.ElementAt(i).Key;
228-
tempFitnessAndValues.Add(network, fitnesses[i]);
228+
tempFitnessAndValues.Add(new KeyValuePair<IWeightedNetwork, double>(network, fitnesses[i]));
229229
}
230230
NetworksAndFitness = tempFitnessAndValues;
231231
}
@@ -240,18 +240,20 @@ private void ThrowIfArgumentDoesNotHaveCorrectLength(double[] array, int expecte
240240

241241
public void SetFitness(int networkIndex, double fitness)
242242
{
243-
SetFitness(NetworksAndFitness.Keys.ElementAt(networkIndex), fitness);
243+
SetFitness(NetworksAndFitness.Select(x => x.Key).ElementAt(networkIndex), fitness);
244244
}
245245

246246
public void SetFitness(IWeightedNetwork network, double fitness)
247247
{
248248
ThrowIfNetworkNotInDictionary(network);
249-
NetworksAndFitness[network] = fitness;
249+
KeyValuePair<IWeightedNetwork, double> temp = NetworksAndFitness.FirstOrDefault(x => x.Key == network);
250+
int index = NetworksAndFitness.IndexOf(temp);
251+
NetworksAndFitness[index] = new KeyValuePair<IWeightedNetwork, double>(network, fitness);
250252
}
251253

252254
private void ThrowIfNetworkNotInDictionary(IWeightedNetwork network)
253255
{
254-
if (!NetworksAndFitness.Keys.Contains(network))
256+
if (!NetworksAndFitness.Select(x => x.Key).Contains(network))
255257
{
256258
throw new ArgumentException($"Network not found inside {nameof(NetworksAndFitness)}");
257259
}

NeuralBotMasterFramework/NeuralBotMasterFramework/Logic/PoolGenerators/FitnessBasedPoolGenerator.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,10 @@ namespace NeuralBotMasterFramework.Logic.PoolGenerators
1010
{
1111
public class FitnessBasedPoolGenerator : IBreedingPoolGenerator
1212
{
13-
public List<IWeightedNetwork> GenerateBreedingPool(Dictionary<IWeightedNetwork, double> networksAndFitness)
13+
public List<IWeightedNetwork> GenerateBreedingPool(IList<KeyValuePair<IWeightedNetwork, double>> networksAndFitness)
1414
{
1515
List<IWeightedNetwork> poolList = new List<IWeightedNetwork>();
16-
double[] fitnesses = MultiplyUntilBiggerThanOne(networksAndFitness.Values.ToArray());
16+
double[] fitnesses = MultiplyUntilBiggerThanOne(networksAndFitness.Select(x => x.Value).ToArray());
1717
int totalFitness = (int)Math.Round(fitnesses.Sum(), 0, MidpointRounding.AwayFromZero);
1818
for (int networkIndex = 0; networkIndex < networksAndFitness.Count; ++networkIndex)
1919
{

NeuralBotMasterFramework/NeuralBotMasterFramework/Logic/PoolGenerators/IndexBasedPoolGenerator.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,12 @@ namespace NeuralBotMasterFramework.Logic.PoolGenerators
99
{
1010
public class IndexBasedPoolGenerator : IBreedingPoolGenerator
1111
{
12-
public List<IWeightedNetwork> GenerateBreedingPool(Dictionary<IWeightedNetwork, double> networksAndFitness)
12+
public List<IWeightedNetwork> GenerateBreedingPool(IList<KeyValuePair<IWeightedNetwork, double>> networksAndFitness)
1313
{
1414
List<IWeightedNetwork> poolList = new List<IWeightedNetwork>();
1515
for (int networkIndex = 0; networkIndex < networksAndFitness.Count; ++networkIndex)
1616
{
17-
IWeightedNetwork currentNetwork = networksAndFitness.Keys.ElementAt(networkIndex);
17+
IWeightedNetwork currentNetwork = networksAndFitness.Select(x => x.Key).ElementAt(networkIndex);
1818
for (int i = 0; i < networksAndFitness.Count - networkIndex; ++i)
1919
{
2020
poolList.Add(currentNetwork);

NeuralBotMasterFramework/NeuralBotMasterFrameworkTests/Logic/Algorithms/GeneticAlgorithmTests.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ public void PropagateAllNetworksTest()
107107
{
108108
Algorithm.SetupTest(Input, Expected);
109109
Algorithm.PropagateAllNetworks();
110-
foreach (IWeightedNetwork network in Algorithm.NetworksAndFitness.Keys)
110+
foreach (IWeightedNetwork network in Algorithm.NetworksAndFitness.Select(x => x.Key))
111111
{
112112
foreach (IWeightedNode node in network.OutputLayer.Nodes)
113113
{
@@ -121,7 +121,7 @@ public void PropagateAllNetworksTest_NoExpectedInput()
121121
{
122122
Algorithm.SetupTest(Input);
123123
Algorithm.PropagateAllNetworks();
124-
foreach (IWeightedNetwork network in Algorithm.NetworksAndFitness.Keys)
124+
foreach (IWeightedNetwork network in Algorithm.NetworksAndFitness.Select(x => x.Key))
125125
{
126126
foreach (IWeightedNode node in network.OutputLayer.Nodes)
127127
{
@@ -142,7 +142,7 @@ public void SortByFitnessTest()
142142
double previousHighestNumber = Algorithm.NetworksAndFitness.FirstOrDefault().Value;
143143
for (int i = 1; i < Algorithm.NetworksAndFitness.Count; ++i)
144144
{
145-
double currentValue = Algorithm.NetworksAndFitness.Values.ElementAt(i);
145+
double currentValue = Algorithm.NetworksAndFitness.Select(x => x.Value).ElementAt(i);
146146
Assert.IsTrue(previousHighestNumber > currentValue);
147147
previousHighestNumber = currentValue;
148148
}
@@ -161,7 +161,7 @@ public void BreedBestNetworksTest()
161161
Algorithm.BreedBestNetworks();
162162

163163
Assert.AreEqual(TOTAL_NETWORKS, Algorithm.NetworksAndFitness.Count);
164-
foreach (IWeightedNetwork network in Algorithm.NetworksAndFitness.Keys)
164+
foreach (IWeightedNetwork network in Algorithm.NetworksAndFitness.Select(x => x.Key))
165165
{
166166
Assert.IsNotNull(network);
167167
}
@@ -210,7 +210,7 @@ private double[] GetRandomDoubleArray(int totalValues)
210210
public void SetFitness_IWeightedNetworkAsParameter()
211211
{
212212
double newValue = RandomNumberGenerator.GetNextDouble();
213-
IWeightedNetwork network = Algorithm.NetworksAndFitness.Keys.ElementAt(0);
213+
IWeightedNetwork network = Algorithm.NetworksAndFitness.Select(x => x.Key).ElementAt(0);
214214
Algorithm.SetFitness(network, newValue);
215215
Assert.AreEqual(newValue, Algorithm.NetworksAndFitness.FirstOrDefault(x => x.Key == network).Value);
216216
}
@@ -229,7 +229,7 @@ public void SetFitness_NetworkIndexAsParameter()
229229
int index = RandomNumberGenerator.GetNextNumber(0, Algorithm.NetworksAndFitness.Count);
230230
double newFitnessValue = RandomNumberGenerator.GetNextDouble();
231231
Algorithm.SetFitness(index, newFitnessValue);
232-
KeyValuePair<IWeightedNetwork, double> networkAndFitness = Algorithm.NetworksAndFitness.ElementAt(index);
232+
KeyValuePair<IWeightedNetwork, double> networkAndFitness = Algorithm.NetworksAndFitness[index];
233233
Assert.AreEqual(newFitnessValue, networkAndFitness.Value);
234234
}
235235
}

NeuralBotMasterFramework/NeuralBotMasterFrameworkTests/Logic/PoolGenerators/FitnessBasedPoolGeneratorTests.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ public void GenerateBreedingPoolTest()
3030
algorithm.PropagateAllNetworks();
3131
algorithm.SortByFitness();
3232
FitnessBasedPoolGenerator generator = new FitnessBasedPoolGenerator();
33-
List<IWeightedNetwork> networkList = generator.GenerateBreedingPool(algorithm.NetworksAndFitness.Take(NETWORKS_TO_KEEP).ToDictionary(x => x.Key, x => x.Value));
33+
List<IWeightedNetwork> networkList = generator.GenerateBreedingPool(algorithm.NetworksAndFitness.Take(NETWORKS_TO_KEEP).ToList());
3434
Assert.IsTrue(networkList.Count > 0);
3535
}
3636

@@ -40,7 +40,7 @@ public void GenerateBreedingPool_ZeroFitnessScore_ShouldIgnoreZeroFitnesses()
4040
{
4141
algorithm.SetFitness(0, 100);
4242
IBreedingPoolGenerator generator = new FitnessBasedPoolGenerator();
43-
List<IWeightedNetwork> networkList = generator.GenerateBreedingPool(algorithm.NetworksAndFitness.Take(NETWORKS_TO_KEEP).ToDictionary(x => x.Key, x => x.Value));
43+
List<IWeightedNetwork> networkList = generator.GenerateBreedingPool(algorithm.NetworksAndFitness.Take(NETWORKS_TO_KEEP).ToList());
4444
Assert.IsTrue(networkList.Count > 0);
4545
}
4646

0 commit comments

Comments
 (0)