/// <summary> /// Create a MateWorker. /// </summary> /// <param name="mother">The mother.</param> /// <param name="father">The father.</param> /// <param name="child1">The first child.</param> /// <param name="child2">The second child.</param> public MateWorker(IGenome mother, IGenome father, IGenome child1, IGenome child2, GATracker.MatedElement matedElement) { this.mother = mother; this.father = father; this.child1 = child1; this.child2 = child2; this.matedElement = matedElement; }
/// <summary> /// Mate two genomes. Will loop over all chromosomes. /// </summary> /// <param name="father">The father.</param> /// <param name="child1">The first child.</param> /// <param name="child2">The second child.</param> public void Mate(IGenome father, IGenome child1, IGenome child2, GATracker.MatedElement matedElement) { int motherChromosomes = Chromosomes.Count; int fatherChromosomes = father.Chromosomes.Count; if (motherChromosomes != fatherChromosomes) { throw new GeneticError( "Mother and father must have same chromosome count, Mother:" + motherChromosomes + ",Father:" + fatherChromosomes); } for (int i = 0; i < fatherChromosomes; i++) { Chromosome motherChromosome = chromosomes[i]; Chromosome fatherChromosome = father.Chromosomes[i]; Chromosome offspring1Chromosome = child1.Chromosomes[i]; Chromosome offspring2Chromosome = child2.Chromosomes[i]; //This splices the chromosomes together, using a random number to decide splice points GA.Crossover.Mate(motherChromosome, fatherChromosome, offspring1Chromosome, offspring2Chromosome); //Set the gene number if (matedElement != null) { matedElement.SetNumChildGenes(offspring1Chromosome.Genes.Count, 1); matedElement.SetNumChildGenes(offspring2Chromosome.Genes.Count, 2); } //Now we potentially mutate the children if (ThreadSafeRandom.NextDouble() < GA.MutationPercent) { if (matedElement != null) { matedElement.Child1Mutated = true; } GA.Mutate.PerformMutation(offspring1Chromosome, matedElement, 1); } //Now we potentially mutate the children if (ThreadSafeRandom.NextDouble() < GA.MutationPercent) { if (matedElement != null) { matedElement.Child2Mutated = true; } GA.Mutate.PerformMutation(offspring2Chromosome, matedElement, 2); } } child1.Decode(); child2.Decode(); GA.PerformScoreCalculation(child1); GA.PerformScoreCalculation(child2); }
/// <summary> /// Perform a perturb mutation on the specified chromosome. /// </summary> /// <param name="chromosome">The chromosome to mutate.</param> public void PerformMutation(Chromosome chromosome, GATracker.MatedElement mutatedElement, int childIndex) { bool usePertubAmount1 = ThreadSafeRandom.NextDouble() <= percentageUsePerturbAmount1; foreach (IGene gene in chromosome.Genes) { if (gene is DoubleGene) { if (usePertubAmount1) { if (ThreadSafeRandom.NextDouble() < percentageGenesToPerturb1) { DoubleGene doubleGene = (DoubleGene)gene; double value = doubleGene.Value; double peturbAmount = (perturbAmount1 - (ThreadSafeRandom.NextDouble()) * perturbAmount1 * 2); mutatedElement.AddChildMutation(new GATracker.MutationRecord(perturbAmount1, peturbAmount), childIndex); value += peturbAmount; doubleGene.Value = value; } } else { //if (ThreadSafeRandom.NextDouble() < percentageGenesToPerturb1) //{ // DoubleGene doubleGene = (DoubleGene)gene; // double value = doubleGene.Value; // double peturbAmount = (perturbAmount1 - (ThreadSafeRandom.NextDouble()) * perturbAmount1 * 2); // mutatedElement.AddChildMutation(new GATracker.MutationRecord(perturbAmount1, peturbAmount), childIndex); // value += peturbAmount; // doubleGene.Value = value; //} if (ThreadSafeRandom.NextDouble() < percentageGenesToPerturb2) { DoubleGene doubleGene = (DoubleGene)gene; double value = doubleGene.Value; double peturbAmount = (perturbAmount2 - (ThreadSafeRandom.NextDouble()) * perturbAmount2 * 2); mutatedElement.AddChildMutation(new GATracker.MutationRecord(perturbAmount2, peturbAmount), childIndex); value += peturbAmount; doubleGene.Value = value; } } } } }
/// <summary> /// Perform one generation. /// </summary> public virtual void Iteration(GATracker gaTracker) { int countToMate = (int)(Population.Genomes.Count * PercentToMate); int matingPopulationSize = (int)(Population.Genomes.Count * MatingPopulation); //The only individuals we want to preserve is the mating population. //i.e. everything but the mating population gets replaced. int newOffspringCount = Population.Genomes.Count - matingPopulationSize; int newOffspringIndex = Population.Genomes.Count - newOffspringCount; int offspringCount = countToMate * 2; //int offspringIndex = Population.Genomes.Count - offspringCount; //TaskGroup group = EngineConcurrency.Instance.CreateTaskGroup(); // mate and form the next generation //20 < 80 while (newOffspringIndex < newOffspringCount + matingPopulationSize) { for (int i = 0; i < countToMate; i++) { IGenome mother = Population.Genomes[i]; int fatherInt = (int)(ThreadSafeRandom.NextDouble() * matingPopulationSize); IGenome father = Population.Genomes[fatherInt]; IGenome child1 = Population.Genomes[newOffspringIndex]; IGenome child2 = Population.Genomes[newOffspringIndex + 1]; GATracker.MatedElement matedElement = new GATracker.MatedElement(i, fatherInt, newOffspringIndex, newOffspringIndex + 1); MateWorker worker = new MateWorker(mother, father, child1, child2, matedElement); //EngineConcurrency.Instance.ProcessTask(worker, group); worker.Run(); //Add the matedElement to the GATracker gaTracker.AddMatedElement(matedElement); newOffspringIndex += 2; } } //group.WaitForComplete(); // sort the next generation Population.Sort(); }
public void PerformMutation(Chromosome chromosome, GATracker.MatedElement matedElement, int childIndex) { throw new NotImplementedException(); }