Beispiel #1
0
    public Chromosome ToChromosome()
    {
        Chromosome chromosome = new Chromosome();

        for (int j = 0; j < data.Count; ++j)
        {
            //  if not black edge
            if (Math.Abs(data[j].Item1 - data[j].Item2) != 1)
            {
                continue;
            }
            if (data[j].Item1 % 2 == data[j].Item2 % 2)
            {
                continue;
            }

            if (data[j].Item1 < data[j].Item2)
            {
                chromosome.Add(data[j].Item2 / 2);
            }
            else
            {
                chromosome.Add(-data[j].Item1 / 2);
            }
        }

        return(chromosome);
    }
Beispiel #2
0
        /// <summary>
        /// Construct a genome, do not provide links and neurons.
        /// </summary>
        ///
        /// <param name="id">The genome id.</param>
        /// <param name="inputCount_0">The input count.</param>
        /// <param name="outputCount_1">The output count.</param>
        public NEATGenome(long id, int inputCount_0, int outputCount_1)
        {
            GenomeID      = id;
            AdjustedScore = 0;
            inputCount    = inputCount_0;
            outputCount   = outputCount_1;
            AmountToSpawn = 0;
            speciesID     = 0;

            double inputRowSlice = 0.8d / (inputCount_0);

            neuronsChromosome = new Chromosome();
            linksChromosome   = new Chromosome();

            Chromosomes.Add(neuronsChromosome);
            Chromosomes.Add(linksChromosome);

            for (int i = 0; i < inputCount_0; i++)
            {
                neuronsChromosome.Add(new NEATNeuronGene(NEATNeuronType.Input,
                                                         i, 0, 0.1d + i * inputRowSlice));
            }

            neuronsChromosome.Add(new NEATNeuronGene(NEATNeuronType.Bias,
                                                     inputCount_0, 0, 0.9d));

            double outputRowSlice = 1 / (double)(outputCount_1 + 1);

            for (int i_2 = 0; i_2 < outputCount_1; i_2++)
            {
                neuronsChromosome.Add(new NEATNeuronGene(
                                          NEATNeuronType.Output, i_2 + inputCount_0 + 1, 1, (i_2 + 1)
                                          * outputRowSlice));
            }

            for (int i_3 = 0; i_3 < inputCount_0 + 1; i_3++)
            {
                for (int j = 0; j < outputCount_1; j++)
                {
                    linksChromosome.Add(new NEATLinkGene(
                                            ((NEATNeuronGene)neuronsChromosome.Get(i_3)).Id,
                                            ((NEATNeuronGene)Neurons.Get(
                                                 inputCount_0 + j + 1)).Id, true, inputCount_0
                                            + outputCount_1 + 1 + NumGenes,
                                            RangeRandomizer.Randomize(-1, 1), false));
                }
            }
        }
Beispiel #3
0
        private void addToChildAndSwap(Chromosome child, List <Gene> chosenGeneSet, GraphNode chosenNode, List <Gene> notChosenGeneSet, int choiceIndex)
        {
            child.Add(chosenGeneSet[choiceIndex]);
            var swapIndex = notChosenGeneSet.FindIndex((g) => ((GraphNode)g.ObjectValue).GetHashCode() == chosenNode.GetHashCode());

            swapElements(notChosenGeneSet, choiceIndex, swapIndex);
        }
Beispiel #4
0
        private void addToChildAndRemoveFromParents(Chromosome child, List <Gene> chosenGeneSet, GraphNode chosenNode, List <Gene> notChosenGeneSet)
        {
            child.Add(chosenGeneSet[0]);
            chosenGeneSet.RemoveAt(0);
            var removeIndex = notChosenGeneSet.FindIndex((g) => ((GraphNode)g.ObjectValue).GetHashCode() == chosenNode.GetHashCode());

            notChosenGeneSet.RemoveAt(0);
        }
Beispiel #5
0
    /*
     *  CycleToChromosome(Nodes)
     *   for j ← 1 to |Nodes|/2
     *        if Node2j−1 < Node2j
     *             Chromosomej ← Node2j /2
     *        else
     *             Chromosomej ← −Node2j−1/2
     *   return Chromosome
     */
    public Chromosome ToChromosome()
    {
        Chromosome chromosome = new Chromosome();

        for (int j = 0; j < Count / 2; ++j)
        {
            if (this[2 * j] < this[2 * j + 1])
            {
                chromosome.Add(this[2 * j + 1] / 2);
            }
            else
            {
                chromosome.Add(-this[2 * j] / 2);
            }
        }

        return(chromosome);
    }
