/// <summary> /// Generates a random set of genes for this chromosome /// </summary> public void GenerateRandomGenes() { for (int i = 0; i < genes.Length; i++) { genes[i] = Friends.GetRandomDouble(); } }
/// <summary> /// Single point crossover /// </summary> /// <param name="probability"></param> public void CrossoverPop(double probability) { if (probability > 0) { int size = chromosomes[0].GetGenes().Length; for (int i = 0; i < chromosomes.Length; i += 2) { if (Friends.GetRandomDouble() < probability) { int splice = Friends.GetRandomInt(0, size); double[] limbo1 = new double[size]; double[] limbo2 = new double[size]; chromosomes[i].GetGenes().CopyTo(limbo1, 0); chromosomes[i + 1].GetGenes().CopyTo(limbo2, 0); for (int s = splice; s < size; s++) { limbo1[s] = chromosomes[i + 1].GetGenes()[s]; limbo2[s] = chromosomes[i].GetGenes()[s]; } chromosomes[i].SetGenes(limbo1); chromosomes[i + 1].SetGenes(limbo2); } } } }
/// <summary> /// Replaces the population with a new one based on fitness using Roulette Wheel selection /// </summary> public void SelectPop() { // First Elitism, then Roulette Wheel technique as described by Melanie Mitchell, An Introduction to GAs, p.166 double fitSum; double totalFitness = 0.0; int counter = 0; // Set up a fresh new population (no clone). Population newPop = new Population(this.chromosomes.Length, popSliders, popGenePools, owner, -1); // Copy the elites for (int i = 0; i < chromosomes.Length; i++) { if (chromosomes[i].GetFitness() == 1.0) { newPop.chromosomes[counter] = new Chromosome(chromosomes[i]); newPop.chromosomes[counter].isRepresentative = false; newPop.chromosomes[counter].isElite = true; counter++; } } // Now for the roulette wheel selection for the new population for (int i = 0; i < chromosomes.Length; i++) { totalFitness += chromosomes[i].GetFitness(); } // Run from the counter above for (int i = counter; i < newPop.chromosomes.Length; i++) { double weightedRandom = Friends.GetRandomDouble() * totalFitness; fitSum = 0.0; for (int j = 0; j < chromosomes.Length; j++) { fitSum += chromosomes[j].GetFitness(); // Stop when we get to the right design // higher fitnesses will result in a greater jump in fitsum, and therefore more likely to be above the random number. if (fitSum > weightedRandom) { // Clone the chromosomes, reset all the representatives // Fitness is cloned at this stage newPop.chromosomes[i] = new Chromosome(chromosomes[j]); newPop.chromosomes[i].isRepresentative = false; newPop.chromosomes[i].isElite = false; break; } } } // Finally, Replace the current popultion of chromosomes with the newPop for (int i = 0; i < chromosomes.Length; i++) { chromosomes[i] = new Chromosome(newPop.chromosomes[i]); } }
/// <summary> /// Goes through each gene and mutates it depending on a given probability /// </summary> /// <param name="probability"> probability that a single gene in the chomrosome will mutate</param> public void Mutate(double probability) { for (int i = 0; i < genes.Length; i++) { double tempRand = Friends.GetRandomDouble(); if (tempRand < probability) { genes[i] = Friends.GetRandomDouble(); } } }
/// <summary> /// Shakes the genes a little /// </summary> /// <param name="t">amount to jiggle the genes by from 0.0 to 1.0</param> public void JiggleGenes(double t) { for (int i = 0; i < genes.Length; i++) { // Note, you can't risk having two chromosomes with the same genes, even 0.0 and 1.0 genes[i] += (0.5 * t - Friends.GetRandomDouble() * t); if (genes[i] < 0.0) { genes[i] = 0.0 + Friends.GetRandomDouble() * 0.001; } if (genes[i] > 1.0) { genes[i] = 1.0 - Friends.GetRandomDouble() * 0.001; } } }
/// <summary> /// Replaces the population with a new one based on fitness using Roulette Wheel selection /// </summary> public void RoulettePop() { // Roulette Wheel technique here as described by Melanie Mitchell, An Introduction to GAs, p.166 double fitSum; double totalFitness = 0.0; // Set up a fresh population. Population newPop = new Population(this.chromosomes.Length, popSliders, popGenePools, owner, -1); // find the total fitness for (int i = 0; i < chromosomes.Length; i++) { totalFitness += chromosomes[i].GetFitness(); } // Now for the roulette wheel selection for the new population for (int i = 0; i < newPop.chromosomes.Length; i++) { double weightedRandom = Friends.GetRandomDouble() * totalFitness; fitSum = 0.0; for (int j = 0; j < chromosomes.Length; j++) { fitSum += chromosomes[j].GetFitness(); if (fitSum > weightedRandom) { // Clone the chromosomes, but make sure to reset if the design is a cluster representative newPop.chromosomes[i] = chromosomes[j].Clone(); newPop.chromosomes[i].isRepresentative = false; break; } } } // Replace the current popultion of chromosomes with the newPop for (int i = 0; i < chromosomes.Length; i++) { chromosomes[i] = newPop.chromosomes[i].Clone(); } // Make sure to reset all the fitnesses here (selection has now already occured). ResetAllFitness(); }