/// <summary> /// Takes 2 parent gene vectors, selects a midpoint and then swaps the ends /// of each genome creating 2 new genomes which are stored in baby1 and baby2 /// </summary> /// <param name="other"></param> /// <param name="baby1"></param> /// <param name="baby2"></param> public void CrossOver(Genome <TMainModel, TCombinationModel> other, Genome <TMainModel, TCombinationModel> baby1, Genome <TMainModel, TCombinationModel> baby2) { // just return parents as offspring dependent on the rate // or if parents are the same if ((GAUtils.RandDouble() > _settings.CrossoverRate) || (this == other)) { baby1.Genes = this.Genes; baby2.Genes = other.Genes; return; } if (baby1.Genes.Count <= 1 || baby2.Genes.Count <= 1) { baby1.Genes = this.Genes; baby2.Genes = other.Genes; return; } // determine a crossover point int crossOverPoint = GAUtils.RandInt(0, this.Genes.Count - 1); // = 29 for (int i = 0; i < this.Genes.Count; i++) { var crossed = Genes[i].Cross(other.Genes[i], i < crossOverPoint); baby1.Genes.Add(crossed[0]); baby2.Genes.Add(crossed[1]); } }
public void Initialize() { int geneSize = _settings.InitialPopulation.Count; // number of all items to be combined Parts.Clear(); // for re-initialisation when there is already a gene that's the same for (int i = 0; i < geneSize; i++) { Parts.Add(new GenePart <TCombinationModel> { Model = _settings.InitialPopulation[i], Active = GAUtils.RandDouble() > 0.5 }); } }
/// <summary> /// Iterates through each gene flipping the bits acording to the mutation rate /// </summary> public void Mutate() { // Go through each gene for (int i = 0; i < Genes.Count; i++) { Gene <TCombinationModel> gene = Genes[i]; int mutationCounter = 0; for (int j = 0; j < gene.Parts.Count; j++) { //do we flip this bit? if (GAUtils.RandDouble() < _settings.MutationRate) { //flip the bit gene.Parts[j].Active = gene.Parts[j].Active == false; mutationCounter++; } } //Debug.WriteLineIf(mutationCounter > 0, $"> Mutated {mutationCounter}/{gene.Parts.Count} items"); } }
private Genome <TMainModel, TCombinationModel> RouletteWheelSelection() { double fSlice = GAUtils.RandDouble() * TotalFitnessScore; double cfTotal = 0.0; int selectedGenome = 0; for (int i = 0; i < Genomes.Count; ++i) { cfTotal += Genomes[i].Fitness; if (cfTotal > fSlice) { selectedGenome = i; break; } } return(Genomes[selectedGenome]); }