Beispiel #6
0
        static void Main(string[] args)
        {
            // Initialize the game table, matches and distances
            WorldCupChronogram.Initialize();
            Distances.Initialize();

            // Population, with a chromossome length
            var population = new Population(CHROMOSOME_SIZE);

            // Random seed
            var random = new Random();

            // Initialize the population
            for (int i = 0; i < INITIAL_POPULATION_SIZE; i++)
            {
                var chromossome = new Chromosome();
                for (int j = 0; j < CHROMOSOME_SIZE; j++)
                {
                    //  Somedays have more or less games
                    var maxGamesInDays = WorldCupChronogram.Days[j].NumberOfGames;

                    var gene = new Gene(random.Next(maxGamesInDays));

                    chromossome.Add(gene);
                }

                population.Solutions.Add(chromossome);
            }

            // Elite operator
            var elite = new Elite(ETILISM);

            // Crossover operator
            var crossover = new Crossover(CROSSOVER_PROBABILITY);

            // Mutation operador
            var mutate = new SwapMutate(MUTATION_PROBABILITY);

            // GA
            var ga = new GeneticAlgorithm(population, CalculateFitness);

            // Add operators
            ga.Operators.Add(elite);
            ga.Operators.Add(crossover);
            ga.Operators.Add(mutate);

            // Handlers
            ga.OnGenerationComplete += ga_OnGenerationComplete;
            ga.OnRunComplete        += ga_OnRunComplete;

            ga.Run(Terminate);


            Console.ReadLine();
        }
Beispiel #7
0
        /// <summary>
        /// Calculate a WoC solution from a population
        /// Each gene value is the most popular value for a gene in that position across the population
        /// </summary>
        /// <param name="pop">The input population. Must contain individuals</param>
        /// <returns>A chromosome representing the WoC solution</returns>
        private Chromosome CalculateWoC(Population pop)
        {
            // Create a hash table. Columns are gene positions and rows are possible gene values
            // The values are the number of times that gene value occured in that position in the genome
            byte[,] hash = new byte[numIntsInSolution, solutionValueMax + 1];

            int i = 0, j = 0;

            // Fill the hash table
            foreach (Chromosome chrom in pop.Solutions)
            {                                         // Iterate through all individuals
                i = 0;                                // i tracks the current gene position in this individual
                foreach (Gene gene in chrom)
                {                                     // Iterate through this individuals genes
                    hash[i, (int)gene.ObjectValue]++; // Increment the correct location in the hash table
                    i++;                              // Increment our iterator
                }
            }

            // Create an empty Chromosome to fill and return
            Chromosome retChrom = new Chromosome();

            // Iterate over hash table again calculating values for return chromosome
            for (i = 0; i < numIntsInSolution; i++)
            { // Iterate through columns, which are gene positions that will be colapsed into single gene values based on which value is most populat in that position
                int mostPop       = -1;
                int timesRepeated = -1;
                for (j = 0; j < solutionValueMax; j++)
                { // Iterate through the rows in this column, finding the most popular value
                    // Make current value the most popular value if it's been here more times. If they're tied choose randomly
                    if (hash[i, j] > timesRepeated || (hash[i, j] == timesRepeated && rand.Next(0, 1) == 1))
                    {
                        timesRepeated = hash[i, j];
                        mostPop       = j;
                    }
                }

                // If we don't have any most popular value, the column was empty, something went very wrong, throw an exception.
                // (This shouldn't be able to happen, but it's still good to double check, as it might take some time to find this otherwise)
                if (mostPop == -1)
                {
                    throw new ApplicationException("Something went very wrong in WoC");
                }

                // Add this most popular gene value to the return chromosome
                var newGene = new Gene(mostPop);
                retChrom.Add(newGene);
            }

            // Let the WoC chromosome we built calculate it's fitness
            retChrom.Evaluate(CalculateFitness);

            // Return the WoC chromosome we built
            return(retChrom);
        }
        private Chromosome CopyChromosome(Chromosome toCopy)
        {
            var result = new Chromosome();

            for (int i = 0; i < toCopy.Genes.Count; i++)
            {
                result.Add(toCopy.Genes[i]);
            }

            return(result);
        }
        protected Chromosome GenerateRandomChromosome(int size)
        {
            var chromosome = new Chromosome();

            for (var i = 0; i < size; i++)
            {
                var gene = RandomGenerator.Next(NumberOfColors);
                chromosome.Add(gene);
            }

            return(chromosome);
        }
