/// <summary> /// Creates an initial population /// </summary> private void InitializePopulation() { ICollection <IGenotype> population; if (AllowDuplicates) { population = new List <IGenotype>(PopulationSize); } else { population = new SafeHashSet <IGenotype>(MaxRetriesForDuplicates); } while (population.Count < PopulationSize) { population.Add(GenerateRandomMember()); } Population = population.OrderByDescending(x => x.Fitness).ToList(); BestInitial = Population.First(); CreateMethod = GenotypeFactory.GetCreateMethod <Gene>(BestInitial.GetType()); }
/// <summary> /// Runs the genetic algorithm for the specified number of generations /// </summary> /// <param name="numGenerations">The number of generations</param> /// <returns></returns> public void Run() { ICollection <IGenotype> nextPopulation; List <IGenotype> parents; Gene[][] children; IGenotype child; double fitness; bool mutated, solutionFound; ParameterCheck(); if (Population == null) { InitializePopulation(); } if (AllowDuplicates) { nextPopulation = new List <IGenotype>(PopulationSize); } else { nextPopulation = new SafeHashSet <IGenotype>(MaxRetriesForDuplicates); } solutionFound = false; if (PreserveElitePercent > 0) { foreach (IGenotype individual in Population.Take((int)(PreserveElitePercent * PopulationSize)).ToList()) { nextPopulation.Add(individual); } } SelectionMethod.Initialize(Population); while (nextPopulation.Count < PopulationSize) { try { parents = SelectionMethod.DoSelection(); } catch (SafeHashSetException) { Converged = true; break; } // Perform crossover children = CrossoverMethod.DoCrossover <Gene>(parents); // Iterate through each child produced by crossover for (int i = 0; i < children.Length; i++) { // Calculate fitness of child fitness = FitnessFunction(children[i], out solutionFound); // Perform mutation (but skip if solution has been found) mutated = solutionFound ? false : MutationMethod.DoMutation <Gene>(ref children[i]); // TODO return mutation and use only if better fitness??? Make a parameter to turn on/off // Recalculate fitness if mutation occurred if (mutated) { fitness = FitnessFunction(children[i], out solutionFound); } // Instantiate child child = CreateMethod(children[i], fitness); try { nextPopulation.Add(child); if (solutionFound) { break; } } catch (SafeHashSetException) { Converged = true; break; } } if (solutionFound || Converged) { break; } } GenerationNumber++; SolutionFound = solutionFound; Population = nextPopulation.OrderByDescending(x => x.Fitness).ToList(); BestCurrent = Population.First(); FinishedGeneration?.Invoke(); foreach (Termination.TerminationMethod t in TerminationMethods) { if (t.CheckTermination(this)) { Terminated = true; TerminationReached?.Invoke(); } } }