public PackedGenome(Genome genome) { genes = genome.Genes.Select(x => new PackedGene(x)).ToArray(); }
/// <summary> /// Mutates a given genome by adding a connection. /// Connection is guaranteed to not be 'into' a sensor or bias. /// </summary> /// <param name="genome">The genome to be modified.</param> /// <param name="innovationsSeen">A list of previously seen innovations.</param> /// <param name="rando">A random number generator.</param> public static void MutateAddConnection(Genome genome, InnovationPool innovationsSeen, Random rando) { //TODO: I'm getting the node information, but I only need that to construct allNodesNotInput... Dictionary <int, NodeInformation> allNodes = genome.GetAllNodeInformation(true); Dictionary <int, NodeInformation> allNodesNotInput = new Dictionary <int, NodeInformation>(allNodes); //TODO: Witnessed a bug where allNodes.Count == 0. // Could be a node where there are only frozen links connecting. foreach (var id in allNodesNotInput.Where(kvp => kvp.Value.IsInput()).ToList()) { allNodesNotInput.Remove(id.Key); } //TODO: Gotta be a better way than a tryCount... int tryCount = 0; int nodeFromId = -1; int nodeToId = -1; while (tryCount < 20) { nodeFromId = allNodes.Keys.ToList()[rando.Next(allNodes.Count)]; nodeToId = allNodesNotInput.Keys.ToList()[rando.Next(allNodesNotInput.Count)]; if (!genome.ContainsConnection(nodeFromId, nodeToId)) { break; } tryCount++; } if (tryCount == 20) { return; } ConnectionInformation connectInfo = new ConnectionInformation(nodeFromId, nodeToId); InnovationInformation innovation = new InnovationInformation(connectInfo); int connectId = -1; //TODO: Pull inital weight setting out of here. double weight = rando.NextDouble() * 2.0 - 1.0; int registeredInnovationId = innovationsSeen.FindByInnovation(innovation); if (registeredInnovationId == -1) { connectId = ConnectionPool.Add(connectInfo); innovation.NewConnectionDetails.ConnectionId = connectId; innovationsSeen.Add(innovation); } else { connectId = innovationsSeen.FindById(registeredInnovationId).NewConnectionDetails.ConnectionId; } genome.Genes.Add(new Gene(ConnectionPool.FindById(connectId), connectId, weight, false)); }
public Player(int inputs, int outputs, ref FitnessMethod fitnessMethod) { Brain = new Genome(inputs, outputs); IsAlive = true; fitness = fitnessMethod; }
/// <summary> /// Count Disjoint Genes between 2 Genomes /// </summary> /// <param name="genome1">Genome 1</param> /// <param name="genome2">Genome 2</param> /// <returns></returns> public static int CountDisjointGene(Genome genome1, Genome genome2) { return(CountDisjointNodeGenes(genome1, genome2) + CountDisjointConnectionGenes(genome1, genome2)); }
/// <summary> /// Count Excess Genes between 2 Genomes /// </summary> /// <param name="genome1">Genome 1</param> /// <param name="genome2">Genome 2</param> /// <returns></returns> public static int CountExcessGene(Genome genome1, Genome genome2) { return(CountExcessNodeGenes(genome1, genome2) + CountExcessConnectionGenes(genome1, genome2)); }
/// <summary> /// Breed /// </summary> private void Breed() { // Logs Setup int weightMutationNb = 0; int addConnectionNb = 0; int addNodeNb = 0; int enableDisableConnectionNb = 0; _mutationLogs = ""; while (_nextEvaluationGenomes.Count() < _config.populationSize) { Genome child = null; Genome mom = null; Genome dad = null; // Get Child Species species = null; int maxToKeep = ((_config.populationSize * _config.percentageToKeep) / 100) - 1; if (_config.species) { species = GetRandomSpecies(_r); } if (_config.crossover) { if (species != null) { mom = GetRandomGenome(species, _r); dad = GetRandomGenome(species, _r); } else { mom = _genomes[UnityEngine.Random.Range(0, maxToKeep)]; dad = _genomes[UnityEngine.Random.Range(0, maxToKeep)]; } // Crossover between Mom & Dad child = mom.Fitness >= dad.Fitness ? Genome.Crossover(mom, dad, _r, _config.disabledConnectionInheritChance) : Genome.Crossover(dad, mom, _r, _config.disabledConnectionInheritChance); } else { child = species != null ? new Genome(GetRandomGenome(species, _r)) : new Genome(_genomes[UnityEngine.Random.Range(0, maxToKeep)]); } // Weights Mutation if ((float)_r.NextDouble() < _config.mutationRate) { child.WeightsMutation(_r); weightMutationNb++; } if (_config.genomeMutations) { // Add Connection Mutation if ((float)_r.NextDouble() < _config.addConnectionRate) { // If for Logs if (child.AddConnectionMutation(_r, _connectionInnovation, 10)) { addConnectionNb++; } } // Add Node Mutation if ((float)_r.NextDouble() < _config.addNodeRate) { child.AddNodeMutation(_r, _connectionInnovation, _nodeInnovation); addNodeNb++; } // Enable/Disable a Random Connection if ((float)_r.NextDouble() < _config.enableDisableRate) { // If for Logs if (child.EnableOrDisableRandomConnection()) { enableDisableConnectionNb++; } } } // Add Child to Next Evaluation Genomes _nextEvaluationGenomes.Add(child); } _mutationLogs += string.Format( "Weights Mutation: {0}, Add Connection: {1}, Add Node: {2}, Enable/Disable Connection: {3}\nCrossover is {4}, Genome Mutations is {5}, Species is {6}", weightMutationNb, addConnectionNb, addNodeNb, enableDisableConnectionNb, _config.crossover, _config.genomeMutations, _config.species ); _genomes.Clear(); _genomes = new List <Genome>(_nextEvaluationGenomes); _nextEvaluationGenomes = new List <Genome>(); }
/// <summary> /// Count Matching Genes between 2 Genomes /// </summary> /// <param name="genome1">Genome 1</param> /// <param name="genome2">Genome 2</param> /// <returns></returns> public static int CountMatchingGene(Genome genome1, Genome genome2) { return(CountMatchingNodeGenes(genome1, genome2) + CountMatchingConnectionGenes(genome1, genome2)); }
/// <summary> /// Evaluate a Genome /// </summary> /// <param name="genome">Genome to Evaluate</param> /// <returns></returns> protected abstract float EvaluateGenome(Genome genome);
/// <summary> /// Remove a genome from this and SpeciesCtrl storages. /// </summary> /// <param name="targetGenome"></param> private void RemoveGenome(Genome targetGenome) { Genomes.Remove(targetGenome); SpeciesCtrl.SpeciesList.ForEach(x => x.Genomes.Remove(targetGenome)); }
public void AddGenomeToList(Genome genome) { _genomes.Add(genome); _currentPop++; }
/// <summary> /// Breed /// </summary> private Genome Breed(Genome mom = null, Genome dad = null) { Genome child = null; // Get Child if (dad != null && mom != null) { // Crossover between Mom & Dad if (mom.Fitness >= dad.Fitness) { child = Genome.Crossover(mom, dad, _r, _config.disabledConnectionInheritChance); } else { child = Genome.Crossover(dad, mom, _r, _config.disabledConnectionInheritChance); } } else { int maxToKeep = ((_currentPop * _config.percentageToKeep) / 100) - 1; mom = _genomes[UnityEngine.Random.Range(0, maxToKeep)]; dad = _genomes[UnityEngine.Random.Range(0, maxToKeep)]; // Crossover between Mom & Dad if (mom.Fitness >= dad.Fitness) { child = Genome.Crossover(mom, dad, _r, _config.disabledConnectionInheritChance); } else { child = Genome.Crossover(dad, mom, _r, _config.disabledConnectionInheritChance); } } // Weights Mutation if ((float)_r.NextDouble() < _config.mutationRate) { child.WeightsMutation(_r); } if (_config.genomeMutations) { // Add Connection Mutation if ((float)_r.NextDouble() < _config.addConnectionRate) { child.AddConnectionMutation(_r, _connectionInnovation, 10); } // Add Node Mutation if ((float)_r.NextDouble() < _config.addNodeRate) { child.AddNodeMutation(_r, _connectionInnovation, _nodeInnovation); } // Enable/Disable a Random Connection if ((float)_r.NextDouble() < _config.enableDisableRate) { child.EnableOrDisableRandomConnection(); } } return(child); }
/// <summary> /// Basic constructor. /// </summary> /// <param name="g">The original genome ( the 'og' =] ).</param> public Species(Genome g) { Template = g; Genomes.Add(g); }