Beispiel #10
0
        private Population GenerateInitialPopulation(int popSize)
        {
            var population = new Population();

            for (int i = 0; i < popSize; i++)
            {
                var chromosome = new Chromosome();
                for (int j = 0; j < numIntsInSolution; j++)
                {
                    chromosome.Add(new Gene(rand.Next(solutionValueMin, solutionValueMax)));
                }

                population.Solutions.Add(chromosome);
            }

            return(population);
        }
Beispiel #11
0
        /// <summary>
        /// Mutate the genome by adding a neuron.
        /// </summary>
        ///
        /// <param name="mutationRate">The mutation rate.</param>
        /// <param name="numTrysToFindOldLink">The number of tries to find a link to split.</param>
        internal void AddNeuron(double mutationRate, int numTrysToFindOldLink)
        {
            // should we add a neuron?
            if (ThreadSafeRandom.NextDouble() > mutationRate)
            {
                return;
            }

            int countTrysToFindOldLink = numTrysToFindOldLink;

            // the link to split
            NEATLinkGene splitLink = null;

            int sizeBias = inputCount + outputCount + 10;

            // if there are not at least
            int upperLimit;

            if (linksChromosome.Size() < sizeBias)
            {
                upperLimit = NumGenes - 1 - (int)Math.Sqrt(NumGenes);
            }
            else
            {
                upperLimit = NumGenes - 1;
            }

            while ((countTrysToFindOldLink--) > 0)
            {
                // choose a link, use the square root to prefer the older links
                int i    = RangeRandomizer.RandomInt(0, upperLimit);
                var link = (NEATLinkGene)linksChromosome
                           .Get(i);

                // get the from neuron
                long fromNeuron = link.FromNeuronID;

                if ((link.Enabled) &&
                    (!link.Recurrent) &&
                    (((NEATNeuronGene)Neurons.Get(
                          GetElementPos(fromNeuron))).NeuronType != NEATNeuronType.Bias))
                {
                    splitLink = link;
                    break;
                }
            }

            if (splitLink == null)
            {
                return;
            }

            splitLink.Enabled = false;

            double originalWeight = splitLink.Weight;

            long from = splitLink.FromNeuronID;
            long to   = splitLink.ToNeuronID;

            var fromGene = (NEATNeuronGene)Neurons.Get(
                GetElementPos(from));
            var toGene = (NEATNeuronGene)Neurons.Get(
                GetElementPos(to));

            double newDepth = (fromGene.SplitY + toGene.SplitY) / 2;
            double newWidth = (fromGene.SplitX + toGene.SplitX) / 2;

            // has this innovation already been tried?
            NEATInnovation innovation = ((NEATTraining)GA).Innovations.CheckInnovation(from, to,
                                                                                       NEATInnovationType
                                                                                       .NewNeuron);

            // prevent chaining
            if (innovation != null)
            {
                long neuronID = innovation.NeuronID;

                if (AlreadyHaveThisNeuronID(neuronID))
                {
                    innovation = null;
                }
            }

            if (innovation == null)
            {
                // this innovation has not been tried, create it
                long newNeuronID = ((NEATTraining)GA).Innovations.CreateNewInnovation(from, to,
                                                                                      NEATInnovationType.
                                                                                      NewNeuron,
                                                                                      NEATNeuronType.
                                                                                      Hidden,
                                                                                      newWidth, newDepth);

                neuronsChromosome.Add(new NEATNeuronGene(
                                          NEATNeuronType.Hidden, newNeuronID, newDepth, newWidth));

                // add the first link
                long link1ID = (GA).Population.AssignInnovationID();

                ((NEATTraining)GA).Innovations
                .CreateNewInnovation(from, newNeuronID,
                                     NEATInnovationType.NewLink);

                var link1 = new NEATLinkGene(from, newNeuronID,
                                             true, link1ID, 1.0d, false);

                linksChromosome.Add(link1);

                // add the second link
                long link2ID = (GA).Population.AssignInnovationID();

                ((NEATTraining)GA).Innovations
                .CreateNewInnovation(newNeuronID, to,
                                     NEATInnovationType.NewLink);

                var link2 = new NEATLinkGene(newNeuronID, to, true,
                                             link2ID, originalWeight, false);

                linksChromosome.Add(link2);
            }

            else
            {
                // existing innovation
                long newNeuronID_0 = innovation.NeuronID;

                NEATInnovation innovationLink1 = ((NEATTraining)GA).Innovations.CheckInnovation(from,
                                                                                                newNeuronID_0,
                                                                                                NEATInnovationType
                                                                                                .
                                                                                                NewLink);
                NEATInnovation innovationLink2 =
                    ((NEATTraining)GA).Innovations.CheckInnovation(newNeuronID_0, to,
                                                                   NEATInnovationType.NewLink);

                if ((innovationLink1 == null) || (innovationLink2 == null))
                {
                    throw new NeuralNetworkError("NEAT Error");
                }

                var link1_1 = new NEATLinkGene(from, newNeuronID_0,
                                               true, innovationLink1.InnovationID, 1.0d, false);
                var link2_2 = new NEATLinkGene(newNeuronID_0, to, true,
                                               innovationLink2.InnovationID, originalWeight, false);

                linksChromosome.Add(link1_1);
                linksChromosome.Add(link2_2);

                var newNeuron = new NEATNeuronGene(
                    NEATNeuronType.Hidden, newNeuronID_0, newDepth, newWidth);

                neuronsChromosome.Add(newNeuron);
            }

            return;
        }
