예제 #1
0
파일: Mutation.cs 프로젝트: mykwillis/genX
 /// <summary>
 /// Mutates a gene by bitwise mutation.
 /// </summary>
 /// <param name="gene"></param>
 /// <returns></returns>
 public static Gene Mutate(Gene gene)
 {
     if (gene is BinaryGene)
     {
         BinaryGene g = (BinaryGene)gene.Clone();
         g.Value = !(BinaryGene)gene;
         return(g);
     }
     else if (gene is DoubleGene)
     {
         DoubleGene g     = (DoubleGene)gene.Clone();
         byte[]     bytes = BitConverter.GetBytes(g.Value);
         BitArray   ba    = new BitArray(bytes);
         int        p     = Utils.Rand.Next(ba.Length);
         ba.Set(p, !ba[p]);
         ba.CopyTo(bytes, 0);
         g.Value = BitConverter.ToDouble(bytes, 0);
         return(g);
     }
     else if (gene is IntegerGene)
     {
         IntegerGene g     = (IntegerGene)gene.Clone();
         byte[]      bytes = BitConverter.GetBytes(g.Value);
         BitArray    ba    = new BitArray(bytes);
         int         p     = Utils.Rand.Next(ba.Length);
         ba.Set(p, !ba[p]);
         ba.CopyTo(bytes, 0);
         g.Value = BitConverter.ToInt32(bytes, 0);
         return(g);
     }
     return((Gene)gene.Clone()); // default
 }
예제 #2
0
        public void Clone_Gene_ClonedGene()
        {
            var representation = new [] { 1.2m, 1.3m, 1.4m, 1.5m };
            var probability    = 0.1m;
            var gene           = new Gene <decimal>(representation, probability);

            var cloned = (Gene <decimal>)gene.Clone();

            Assert.AreEqual(cloned.Representation[0], representation[0]);
            Assert.AreEqual(cloned.Representation[1], representation[1]);
            Assert.AreEqual(cloned.Representation[2], representation[2]);
            Assert.AreEqual(cloned.Representation[3], representation[3]);

            Assert.AreEqual(cloned.MutationProbability, probability);
        }
            private Gene CrossOverGenes(Gene a, Gene b)
            {
                double mutationProb = 0.5f;
                Gene   c            = a.Clone();

                for (int i = 0; i < a.collection.Count; i++)
                {
                    if (random.NextDouble() > mutationProb)
                    {
                        c.collection[i] = b.collection[i].Clone();
                    }
                }

                return(c);
            }
예제 #4
0
        private void Crossbreed(Individual child)
        {
            var rnd       = new Random();
            var swopIndex = rnd.Next(0, child.Genes.Length);

            //todo: enhance per category e.g. breakfast, snack, lunch, supper
            for (int i = 0; i < swopIndex; i++)
            {
                //todo: check for duplicate genes
                child.Genes[i] = Gene.Clone(Best.Genes[i]);
            }

            //todo: enhance per category e.g. breakfast, snack, lunch, supper
            for (int i = swopIndex; i < child.Genes.Length; i++)
            {
                //todo: check for duplicate genes
                child.Genes[i] = Gene.Clone(SecondBest.Genes[i]);
            }
        }
예제 #5
0
        public void Run(object obj_iterations)
        {
            int nrOfIterations = (int)obj_iterations;

            double referenceNegativeIndex  = double.MaxValue;
            double referenceComeback       = NrOfPolygons;
            bool   nrOfMutationsTryChanged = false;

            int    limit = 0;
            int    shakeTheImageCounter   = 0;
            double currentNegativeFitness = workingGene.NegativeFitness;

            for (int i = 0; i < nrOfIterations; i++)
            {
                if (CommandChannel.GetCommand() == 1)
                {
                    break;
                }
                List <int> mutationsList = retrieveMutationsList();
                for (int mi = 0; mi < mutationsList.Count; mi++)
                {
                    int mutationStep = mutationsList[mi];
                    switch (mutationStep)
                    {
                    case 1: performAddPolygon(workingGene); break;

                    case 2: performMutateColor(workingGene); break;

                    case 3: performMutatePolygon(workingGene); break;

                    case 4: performMutatePolygonAndColor(workingGene); break;

                    case 5: performMutateColorParam(workingGene); break;

                    case 6: performMutatePolygonPoint(workingGene); break;
                    }
                }


                #region check if the gene had evolved in the last 250 iterations; comment this region if you don't one to have momentum in your app
                if (currentNegativeFitness != workingGene.NegativeFitness)
                {
                    currentNegativeFitness = workingGene.NegativeFitness;
                    shakeTheImageCounter   = 0;
                }
                else
                {
                    //that means the in the last 250 iterations nothing changed in the gene fitness.
                    if (shakeTheImageCounter > 250)
                    {
                        int nrOfPolysToBeRemoved = workingGene.NrOfPolygons / 10;
                        for (int ix = 0; ix < nrOfPolysToBeRemoved; ix++)
                        {
                            randomlyRemovePolygons(workingGene);
                        }
                        referenceComeback = workingGene.Polygons.Count + 1;
                    }
                    shakeTheImageCounter++;
                }
                #endregion

                //if gene is more fit, we added to the container;
                Console.WriteLine("Negative fitness: {0} ,     {1}", workingGene.NegativeFitness, workingGene.Polygons.Count);
                if (workingGene.NegativeFitness < referenceNegativeIndex)
                {
                    GeneContainer.Instance.AddGene(workingGene.Clone());
                    referenceNegativeIndex = workingGene.NegativeFitness;
                }

                #region every 100 iterations we increase the number of polygons, till we reach 50
                if (workingGene.Polygons.Count < 50 && this.NrOfPolygons < 50)
                {
                    if (i % 100 == 0 && i != 0)
                    {
                        this.NrOfPolygons++;
                        workingGene.NrOfPolygons++;
                    }
                }
                #endregion

                //if every time the number of polygons in the gene reaches the max number of polygons, then we increase the nr of polygons and
                //we remove the less fit individuals
                if (workingGene.Polygons.Count < 50)
                {
                    if (workingGene.Polygons.Count == referenceComeback)
                    {
                        limit = workingGene.Polygons.Count / 10;
                        for (int ix = 0; ix < limit; ix++)
                        {
                            removeLessFitPolys(workingGene);
                        }
                        Console.WriteLine("-------- [ReferenceComeback] :" + referenceComeback);
                        referenceComeback++;
                    }
                }
                // when 50 poly are reached, we double the nr of mutations tries;
                // and we remove a larger number of less fit individuals;
                else if (workingGene.Polygons.Count >= 50)
                {
                    if (nrOfMutationsTryChanged == false)
                    {
                        NrOfMutationsTries      = NrOfMutationsTries * 2;
                        nrOfMutationsTryChanged = true;
                    }

                    limit = workingGene.Polygons.Count / 8;
                    for (int ix = 0; ix < limit; ix++)
                    {
                        removeLessFitPolys(workingGene);
                    }
                }
            }

            CommandChannel.SetCommand(2); //tell timer to stop
        }