void Window() { if (selected == null) { panel.SetActive(false); } else { panel.SetActive(true); infos.text = "Name: " + selected.name + "\n"; if (selected.GetComponent <MonoBehaviour>().GetType().Name == "Animal") { Animal a = (Animal)selected; infos.text += "Life: " + a.currLife + " / " + a.life + "\n"; infos.text += "Food: " + a.currFood + " / " + a.food + "\n"; infos.text += "Water: " + a.currWater + " / " + a.water + "\n"; infos.text += "Breath: " + a.breath + "\n"; infos.text += "Speed: " + a.speed + "\n"; infos.text += "Weight: " + a.weight + "\n"; infos.text += "Age: " + a.age + "\n"; infos.text += "Current Behaviour: " + a.currBehaviour + "\n"; } else if (selected.GetComponent <MonoBehaviour>().GetType().Name == "Flower") { Flower f = (Flower)selected; infos.text += "Life: " + f.currLife + " / " + f.life + "\n"; infos.text += "Age: " + f.age + "\n"; } genes = scroll.content.GetComponent <GeneList>(); if (selected != prevSelected) { disp_selected = null; prevSelected = selected; } if (gene_choice.captionText.text == "Appearance" && disp_selected != "Appearance") { genes.DestroyList(); genes.printList(selected.appearance); disp_selected = "Appearance"; } else if (gene_choice.captionText.text == "Behaviour" && disp_selected != "Behaviour") { genes.DestroyList(); genes.printList(selected.behavior); disp_selected = "Behaviour"; } else if (gene_choice.captionText.text == "Composition" && disp_selected != "Composition") { genes.DestroyList(); genes.printList(selected.composition); disp_selected = "Composition"; } else if (gene_choice.captionText.text == "Show Genes") { genes.DestroyList(); disp_selected = null; } } }
public void Mutate(Genotype genotype, MutationResults results) { var neuronIndexA = Random.Range(0, genotype.NeuronCount); var neuronGeneA = genotype.NeuronGenes.ElementAt(neuronIndexA); var candidates = new List<NeuronGene>(genotype.NeuronGenes); candidates.Shuffle(); NeuronGene neuronGeneB = default(NeuronGene); bool foundNeuron = false; for (var i = 0; i < candidates.Count; i++) { neuronGeneB = candidates[i]; var exists = genotype.SynapseGenes.Any(s => neuronGeneA.InnovationId == s.fromNeuronId && neuronGeneB.InnovationId == s.toNeuronId); if (!exists) { foundNeuron = true; break; } } if (foundNeuron) { var synapseInnovationId = innovations.GetSynapseInnovationId(neuronGeneA.InnovationId, neuronGeneB.InnovationId); var synapseGene = new SynapseGene(synapseInnovationId, neuronGeneA.InnovationId, neuronGeneB.InnovationId, true); var synapseGenes = new GeneList<SynapseGene>(genotype.SynapseGenes); synapseGenes.Add(synapseGene); genotype.SynapseGenes = synapseGenes; results.addedSynapses += 1; } }
public Genotype(Genotype other) { this.neuronGenes = other.NeuronGenes .Select(g => new NeuronGene(g)) .ToGeneList(); this.synapseGenes = other.SynapseGenes .Select(g => new SynapseGene(g)) .ToGeneList(); }
public void Mutate(Genotype genotype, MutationResults results) { // We require a synapse to split if (genotype.SynapseCount == 0) { return; } // Pick a synapse at random var synapseIndex = Random.Range(0, genotype.SynapseCount); var synapseGene = genotype.SynapseGenes.ElementAt(synapseIndex); // Generate an innovation id for the operation var innovationId = innovations.GetNeuronInnovationId( synapseGene.fromNeuronId, synapseGene.toNeuronId, synapseGene.InnovationId ); // If the genotype already contains the innovation id, bail if (genotype.Contains(innovationId)) { return; } var neuronGene = NeuronGene.Random(innovationId); var neuronGenes = new GeneList<NeuronGene>(genotype.NeuronGenes); neuronGenes.Add(neuronGene); genotype.NeuronGenes = neuronGenes; var synapseGenes = new GeneList<SynapseGene>(genotype.SynapseGenes); var synapseGene1 = new SynapseGene(innovationId + 0, synapseGene.fromNeuronId, neuronGene.InnovationId, true, 0.5f); synapseGenes.Add(synapseGene1); var synapseGene2 = new SynapseGene(innovationId + 1, neuronGene.InnovationId, synapseGene.toNeuronId, true, 0.5f); synapseGenes.Add(synapseGene2); genotype.SynapseGenes = synapseGenes; results.addedNeurons += 1; results.addedSynapses += 2; }
public void Mutate(Genotype genotype, MutationResults results) { var neuronIndexA = Random.Range(0, genotype.InputNeurons.Count); var neuronGeneA = genotype.InputNeurons[neuronIndexA]; var validNeurons = genotype.OutputNeurons .Where(_ => Random.value < p) .Where(neuronGeneB => genotype.SynapseGenes.None(s => neuronGeneA.InnovationId == s.fromNeuronId && neuronGeneB.InnovationId == s.toNeuronId)); foreach (var neuronGeneB in validNeurons) { var synapseInnovationId = innovations.GetSynapseInnovationId(neuronGeneA.InnovationId, neuronGeneB.InnovationId); var synapseGene = SynapseGene.Random(synapseInnovationId, neuronGeneA.InnovationId, neuronGeneB.InnovationId, true); var synapseGenes = new GeneList<SynapseGene>(genotype.SynapseGenes); synapseGenes.Add(synapseGene); genotype.SynapseGenes = synapseGenes; results.addedSynapses += 1; } }
public Genotype(GeneList<NeuronGene> neuronGenes, GeneList<SynapseGene> synapseGenes) { this.neuronGenes = neuronGenes; this.synapseGenes = synapseGenes; }
IEnumerator Start() { var logPath = string.Format("logs_{0}", DateTime.Now.Ticks); Debug.LogFormat("Logging to {0}", logPath); if (!Directory.Exists(logPath)) { Directory.CreateDirectory(logPath); } elitesLog = File.CreateText(Path.Combine(logPath, "elites.csv")); populationLog = File.CreateText(Path.Combine(logPath, "populations.csv")); generationLog = File.CreateText(Path.Combine(logPath, "generations.csv")); speciesLog = File.CreateText(Path.Combine(logPath, "species.csv")); var populationSize = 100; var innovations = new InnovationCollection(); var mutations = new MutationCollection(); mutations.Add(0.01f, new AddNeuronMutator(innovations)); // 0.1% mutations.Add(0.05f, new AddSynapseMutator(innovations)); // 1% mutations.Add(0.05f, new ToggleSynapseMutator(0.125f)); mutations.Add(0.20f, new PerturbNeuronMutator(0.5f, 0.25f)); // 98% vvv mutations.Add(0.20f, new PerturbSynapseMutator(0.5f, 0.25f)); mutations.Add(0.20f, new ReplaceNeuronMutator(0.5f)); mutations.Add(0.20f, new ReplaceSynapseMutator(0.5f)); var eliteSelector = new EliteSelector(); var crossover = new MultipointCrossover(); var offspringSelector = new OffspringSelector(crossover); var distanceMetric = new DistanceMetric(2.0f, 2.0f, 1.0f); var speciation = new Speciation(10, 6.0f, 0.3f, distanceMetric); var neuronGenes = new []{ new NeuronGene(innovations.GetInitialNeuronInnovationId(0), NeuronType.UpperNeuron), new NeuronGene(innovations.GetInitialNeuronInnovationId(1), NeuronType.LowerNeuron), new NeuronGene(innovations.GetInitialNeuronInnovationId(2), NeuronType.PositionNeuron), new NeuronGene(innovations.GetInitialNeuronInnovationId(3), NeuronType.SpeedNeuron), }.ToGeneList(); var synapseGenes = new GeneList<SynapseGene>(); var protoGenotype = new Genotype(neuronGenes, synapseGenes); var genotypes = new GenotypeStream(protoGenotype) .Take(populationSize).ToArray(); var species = new Specie[0]; var generation = 0; var elitePhenotypes = new List<Phenotype>(); var offspringPhenotypes = genotypes.Select(gt => new Phenotype(gt)).ToList(); while (true) { yield return StartCoroutine(EvaluatePopulation(offspringPhenotypes)); var phenotypes = new List<Phenotype>(elitePhenotypes.Count + offspringPhenotypes.Count); phenotypes.AddRange(elitePhenotypes); phenotypes.AddRange(offspringPhenotypes); Assert.AreEqual(phenotypes.Count, populationSize, "Population size must remain constant"); var longest = phenotypes.OrderByDescending(pt => pt.BestDuration).First(); Debug.LogFormat("[{0}] Fitness: {1}, Duration: {2}s ({3}, {4}) (Longest)", generation, longest.MeanFitness, longest.MeanDuration, longest.Genotype.NeuronCount, longest.Genotype.SynapseCount); var best = phenotypes.OrderByDescending(pt => pt.Fitness).First(); Debug.LogFormat("[{0}] Fitness: {1}, Duration: {2}s ({3}, {4}) (Best)", generation, best.MeanFitness, best.MeanDuration, best.Genotype.NeuronCount, best.Genotype.SynapseCount); elitesLog.WriteLine(string.Join(",", new string[]{ generation.ToString(), best.Fitness.ToString(), best.BestDuration.ToString(), JSON.Serialize(best.Genotype.ToJSON()), })); var meanComplexity = phenotypes.Aggregate(0.0f, (sum, pt) => sum + (float)pt.Genotype.Complexity, (sum) => sum / (float)phenotypes.Count); var meanNeuronCount = phenotypes.Aggregate(0.0f, (sum, pt) => sum + (float)pt.Genotype.NeuronCount, (sum) => sum / (float)phenotypes.Count); var meanSynapseCount = phenotypes.Aggregate(0.0f, (sum, pt) => sum + (float)pt.Genotype.SynapseCount, (sum) => sum / (float)phenotypes.Count); var meanFitness = phenotypes.Aggregate(0.0f, (sum, pt) => sum + (float)pt.Fitness, (sum) => sum / (float)phenotypes.Count); var stdevFitness = phenotypes.Aggregate(0.0f, (sum, pt) => sum + Mathf.Pow(pt.Fitness - meanFitness, 2.0f), (sum) => Mathf.Sqrt(sum / (float)phenotypes.Count)); var stdevComplexity = phenotypes.Aggregate(0.0f, (sum, pt) => sum + Mathf.Pow((float)pt.Genotype.Complexity - meanComplexity, 2.0f), (sum) => Mathf.Sqrt(sum / (float)phenotypes.Count)); var stdevNeuronCount = phenotypes.Aggregate(0.0f, (sum, pt) => sum + Mathf.Pow((float)pt.Genotype.NeuronCount - meanNeuronCount, 2.0f), (sum) => Mathf.Sqrt(sum / (float)phenotypes.Count)); var stdevSynapseCount = phenotypes.Aggregate(0.0f, (sum, pt) => sum + Mathf.Pow((float)pt.Genotype.SynapseCount - meanSynapseCount, 2.0f), (sum) => Mathf.Sqrt(sum / (float)phenotypes.Count)); species = speciation.Speciate(species, phenotypes.ToArray()); Debug.LogFormat("[{0}] Species Count: {1} (Threshold: {2})", generation, species.Length, speciation.DistanceThreshold); var meanAdjustedFitness = phenotypes.Aggregate(0.0f, (sum, pt) => sum + (float)pt.AdjustedFitness, (sum) => sum / (float)phenotypes.Count); // standard deviation: // take the square root of the average of the squared deviations of the values from their average value var stdevAdjustedFitness = phenotypes.Aggregate(0.0f, (sum, pt) => sum + Mathf.Pow(pt.AdjustedFitness - meanAdjustedFitness, 2.0f), (sum) => Mathf.Sqrt(sum / (float)phenotypes.Count)); generationLog.WriteLine(new []{ generation, best.Fitness, best.MeanDuration, meanAdjustedFitness, stdevAdjustedFitness, meanFitness, stdevFitness, meanComplexity, stdevComplexity, meanNeuronCount, stdevNeuronCount, meanSynapseCount, stdevSynapseCount }.Stringify()); foreach (var sp in species) { speciesLog.WriteLine(new []{ generation, sp.SpeciesId, sp.Count, sp.BestFitness, sp.MeanFitness, sp.MeanAdjustedFitness, sp.MeanComplexity, }.Stringify()); foreach (var pt in sp) { populationLog.WriteLine(new []{ generation, sp.SpeciesId, pt.Fitness, pt.AdjustedFitness, pt.BestDuration, pt.Genotype.Complexity, pt.Genotype.NeuronCount, pt.Genotype.SynapseCount, }.Stringify()); } } var eliteCount = species.Length; elitePhenotypes = eliteSelector.Select(species, eliteCount); var offspringCount = populationSize - elitePhenotypes.Count; var offspringGenotypes = offspringSelector.Select(species, offspringCount); var mutationResults = mutations.Mutate(offspringGenotypes); Debug.LogFormat("[{0}] Mutations: Added Neurons: {1}, Added Synapses: {2}, Perturbed Neurons: {3}, Perturbed Synapses: {4}, Replaced Neurons: {5}, Replaced Synapses: {6}, Toggled Synapses: {7}, Pruned Synapses: {8}, Orphaned Neurons: {9}", generation, mutationResults.addedNeurons, mutationResults.addedSynapses, mutationResults.perturbedNeurons, mutationResults.perturbedSynapses, mutationResults.replacedNeurons, mutationResults.replacedSynapses, mutationResults.toggledSynapses, mutationResults.prunedSynapses, mutationResults.orphanedNeurons); offspringPhenotypes = offspringGenotypes.Select(gt => new Phenotype(gt)).ToList(); generation++; // Flush these so we can preview results while it runs generationLog.Flush(); populationLog.Flush(); speciesLog.Flush(); } }
IEnumerator Start() { var logPath = string.Format("logs_{0}", DateTime.Now.Ticks); Debug.LogFormat("Logging to {0}", logPath); if (!Directory.Exists(logPath)) { Directory.CreateDirectory(logPath); } elitesLog = File.CreateText(Path.Combine(logPath, "elites.csv")); populationLog = File.CreateText(Path.Combine(logPath, "populations.csv")); generationLog = File.CreateText(Path.Combine(logPath, "generations.csv")); speciesLog = File.CreateText(Path.Combine(logPath, "species.csv")); var populationSize = 100; var innovations = new InnovationCollection(); var mutations = new MutationCollection(); mutations.Add(0.01f, new AddNeuronMutator(innovations)); // 0.1% mutations.Add(0.05f, new AddSynapseMutator(innovations)); // 1% mutations.Add(0.05f, new ToggleSynapseMutator(0.125f)); mutations.Add(0.20f, new PerturbNeuronMutator(0.5f, 0.25f)); // 98% vvv mutations.Add(0.20f, new PerturbSynapseMutator(0.5f, 0.25f)); mutations.Add(0.20f, new ReplaceNeuronMutator(0.5f)); mutations.Add(0.20f, new ReplaceSynapseMutator(0.5f)); var eliteSelector = new EliteSelector(); var crossover = new MultipointCrossover(); var offspringSelector = new OffspringSelector(crossover); var distanceMetric = new DistanceMetric(2.0f, 2.0f, 1.0f); var speciation = new Speciation(10, 6.0f, 0.3f, distanceMetric); var neuronGenes = new [] { new NeuronGene(innovations.GetInitialNeuronInnovationId(0), NeuronType.UpperNeuron), new NeuronGene(innovations.GetInitialNeuronInnovationId(1), NeuronType.LowerNeuron), new NeuronGene(innovations.GetInitialNeuronInnovationId(2), NeuronType.PositionNeuron), new NeuronGene(innovations.GetInitialNeuronInnovationId(3), NeuronType.SpeedNeuron), }.ToGeneList(); var synapseGenes = new GeneList <SynapseGene>(); var protoGenotype = new Genotype(neuronGenes, synapseGenes); var genotypes = new GenotypeStream(protoGenotype) .Take(populationSize).ToArray(); var species = new Specie[0]; var generation = 0; var elitePhenotypes = new List <Phenotype>(); var offspringPhenotypes = genotypes.Select(gt => new Phenotype(gt)).ToList(); while (true) { yield return(StartCoroutine(EvaluatePopulation(offspringPhenotypes))); var phenotypes = new List <Phenotype>(elitePhenotypes.Count + offspringPhenotypes.Count); phenotypes.AddRange(elitePhenotypes); phenotypes.AddRange(offspringPhenotypes); Assert.AreEqual(phenotypes.Count, populationSize, "Population size must remain constant"); var longest = phenotypes.OrderByDescending(pt => pt.BestDuration).First(); Debug.LogFormat("[{0}] Fitness: {1}, Duration: {2}s ({3}, {4}) (Longest)", generation, longest.MeanFitness, longest.MeanDuration, longest.Genotype.NeuronCount, longest.Genotype.SynapseCount); var best = phenotypes.OrderByDescending(pt => pt.Fitness).First(); Debug.LogFormat("[{0}] Fitness: {1}, Duration: {2}s ({3}, {4}) (Best)", generation, best.MeanFitness, best.MeanDuration, best.Genotype.NeuronCount, best.Genotype.SynapseCount); elitesLog.WriteLine(string.Join(",", new string[] { generation.ToString(), best.Fitness.ToString(), best.BestDuration.ToString(), JSON.Serialize(best.Genotype.ToJSON()), })); var meanComplexity = phenotypes.Aggregate(0.0f, (sum, pt) => sum + (float)pt.Genotype.Complexity, (sum) => sum / (float)phenotypes.Count); var meanNeuronCount = phenotypes.Aggregate(0.0f, (sum, pt) => sum + (float)pt.Genotype.NeuronCount, (sum) => sum / (float)phenotypes.Count); var meanSynapseCount = phenotypes.Aggregate(0.0f, (sum, pt) => sum + (float)pt.Genotype.SynapseCount, (sum) => sum / (float)phenotypes.Count); var meanFitness = phenotypes.Aggregate(0.0f, (sum, pt) => sum + (float)pt.Fitness, (sum) => sum / (float)phenotypes.Count); var stdevFitness = phenotypes.Aggregate(0.0f, (sum, pt) => sum + Mathf.Pow(pt.Fitness - meanFitness, 2.0f), (sum) => Mathf.Sqrt(sum / (float)phenotypes.Count)); var stdevComplexity = phenotypes.Aggregate(0.0f, (sum, pt) => sum + Mathf.Pow((float)pt.Genotype.Complexity - meanComplexity, 2.0f), (sum) => Mathf.Sqrt(sum / (float)phenotypes.Count)); var stdevNeuronCount = phenotypes.Aggregate(0.0f, (sum, pt) => sum + Mathf.Pow((float)pt.Genotype.NeuronCount - meanNeuronCount, 2.0f), (sum) => Mathf.Sqrt(sum / (float)phenotypes.Count)); var stdevSynapseCount = phenotypes.Aggregate(0.0f, (sum, pt) => sum + Mathf.Pow((float)pt.Genotype.SynapseCount - meanSynapseCount, 2.0f), (sum) => Mathf.Sqrt(sum / (float)phenotypes.Count)); species = speciation.Speciate(species, phenotypes.ToArray()); Debug.LogFormat("[{0}] Species Count: {1} (Threshold: {2})", generation, species.Length, speciation.DistanceThreshold); var meanAdjustedFitness = phenotypes.Aggregate(0.0f, (sum, pt) => sum + (float)pt.AdjustedFitness, (sum) => sum / (float)phenotypes.Count); // standard deviation: // take the square root of the average of the squared deviations of the values from their average value var stdevAdjustedFitness = phenotypes.Aggregate(0.0f, (sum, pt) => sum + Mathf.Pow(pt.AdjustedFitness - meanAdjustedFitness, 2.0f), (sum) => Mathf.Sqrt(sum / (float)phenotypes.Count)); generationLog.WriteLine(new [] { generation, best.Fitness, best.MeanDuration, meanAdjustedFitness, stdevAdjustedFitness, meanFitness, stdevFitness, meanComplexity, stdevComplexity, meanNeuronCount, stdevNeuronCount, meanSynapseCount, stdevSynapseCount }.Stringify()); foreach (var sp in species) { speciesLog.WriteLine(new [] { generation, sp.SpeciesId, sp.Count, sp.BestFitness, sp.MeanFitness, sp.MeanAdjustedFitness, sp.MeanComplexity, }.Stringify()); foreach (var pt in sp) { populationLog.WriteLine(new [] { generation, sp.SpeciesId, pt.Fitness, pt.AdjustedFitness, pt.BestDuration, pt.Genotype.Complexity, pt.Genotype.NeuronCount, pt.Genotype.SynapseCount, }.Stringify()); } } var eliteCount = species.Length; elitePhenotypes = eliteSelector.Select(species, eliteCount); var offspringCount = populationSize - elitePhenotypes.Count; var offspringGenotypes = offspringSelector.Select(species, offspringCount); var mutationResults = mutations.Mutate(offspringGenotypes); Debug.LogFormat("[{0}] Mutations: Added Neurons: {1}, Added Synapses: {2}, Perturbed Neurons: {3}, Perturbed Synapses: {4}, Replaced Neurons: {5}, Replaced Synapses: {6}, Toggled Synapses: {7}, Pruned Synapses: {8}, Orphaned Neurons: {9}", generation, mutationResults.addedNeurons, mutationResults.addedSynapses, mutationResults.perturbedNeurons, mutationResults.perturbedSynapses, mutationResults.replacedNeurons, mutationResults.replacedSynapses, mutationResults.toggledSynapses, mutationResults.prunedSynapses, mutationResults.orphanedNeurons); offspringPhenotypes = offspringGenotypes.Select(gt => new Phenotype(gt)).ToList(); generation++; // Flush these so we can preview results while it runs generationLog.Flush(); populationLog.Flush(); speciesLog.Flush(); } }