Beispiel #12
0
        /// <summary>
        /// Mutate the genome by adding a link to this genome.
        /// </summary>
        ///
        /// <param name="mutationRate">The mutation rate.</param>
        /// <param name="chanceOfLooped">The chance of a self-connected neuron.</param>
        /// <param name="numTrysToFindLoop">The number of tries to find a loop.</param>
        /// <param name="numTrysToAddLink">The number of tries to add a link.</param>
        internal void AddLink(double mutationRate, double chanceOfLooped,
                              int numTrysToFindLoop, int numTrysToAddLink)
        {
            // should we even add the link
            if (ThreadSafeRandom.NextDouble() > mutationRate)
            {
                return;
            }

            int countTrysToFindLoop = numTrysToFindLoop;
            int countTrysToAddLink  = numTrysToFindLoop;

            // the link will be between these two neurons
            long neuron1ID = -1;
            long neuron2ID = -1;

            bool recurrent = false;

            // a self-connected loop?
            if (ThreadSafeRandom.NextDouble() < chanceOfLooped)
            {
                // try to find(randomly) a neuron to add a self-connected link to
                while ((countTrysToFindLoop--) > 0)
                {
                    NEATNeuronGene neuronGene = ChooseRandomNeuron(false);

                    // no self-links on input or bias neurons
                    if (!neuronGene.Recurrent &&
                        (neuronGene.NeuronType != NEATNeuronType.Bias) &&
                        (neuronGene.NeuronType != NEATNeuronType.Input))
                    {
                        neuron1ID = neuronGene.Id;
                        neuron2ID = neuronGene.Id;

                        neuronGene.Recurrent = true;
                        recurrent            = true;

                        countTrysToFindLoop = 0;
                    }
                }
            }
            else
            {
                // try to add a regular link
                while ((countTrysToAddLink--) > 0)
                {
                    NEATNeuronGene neuron1 = ChooseRandomNeuron(true);
                    NEATNeuronGene neuron2 = ChooseRandomNeuron(false);

                    if (!IsDuplicateLink(neuron1ID, neuron2ID) &&
                        (neuron1.Id != neuron2.Id) &&
                        (neuron2.NeuronType != NEATNeuronType.Bias))
                    {
                        neuron1ID = neuron1.Id;
                        neuron2ID = neuron2.Id;
                        break;
                    }
                }
            }

            // did we fail to find a link
            if ((neuron1ID < 0) || (neuron2ID < 0))
            {
                return;
            }

            // check to see if this innovation has already been tried
            NEATInnovation innovation = ((NEATTraining)GA).Innovations.CheckInnovation(neuron1ID,
                                                                                       neuron1ID,
                                                                                       NEATInnovationType
                                                                                       .NewLink);

            // see if this is a recurrent(backwards) link
            var neuronGene_0 = (NEATNeuronGene)neuronsChromosome
                               .Get(GetElementPos(neuron1ID));

            if (neuronGene_0.SplitY > neuronGene_0.SplitY)
            {
                recurrent = true;
            }

            // is this a new innovation?
            if (innovation == null)
            {
                // new innovation
                ((NEATTraining)GA).Innovations
                .CreateNewInnovation(neuron1ID, neuron2ID,
                                     NEATInnovationType.NewLink);

                long id2 = GA.Population.AssignInnovationID();

                var linkGene = new NEATLinkGene(neuron1ID,
                                                neuron2ID, true, id2, RangeRandomizer.Randomize(-1, 1),
                                                recurrent);
                linksChromosome.Add(linkGene);
            }
            else
            {
                // existing innovation
                var linkGene_1 = new NEATLinkGene(neuron1ID,
                                                  neuron2ID, true, innovation.InnovationID,
                                                  RangeRandomizer.Randomize(-1, 1), recurrent);
                linksChromosome.Add(linkGene_1);
            }
        }
        /// <summary>
        /// Perform a cross over.
        /// </summary>
        /// <param name="mom">The mother genome.</param>
        /// <param name="dad">The father genome.</param>
        /// <returns></returns>
        public new NEATGenome Crossover(NEATGenome mom, NEATGenome dad)
        {
            NEATParent best;

            // first determine who is more fit, the mother or the father?
            if (mom.Score == dad.Score)
            {
                if (mom.NumGenes == dad.NumGenes)
                {
                    if (ThreadSafeRandom.NextDouble() > 0)
                    {
                        best = NEATParent.Mom;
                    }
                    else
                    {
                        best = NEATParent.Dad;
                    }
                }

                else
                {
                    if (mom.NumGenes < dad.NumGenes)
                    {
                        best = NEATParent.Mom;
                    }
                    else
                    {
                        best = NEATParent.Dad;
                    }
                }
            }
            else
            {
                if (Comparator.IsBetterThan(mom.Score, dad.Score))
                {
                    best = NEATParent.Mom;
                }

                else
                {
                    best = NEATParent.Dad;
                }
            }

            var babyNeurons = new Chromosome();
            var babyGenes   = new Chromosome();

            var vecNeurons = new List <long>();

            int curMom = 0;
            int curDad = 0;

            NEATLinkGene momGene;
            NEATLinkGene dadGene;

            NEATLinkGene selectedGene = null;

            while ((curMom < mom.NumGenes) || (curDad < dad.NumGenes))
            {
                if (curMom < mom.NumGenes)
                {
                    momGene = (NEATLinkGene)mom.Links.Get(curMom);
                }
                else
                {
                    momGene = null;
                }

                if (curDad < dad.NumGenes)
                {
                    dadGene = (NEATLinkGene)dad.Links.Get(curDad);
                }
                else
                {
                    dadGene = null;
                }

                if ((momGene == null) && (dadGene != null))
                {
                    if (best == NEATParent.Dad)
                    {
                        selectedGene = dadGene;
                    }
                    curDad++;
                }
                else if ((dadGene == null) && (momGene != null))
                {
                    if (best == NEATParent.Mom)
                    {
                        selectedGene = momGene;
                    }
                    curMom++;
                }
                else if (momGene.InnovationId < dadGene.InnovationId)
                {
                    if (best == NEATParent.Mom)
                    {
                        selectedGene = momGene;
                    }
                    curMom++;
                }
                else if (dadGene.InnovationId < momGene.InnovationId)
                {
                    if (best == NEATParent.Dad)
                    {
                        selectedGene = dadGene;
                    }
                    curDad++;
                }
                else if (dadGene.InnovationId == momGene.InnovationId)
                {
                    if (ThreadSafeRandom.NextDouble() < 0.5f)
                    {
                        selectedGene = momGene;
                    }

                    else
                    {
                        selectedGene = dadGene;
                    }
                    curMom++;
                    curDad++;
                }

                if (babyGenes.Size() == 0)
                {
                    babyGenes.Add(selectedGene);
                }

                else
                {
                    if (((NEATLinkGene)babyGenes.Get(babyGenes.Size() - 1))
                        .InnovationId != selectedGene.InnovationId)
                    {
                        babyGenes.Add(selectedGene);
                    }
                }

                // Check if we already have the nodes referred to in SelectedGene.
                // If not, they need to be added.
                AddNeuronID(selectedGene.FromNeuronID, vecNeurons);
                AddNeuronID(selectedGene.ToNeuronID, vecNeurons);
            } // end while

            // now create the required nodes. First sort them into order
            vecNeurons.Sort();

            for (int i = 0; i < vecNeurons.Count; i++)
            {
                babyNeurons.Add(Innovations.CreateNeuronFromID(
                                    vecNeurons[i]));
            }

            // finally, create the genome
            var babyGenome = new NEATGenome(Population
                                            .AssignGenomeID(), babyNeurons, babyGenes, mom.InputCount,
                                            mom.OutputCount);

            babyGenome.GA         = this;
            babyGenome.Population = Population;

            return(babyGenome);
        }