private bool fitnessAlreadyMeasured() { //FITNESS ALREADY MEASURED newSpecies species = Pool.species[Pool.currentSpecies]; newGenome genome = species.genomes[Pool.currentGenome]; return(genome.fitness != 0); }
private bool sameSpecies(newGenome genome1, newGenome genome2) { //SAME SPECIES double dd = DeltaDisjoint * disjoint(genome1.genes, genome2.genes); double dw = DeltaWeights * weights(genome1.genes, genome2.genes); return(dd + dw < DeltaThreshold); }
private void initializeRun() { //INITIALIZE RUN Score = 0; clearJoypad(); newSpecies species = Pool.species[Pool.currentSpecies]; newGenome genome = species.genomes[Pool.currentGenome]; generateNetwork network = new generateNetwork(genome); evaluateCurrent(); }
private void calculateAverageFitness(newSpecies species) { //CALCULATE AVERAGE FITNESS double total = 0; for (int i = 0; i < species.genomes.Count; i++) { newGenome genome = species.genomes[i]; total = total + genome.globalRank; } //SET SPECIES FITNESS species.averageFitness = total / species.genomes.Count; }
private void newGeneration() { //NEW GENERATION cullSpecies(false); //CULL THE BOTTOM HALF OF EACH SPECIES rankGlobally(); removeStaleSpecies(); rankGlobally(); for (int i = 0; i < Pool.species.Count; i++) { newSpecies species = Pool.species[i]; calculateAverageFitness(species); } //REMOVE WEAK SPECIES removeWeakSpecies(); double sum = totalAverageFitness(); List <newGenome> children = new List <newGenome>(); for (int i = 0; i < Pool.species.Count; i++) { newSpecies species = Pool.species[i]; double breed = Math.Floor(species.averageFitness / sum * Population) - 1; for (double d = 0; d < breed; d++) //DOUBLE LOOP { children.Add(breedChild(species)); } } cullSpecies(true); //CULL ALL BUT THE TOP MEMBER OF EACH SPECIES while (children.Count + Pool.species.Count < Population) { newSpecies species = Pool.species[Random(0, Pool.species.Count - 1)]; children.Add(breedChild(species)); } for (int i = 0; i < children.Count; i++) { newGenome child = children[i]; addToSpecies(child); } //RAISE POOL GENERATION Pool.generation = Pool.generation + 1; //GENERATE BACKUP FILE //writeFile("backup."..pool.generation.. "."..forms.gettext(saveLoadFile)) }
private void evaluateCurrent() { //ABBRUCH if (!NetMain.Cam.Visible) { return; } //EVALUATE CURRENT newSpecies species = Pool.species[Pool.currentSpecies]; newGenome genome = species.genomes[Pool.currentGenome]; List <double> inputs = Mod_Convert.ArrayToList <double>(NetMain.Cam.getDoubleArray()); //READ INPUTS FROM CAM Controller = genome.network.evaluateNetwork(inputs); //GET OUTPUTS }
private newGenome crossover(newGenome g1, newGenome g2) { //MAKE SURE G1 IS THE HIGHER FITNESS GENOME if (g2.fitness > g1.fitness) { newGenome tempg = g1; g1 = g2; g2 = tempg; } newGenome child = new newGenome(); Dictionary <int, newGene> innovations2 = new Dictionary <int, newGene>(); for (int i = 0; i < g2.genes.Count; i++) { newGene gene = g2.genes[i]; innovations2[gene.innovation] = gene; } for (int i = 0; i < g1.genes.Count; i++) { newGene gene1 = g1.genes[i]; newGene gene2 = innovations2[gene1.innovation]; //COPY GENE1 OR GENE2 if (gene2 != null && Random(1, 2) == 1 && gene2.enabled) { child.genes.Add(gene2.Copy()); } else { child.genes.Add(gene1.Copy()); } } //GET MAXIMUM child.maxneuron = Max(g1.maxneuron, g2.maxneuron); foreach (KeyValuePair <string, double> item in g1.mutationRates) { child.mutationRates[item.Key] = item.Value; } return(child); }
private void initializePool(bool xLoad = false) { //INITIALIZE POOL Pool = new newPool(); //ABBRUCH if (xLoad) { return; } for (int i = 0; i < Population; i++) { newGenome basic = newGenome.basicGenome(this); addToSpecies(basic); } //INITIALIZE RUN initializeRun(); }
private void pointMutate(newGenome genome) { //POINT MUTATE double step = genome.mutationRates["step"]; //LOOP GENES if (genome.genes != null) { for (int i = 0; i < genome.genes.Count; i++) { if (Random() < PerturbChance) { genome.genes[i].weight = genome.genes[i].weight + Random() * step * 2 - step; } else { genome.genes[i].weight = Random() * 4 - 2; } } } }
private newGenome breedChild(newSpecies species) { //BREED CHILD newGenome child; if (Random() < CrossoverChance) { newGenome g1 = species.genomes[Random(0, species.genomes.Count - 1)]; newGenome g2 = species.genomes[Random(0, species.genomes.Count - 1)]; child = crossover(g1, g2); } else { newGenome g = species.genomes[Random(0, species.genomes.Count - 1)]; child = g.copyGenome(); } //MUTATE CHILD mutate(child); return(child); }
private void displayGenome(newGenome genome) { //DISPLAY GENOME generateNetwork network = genome.network; List <int[]> cells = new List <int[]>(); int[] cell; int i = 1; for (int dy = -BoxSize.Height; dy < BoxSize.Height; dy++) { for (int dx = -BoxSize.Width; dx < BoxSize.Width; dx++) { cell = new int[] { 50 + 5 * dx, 70 + 5 * dy, (int)network.neurons[i].value }; cells.Add(cell); i = i + 1; } int[] biasCell = new int[] { 80, 110, (int)network.neurons[InputsCount].value }; cells[InputsCount] = biasCell; } }
private void linkMutate(newGenome genome, bool forceBias) { //LINK MUTATE int neuron1 = randomNeuron(genome.genes, false); int neuron2 = randomNeuron(genome.genes, true); newGene newLink = new newGene(); if (neuron1 <= InputsCount && neuron2 <= InputsCount) //BOTH INPUT NODES { return; } if (neuron2 <= InputsCount) //SWAP OUTPUT AND INPUT { int temp = neuron1; neuron1 = neuron2; neuron2 = temp; } newLink.into = neuron1; newLink.output = neuron2; if (forceBias) { newLink.into = InputsCount; } if (containsLink(genome.genes, newLink)) { return; } newLink.innovation = newInnovation(Pool); newLink.weight = Random() * 4 - 2; //ADD TO GENES LIST genome.genes.Add(newLink); }
private void nodeMutate(newGenome genome) { //NODE MUTATE if (genome.genes.Count == 0) { return; } genome.maxneuron = genome.maxneuron + 1; //GET RANDOM GENE newGene gene = genome.genes[Random(0, genome.genes.Count - 1)]; if (!gene.enabled) //IF FALSE RETURN { return; } gene.enabled = false; //ADD GENE1 newGene gene1 = gene.Copy(); gene1.output = genome.maxneuron; gene1.weight = 1.0; gene1.innovation = newInnovation(Pool); gene1.enabled = true; genome.genes.Add(gene1); //ADD GENE2 newGene gene2 = gene.Copy(); gene2.into = genome.maxneuron; gene2.innovation = newInnovation(Pool); gene2.enabled = true; genome.genes.Add(gene2); }
private void addToSpecies(newGenome child) { //ADD TO SPECIES bool foundSpecies = false; //LOOP AND SEARCH POOL SPECIES for (int i = 0; i < Pool.species.Count; i++) { newSpecies species = Pool.species[i]; if (!foundSpecies && sameSpecies(child, species.genomes[0])) { species.genomes.Add(child); foundSpecies = true; } } //SPECIES NOT FOUND if (!foundSpecies) { newSpecies childSpecies = new newSpecies(); childSpecies.genomes.Add(child); Pool.species.Add(childSpecies); } }
private void enableDisableMutate(newGenome genome, bool enable) { //ENABLE DISABLE MUTATE List <newGene> candidates = new List <newGene>(); //GET ENABLES GENES foreach (newGene item in genome.genes) { if (item.enabled == !enable) { candidates.Add(item); } } if (candidates.Count == 0) { return; } //GET RANDOM GENE FROM CANIDATES newGene gene = candidates[Random(0, candidates.Count - 1)]; gene.enabled = !gene.enabled; }
public generateNetwork(newGenome genome) { //INPUTS for (int i = 0; i < InputsCount; i++) { neurons[i] = new newNeuron(); } //OUTPUTS for (int i = 0; i < OutputsCount; i++) { neurons[MaxNodes + i] = new newNeuron(); } genome.genes.Sort(); //table.sort(genome.genes, function(a, b) return (a.output < b.output) end) for (int i = 0; i < genome.genes.Count; i++) { newGene gene = genome.genes[i]; if (gene.enabled) { if (!neurons.Keys.Contains(gene.output)) { neurons[gene.output] = new newNeuron(); } newNeuron neuron = neurons[gene.output]; neuron.incoming.Add(gene); if (!neurons.Keys.Contains(gene.into)) { neurons[gene.into] = new newNeuron(); } } genome.network = this; } }
public void Plot(Graphics g) { Pool = Main.Mario.Pool; //ABBRUCH if (Pool == null) { return; } //RECALCULATE NEUROEVOLUTION RecalculateNeuroevolution(Pool); //GET SPCIES LIST List <newSpecies> spciesList = Pool.species; for (int i = 0; i < spciesList.Count; i++) { float width = PanelLeft[2] + getScoreWidth(spciesList[i].topFitness); float average = PanelLeft[2] + getScoreWidth(spciesList[i].averageFitness); float height = PanelTop[0] + i * PenPositive.Width; //DRAW NUMBER g.DrawString((i + 1) + ".", Mod_Convert.FontSize(Fonts.MainFont, PenText.Width), PenText.Brush, new PointF(PanelLeft[1], height - PenPositive.Width / 2)); //DRAW SCORE if (Mod_Check.isEven(i)) { g.DrawLine(PenNegative, new PointF(PanelLeft[2], height), new PointF(width, height)); } else { g.DrawLine(PenPositive, new PointF(PanelLeft[2], height), new PointF(width, height)); } //DRAW STALE for (int l = 0; l < Pool.species[i].staleness; l++) { g.FillEllipse(new SolidBrush(Colors.MainLight), PanelLeft[2] + 1f + l * PenPositive.Width, height, PenPositive.Width / 2, PenPositive.Width / 2); } //DRAW AVERAGE g.DrawLine(new Pen(Colors.MainDominant, 1), new PointF(average, height), new PointF(average, height + PenPositive.Width / 2)); } //INFORMATIONS newSpecies currSpecies = Pool.species[Pool.currentSpecies]; //GET CURRENT SPECIES newGenome currGenome = currSpecies.genomes[Pool.currentGenome]; //GET CURRENT GENOME float left = PanelLeft[0]; Font infoFont = Mod_Convert.FontSize(Fonts.MainFont, 9); g.DrawString("Generation:", infoFont, PenNegative.Brush, new PointF(left, PanelTop[1])); g.DrawString(Pool.generation.ToString(), infoFont, PenText.Brush, new PointF(left, PanelTop[2])); left += PanelLeft[0] * 2.5f; g.DrawString("Species:", infoFont, PenNegative.Brush, new PointF(left, PanelTop[1])); g.DrawString((Pool.currentSpecies + 1) + "/" + Pool.species.Count, infoFont, PenText.Brush, new PointF(left, PanelTop[2])); left += PanelLeft[0] * 2.5f; g.DrawString("Genome:", infoFont, PenNegative.Brush, new PointF(left, PanelTop[1])); g.DrawString((Pool.currentGenome + 1) + "/" + currSpecies.genomes.Count, infoFont, PenText.Brush, new PointF(left, PanelTop[2])); left += PanelLeft[0] * 2.5f; g.DrawString("Stale:", infoFont, PenNegative.Brush, new PointF(left, PanelTop[1])); g.DrawString(currSpecies.staleness + "/" + (NetMario.StaleSpecies - 1), infoFont, PenText.Brush, new PointF(left, PanelTop[2])); left += PanelLeft[0] * 2.5f; g.DrawString("Fitness:", infoFont, PenNegative.Brush, new PointF(left, PanelTop[1])); g.DrawString(currGenome.fitness + " (" + Pool.maxFitness + ", " + currSpecies.averageFitness + ")", infoFont, PenText.Brush, new PointF(left, PanelTop[2])); left += PanelLeft[0] * 2.5f; g.DrawString("Measure:", infoFont, PenNegative.Brush, new PointF(left, PanelTop[1])); g.DrawString(Pool.measured + " %", infoFont, PenText.Brush, new PointF(left, PanelTop[2])); }
public void LearningRun() { //LEARNING RUN if (!Learning) { Status = "stopped"; return; } //GET SCORE Score = NetMain.Cam.Score; //SCORE = TIME -> T-REX RUNNING //RESET GAME if (Reset) { NetMain.Cam.eventResetGame(); Wait = true; Status = "reset"; } if (Wait) { if (NetMain.Cam.Alive) { Reset = Wait = false; StartRun = DateTime.Now; } else { return; } } Status = "alive"; //GET CURRENT SPECIES & GENOME newSpecies species = Pool.species[Pool.currentSpecies]; newGenome genome = species.genomes[Pool.currentGenome]; //CONVERT INPUTS TO OUTPUTS evaluateCurrent(); //EXECUTE OUTPUTS foreach (string key in Controller.Keys.ToList()) { if (Controller[key]) { NetMain.Cam.eventGlobalSendKeys(Array.IndexOf(Controller.Keys.ToArray(), key)); //SENDKEYS } else { NetMain.Cam.eventGlobalSendKeys(int.MinValue); } } //CHECK IS ALIVE if (!NetMain.Cam.Alive && !Reset) { double fitness = Score; if (Score > 500) //INPUT BONUS SCORE { fitness = fitness + 200; } if (fitness == 0) { fitness = -1; } genome.fitness = fitness; //MAKE BACKUP IF HIGHSCORE REACHED if (fitness > Pool.maxFitness) { Pool.maxFitness = fitness; Console.WriteLine("Max Fitness: " + Math.Floor(Pool.maxFitness)); Console.WriteLine("backup." + Pool.generation + "."); } Pool.currentSpecies = 0; //ZERO START Pool.currentGenome = 0; //ZERO START while (fitnessAlreadyMeasured()) { Status = "next genome"; nextGenome(); } Status = "dead"; //FEEDBACK int currSpecies = Pool.currentSpecies + 1; int currGenome = Pool.currentGenome + 1; //LEARN PANEL CALLBACK FUNCTION NetMain.RoundFinished(Score); //INITIALIZE RUN initializeRun(); double measured = 0; double total = 0; foreach (newSpecies spec in Pool.species) { foreach (newGenome gen in spec.genomes) { total = total + 1; if (gen.fitness != 0) { measured = measured + 1; } Status = "measure"; } } //CONSOLE FEEDBACK Pool.measured = Math.Floor(measured / total * 100); DurationRun = StartRun - DateTime.Now; NetMain.setConsoleInvoke("Round finished!\tDuration: " + DurationRun.ToString(@"mm\:ss") + "\tGeneration: " + Pool.generation + "\tSpecies: " + currSpecies + "\tStale: " + Pool.species[Pool.currentSpecies].staleness + "\tGenome: " + currGenome + "\tFitness: " + fitness + "\tMeasured: " + Pool.measured + "%"); //RESET GAME Reset = true; } }
public void mutate(newGenome genome) { //MUTATE foreach (string key in genome.mutationRates.Keys.ToList()) { if (Random(1, 2) == 1) { genome.mutationRates[key] = 0.95 * genome.mutationRates[key]; //KONSTANT 0.95 } else { genome.mutationRates[key] = 1.05263 * genome.mutationRates[key]; //KONSTANT 1.05263 } } //POINT MUTATE if (Random() < genome.mutationRates["connections"]) { pointMutate(genome); } double p = genome.mutationRates["link"]; //LINK MUTATE BY LINK RATE while (p > 0) { if (Random() < p) { linkMutate(genome, false); } p = p - 1; } p = genome.mutationRates["bias"]; //LINK MUTATE BY BIAS RATE while (p > 0) { if (Random() < p) { linkMutate(genome, true); } p = p - 1; } p = genome.mutationRates["node"]; //NODE MUTATE BY NODE RATE while (p > 0) { if (Random() < p) { nodeMutate(genome); } p = p - 1; } p = genome.mutationRates["enable"]; //ENABLE DISABLE MUTATE BY ENABLE RATE while (p > 0) { if (Random() < p) { enableDisableMutate(genome, true); } p = p - 1; } p = genome.mutationRates["disable"]; //ENABLE DISABLE MUTATE BY DISABLE RATE while (p > 0) { if (Random() < p) { enableDisableMutate(genome, false); } p = p - 1; } }
public void Load() { //LOAD string[] path = Mod_File.FileOpenDialog(false, FILTER.TXT); //ABBRUCH if (path == null) { return; } //START LOADING UniLoad.loadingStart(); //READ TXT FILE string[] file = Mod_TXT.readTXT(path[0]); int x = 0; //GET DURATION Duration = TimeSpan.FromMilliseconds(Mod_Convert.StringToDouble(file[x++])); //GET OUTPUT KEYS OutputKeys = file[x++].Split(' '); //INITIALIZE POOL Initialize(OutputKeys, true); Pool.generation = Mod_Convert.StringToInteger(file[x++]); Pool.maxFitness = Mod_Convert.StringToDouble(file[x++]); int numSpecies = Mod_Convert.StringToInteger(file[x++]); for (int j = 0; j < numSpecies; j++) //SPECIES { newSpecies species = new newSpecies(); Pool.species.Add(species); species.topFitness = Mod_Convert.StringToDouble(file[x++]); species.staleness = Mod_Convert.StringToInteger(file[x++]); int numGenomes = Mod_Convert.StringToInteger(file[x++]); for (int i = 0; i < numGenomes; i++) //GENOME { newGenome genome = new newGenome(); species.genomes.Add(genome); genome.fitness = Mod_Convert.StringToDouble(file[x++]); genome.maxneuron = Mod_Convert.StringToInteger(file[x++]); string line = file[x++]; while (line != "done") { genome.mutationRates[line] = Mod_Convert.StringToDouble(file[x++]); line = file[x++]; } int numGenes = Mod_Convert.StringToInteger(file[x++]); for (int k = 0; k < numGenes; k++) //GENE { newGene gene = new newGene(); genome.genes.Add(gene); string[] split = file[x++].Split(' '); gene.into = Mod_Convert.StringToInteger(split[0]); gene.output = Mod_Convert.StringToInteger(split[1]); gene.weight = Mod_Convert.StringToDouble(split[2]); gene.innovation = Mod_Convert.StringToInteger(split[3]); gene.enabled = Mod_Convert.ObjectToBool(split[4]); } } } //FITNESS ALREADY MEASURED while (fitnessAlreadyMeasured()) { nextGenome(); } initializeRun(); //UPDATE LEARN PANEL NetMain.RoundFinished(0); //END LOADING UniLoad.loadingEnd(); }