// the whole encode / decode process (just for learning purposes) void encode(WeightsInfo weightsInfo, List <double> gene) { for (int k = 0; k < weightsInfo.lstWeight.Count; k++) { for (int i = 0; i < weightsInfo.lstWeight[k].GetLength(0); i++) { for (int j = 0; j < weightsInfo.lstWeight[k].GetLength(1); j++) { gene.Add(weightsInfo.lstWeight[k][i, j]); } } } }
void decode(WeightsInfo weightsInfo, List <double> gene) { for (int k = 0; k < weightsInfo.lstWeight.Count; k++) { for (int i = 0; i < weightsInfo.lstWeight[k].GetLength(0); i++) { for (int j = 0; j < weightsInfo.lstWeight[k].GetLength(1); j++) { weightsInfo.lstWeight[k][i, j] = gene[0]; gene.RemoveAt(0); } } } }
public override ActionResult SubWeights(WeightsInfo input) { var termNumber = input.TermNumber; var weights = input.Weights; var totalWeights = State.TotalWeightsMap[termNumber]; Assert(totalWeights > 0, $"Invalid weights of term {termNumber}"); var newWeights = totalWeights - weights; State.TotalWeightsMap[termNumber] = newWeights; return(new ActionResult { Success = true }); }
public override SInt64Value AddWeights(WeightsInfo input) { var termNumber = input.TermNumber; var weights = input.Weights; var currentWeights = State.TotalWeightsMap[termNumber]; var finalWeights = currentWeights + weights; State.TotalWeightsMap[termNumber] = finalWeights; Context.LogDebug(() => $"Weights of term {termNumber}: {finalWeights}.[Add]"); return(new SInt64Value() { Value = finalWeights }); }
// creates a new candidate solution using crossover void crossover(List <double> gene1, List <double> gene2) { if (r.NextDouble() > CROSSOVER_RATE) { return; } List <double> descendant1 = new List <double>(); List <double> descendant2 = new List <double>(); int count; // mixing the genes using the arithmetic mean if (gene1.Count < gene2.Count) { count = gene1.Count; } else { count = gene2.Count; } for (int i = 0; i < count; i++) { descendant1.Add((gene1[i] + gene2[i]) / 2.0); descendant2.Add((gene1[i] + gene2[i]) / 2.0); } // decoding the result back to the "weights-format" WeightsInfo weightsInfo1 = new WeightsInfo(); decode(weightsInfo1, descendant1); nextWeightsList.Add(weightsInfo1); WeightsInfo weightsInfo2 = new WeightsInfo(); decode(weightsInfo2, descendant2); nextWeightsList.Add(weightsInfo2); }
public void breedNetworks(int gameIndex) { // updates the score weightsList[gameIndex].fitness = lstgame[gameIndex].GameTime + lstgame[gameIndex].Score; averageFitness += weightsList[gameIndex].fitness; maxFitness = maxFitness > weightsList[gameIndex].fitness ? maxFitness : weightsList[gameIndex].fitness; if (DataGame.IsAllGameFailed()) { generation++; Debug.WriteLine("GEN: " + generation + " | AVG: " + averageFitness / (float)POPULATION_SIZE + " | MAX: " + maxFitness); averageFitness = 0; maxFitness = 0; weightsList = weightsList.OrderByDescending(wi => wi.fitness).ToList(); // starting with a large mutation rate so there's will be more solutions to choose from if (weightsList[0].fitness < 10) { MUTATION_RATE = 0.9; } else if (weightsList[0].fitness < 50 && weightsList[0].fitness >= 10) { MUTATION_RATE = 0.2; } else { MUTATION_RATE = 0.05; } // adding better solutions from the other instances (if any) if (nextWeightsList.Count + 3 <= POPULATION_SIZE) { // the whole synchronization thingy try { if (mmfMutex == null) { mmfMutex = Mutex.OpenExisting("mmfMutex"); } if (mmfMutex.WaitOne()) { WeightsInfo wi = new WeightsInfo(); wi = dataSharer.getFromMemoryMap(); if (wi == null || wi.fitness < weightsList[0].fitness) { if (wi == null) { Debug.WriteLine("Updated - NULL -> " + weightsList[0].fitness); } if (wi != null) { Debug.WriteLine("Updated - " + wi.fitness + " -> " + weightsList[0].fitness); } dataSharer.writeToMemoryMap(weightsList[0]); } if (wi != null && wi.fitness > weightsList[0].fitness) { nextWeightsList.Add(wi); } mmfMutex.ReleaseMutex(); } } catch (WaitHandleCannotBeOpenedException ex) { mmfMutex = new Mutex(true, "mmfMutex"); nextWeightsList.AddRange(weightsList.Take(4)); mmfMutex.ReleaseMutex(); } // adding elites to the next generation nextWeightsList.AddRange(weightsList.Take(3)); } // creating a new generation while (nextWeightsList.Count < POPULATION_SIZE) { WeightsInfo w1 = select(); WeightsInfo w2 = select(); while (w1 == w2) { w1 = select(); w2 = select(); } List <double> gene1 = new List <double>(); List <double> gene2 = new List <double>(); encode(w1, gene1); encode(w2, gene2); crossover(gene1, gene2); if (mutate(gene1)) { w1 = new WeightsInfo(); } if (mutate(gene2)) { w2 = new WeightsInfo(); } decode(w1, gene1); decode(w2, gene2); if (!nextWeightsList.Contains(w1)) { nextWeightsList.Add(w1); } if (!nextWeightsList.Contains(w2)) { nextWeightsList.Add(w2); } } weightsList.Clear(); nextWeightsList = nextWeightsList.OrderByDescending(wi => wi.fitness).ToList(); weightsList.AddRange(nextWeightsList); nextWeightsList.Clear(); } }