private Tuple <Ind, Ind> SelectTwoParents(Ind[] currentPopulation, double[] fitnesses) { var totalProbability = fitnesses.Sum(); var probabilitySelection = Enumerable.Range(0, populationSize).Select(i => fitnesses[i] / totalProbability).ToArray(); var currentProbability = 0.0; Ind parent1 = new Ind(); Ind parent2 = new Ind(); for (int i = 0; i < currentPopulation.Count(); i++) { currentProbability += probabilitySelection[i]; if (currentProbability >= r.NextDouble()) { parent1 = currentPopulation[i]; } if (currentProbability >= r.NextDouble()) { parent2 = currentPopulation[i]; } } var parents = new Tuple <Ind, Ind>(parent1, parent2); return(parents); }
private double ComputeFitness(Ind individual) { var bitsToInt = Convert.ToInt32(individual.bits, 2); var fitness = -(Math.Pow(bitsToInt, 2)) + (7 * bitsToInt); return(fitness); }
//New child is made using singlepoint crossover private Tuple <Ind, Ind> Crossover(Tuple <Ind, Ind> parents) { var crossoverIndex = (digits / 2); Ind child1 = new Ind(); Ind child2 = new Ind(); child1.bits = parents.Item1.bits.Substring(0, crossoverIndex) + parents.Item2.bits.Substring((crossoverIndex), (digits - crossoverIndex)); child2.bits = parents.Item2.bits.Substring(0, crossoverIndex) + parents.Item1.bits.Substring((crossoverIndex), (digits - crossoverIndex)); var newChildren = new Tuple <Ind, Ind>(child1, child2); return(newChildren); }
private Ind Mutation(Ind child, double mutationRate) { StringBuilder sbChild = new StringBuilder(child.bits); for (int i = 0; i < digits; i++) { if (r.NextDouble() < mutationRate) { sbChild[i] = ('0' == child.bits[i] ? '1' : '0'); } } child.bits = sbChild.ToString(); return(child); }
public Ind Run() { Stopwatch sw = new Stopwatch(); sw.Start(); // initialize the first population var initialPopulation = Enumerable.Range(0, populationSize).Select(i => CreateIndividual()).ToArray(); var currentPopulation = initialPopulation; for (int generation = 0; generation < numIterations; generation++) { // compute fitness of each individual in the population var fitnesses = Enumerable.Range(0, populationSize).Select(i => ComputeFitness(currentPopulation[i])).ToArray(); var nextPopulation = new Ind[populationSize]; // apply elitism int startIndex; if (elitism) { startIndex = 1; var populationWithFitness = currentPopulation.Select((individual, index) => new Tuple <Ind, double>(individual, fitnesses[index])); var populationSorted = populationWithFitness.OrderByDescending(tuple => tuple.Item2); // item2 is the fitness var bestIndividual = populationSorted.First(); nextPopulation[0] = bestIndividual.Item1; } else { startIndex = 0; } // initialize the selection function given the current individuals and their fitnesses var getTwoParents = SelectTwoParents(currentPopulation, fitnesses); // create the individuals of the next generation for (int newInd = startIndex; newInd < populationSize; newInd++) { // select two parents var parents = SelectTwoParents(currentPopulation, fitnesses); // do a crossover between the selected parents to generate two children (with a certain probability, crossover does not happen and the two parents are kept unchanged) Tuple <Ind, Ind> offspring; if (r.NextDouble() < crossoverRate) { offspring = Crossover(parents); } else { offspring = parents; } // save the two children in the next population (after mutation) nextPopulation[newInd++] = Mutation(offspring.Item1, mutationRate); if (newInd < populationSize) //there is still space for the second children inside the population { nextPopulation[newInd] = Mutation(offspring.Item2, mutationRate); } } //the new population becomes the current one currentPopulation = nextPopulation; } //recompute the fitnesses on the final population and return the best individual var finalFitnesses = Enumerable.Range(0, populationSize).Select(i => ComputeFitness(currentPopulation[i])).ToArray(); Console.WriteLine("Run Time: " + sw.Elapsed); Console.WriteLine("Average fitness of last population: " + finalFitnesses.Average()); Console.WriteLine("Best fitness of last population: " + finalFitnesses.Max()); return(currentPopulation.Select((individual, index) => new Tuple <Ind, double>(individual, finalFitnesses[index])).OrderByDescending(tuple => tuple.Item2).First().Item1); }
private Ind CreateIndividual() { Ind newIndividual = new Ind(digits, r); return(newIndividual); }