/// <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 }
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); }
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]); } }
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 }