Example #1
0
 public PackedGenome(Genome genome)
 {
     genes = genome.Genes.Select(x => new PackedGene(x)).ToArray();
 }
Example #2
0
        /// <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));
        }
Example #3
0
 public Player(int inputs, int outputs, ref FitnessMethod fitnessMethod)
 {
     Brain   = new Genome(inputs, outputs);
     IsAlive = true;
     fitness = fitnessMethod;
 }
Example #4
0
 /// <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));
 }
Example #5
0
 /// <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));
 }
Example #6
0
        /// <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>();
        }
Example #7
0
 /// <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));
 }
Example #8
0
 /// <summary>
 /// Evaluate a Genome
 /// </summary>
 /// <param name="genome">Genome to Evaluate</param>
 /// <returns></returns>
 protected abstract float EvaluateGenome(Genome genome);
Example #9
0
 /// <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));
 }
Example #10
0
 public void AddGenomeToList(Genome genome)
 {
     _genomes.Add(genome);
     _currentPop++;
 }
Example #11
0
        /// <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);
        }
Example #12
0
 /// <summary>
 /// Basic constructor.
 /// </summary>
 /// <param name="g">The original genome ( the 'og' =] ).</param>
 public Species(Genome g)
 {
     Template = g;
     Genomes.Add(g);
 }