示例#1
0
        /// <summary>
        /// This is used to crossover two parents to make a child
        /// </summary>
        /// <param name="parentA"></param>
        /// <param name="parentB"></param>
        private Genome(EvolutionConfig config, Genome parentA, Genome parentB)
            : this(config, false)
        {
            Genome moreFitParent = parentA.fitness > parentB.fitness ? parentA : parentB;
            Genome lessFitParent = parentA.fitness > parentB.fitness ? parentB : parentA;

            // Take all similar genes from the most fit parent, and randomly select disjoint genes
            IEnumerable<Gene> childGenes = moreFitParent.Genes.Where(item => lessFitParent.Genes.Exists(item2 => item2.InnovationNumber == item.InnovationNumber) || config.rng.NextDouble() > 0.50)
                .Union(lessFitParent.Genes.Where(item => !moreFitParent.Genes.Exists(item2 => item2.InnovationNumber == item.InnovationNumber) && config.rng.NextDouble() > 0.50));

            // Set mutation rates to the most fit parent
            mutationRates = moreFitParent.mutationRates;

            // Create unique copies of genes
            foreach (Gene g in childGenes)
                Genes.Add((Gene)g.Clone());

            // Copy parent A's start values
            startValues = new Dictionary<int,double>(moreFitParent.startValues);

            // Throw in parent B's extra start values
            foreach (var pair in lessFitParent.startValues) {
                if (!startValues.ContainsKey(pair.Key))
                    startValues.Add(pair.Key, pair.Value);
            }
        }
示例#2
0
        /// <summary>
        /// This breeds to parents to make a new child from a species offspring has a chance of being a clone of the parent
        /// </summary>
        /// <param name="config"></param>
        /// <param name="species"></param>
        /// <returns></returns>
        public static Genome BreedChild(EvolutionConfig config, Species species)
        {
            Genome child;
            // If the specie only contains one child, the species can't crossover
            if (species.genomes.Count == 1)
                child = (Genome) species.genomes.First().Clone();
            else {
                Genome parentA = species.genomes.ElementAt(rng.Next(species.genomes.Count));

                // Non-crossover chance
                if (rng.NextDouble() >= config.CrossOverRate)
                    child = (Genome) parentA.Clone();
                else { // Crossover
                    Genome parentB = species.genomes.Where(g => g != parentA).ElementAt(rng.Next(species.genomes.Count - 1));
                    child = new Genome(config, parentA, parentB);
                }
            }

            // Mutate
            child.Mutate();

            return child;
        }
        /// <summary>
        /// Sets up a neural network for a
        /// </summary>
        /// <param name="config"></param>
        /// <param name="genes"></param>
        public NeuralNetwork(Genome genome)
        {
            // Copy genome
            gen = genome;

            smallestNode = null;
            int? smallestBackup = null;

            // Setup hash table
            hashTable = new Dictionary<int, int>();
            int hashIndex = gen.evoConfig.InputNodeCount + 1 + gen.evoConfig.OutputNodeCount;

            // Select unique node values (Get the distinct values from both the NodeInputs and NodeOuputs)
            foreach (int n in genome.Genes.Select(g => g.NodeInput)
                .Union(
                    genome.Genes.Select(g => g.NodeOutput))
                    .Union(Enumerable.Range(0, gen.evoConfig.InputNodeCount + 1 + gen.evoConfig.OutputNodeCount))
               .Distinct()) {
                // Assign exact values if an input or outputnode
                if (IsInputOutputNode(genome.evoConfig, n))
                    hashTable.Add(n, n);
                else
                    hashTable.Add(n, hashIndex++);
            }

            foreach (int n in genome.Genes.Select(g => g.NodeOutput)) {
                if (IsOutputNode(gen.evoConfig, n)) {
                    if (!smallestBackup.HasValue || n < smallestBackup)
                        smallestBackup = n;
                }
                else if (!smallestNode.HasValue || n < smallestNode)
                    smallestNode = n;
            }

            if (!smallestNode.HasValue)
                smallestNode = smallestBackup;

            // Setup instances
            outputs = new double[genome.evoConfig.OutputNodeCount];
            values = new double[hashTable.Count];

            // Set the bias
            biasIndex = gen.evoConfig.InputNodeCount;
            values[biasIndex] = 1.0;

            // Sort the genes
            gen.Genes.Sort((a, b) => {

                // If the one out of the two are an output, make that the largest number
                bool isAOutput = IsOutputNode(gen.evoConfig, a.NodeOutput);
                if (isAOutput != IsOutputNode(gen.evoConfig, b.NodeOutput))
                    if (isAOutput)
                        return 1;
                    else
                        return 0;

                // Otherwise sort by ouput node number
                if (a.NodeOutput > b.NodeOutput)
                    return 1;
                else if (a.NodeOutput < b.NodeOutput)
                    return -1;
                return 0;
            });

            // Copy start values to array
            foreach (var pair in gen.startValues)
                if (hashTable.ContainsKey(pair.Key))
                    values[hashTable[pair.Key]] = pair.Value;
        }
示例#4
0
        private void AddGenomeToSpecies(Genome genome)
        {
            List<Species> possibleSpecies = new List<Species>(species);

            // Attempt to find a compatable species
            while (possibleSpecies.Count > 0) {
                // Select a random species from the list
                Species selectedSpecies = possibleSpecies[evoConfig.rng.Next(possibleSpecies.Count)];

                // If the select species is within range of the compatability threshold add it to the species
                if (selectedSpecies.genomes.First() - genome < evoConfig.CompatablilityThresholdConstant) {
                    selectedSpecies.Add(genome);
                    return;
                }

                // Cross this species attempt off our list (literally, because its a list)
                possibleSpecies.Remove(selectedSpecies);
            }

            // We could not find a species, make a new one
            Species newSpecies = new Species();

            // Add the genome to the species
            newSpecies.Add(genome);

            // Add the species to the species list
            species.Add(newSpecies);
        }