/// <summary> /// Evolved one generation. /// </summary> /// <param name="population">Curr. pop</param> /// <returns>New generation</returns> protected override IPopulation EvolvedOneGeneration(IPopulation population) { List <IIndividual> newGeneration = new List <IIndividual>(); foreach (var orginal in population.Individuals) { // generate unique random numbers var randomValues = FastRandom.GetUniqueInts(3, 0, population.Size); int a = randomValues[0]; int b = randomValues[1]; int c = randomValues[2]; // choose random individuals (agents) from population IIndividual individual1 = population.Individuals[a]; IIndividual individual2 = population.Individuals[b]; IIndividual individual3 = population.Individuals[c]; int i = 0; int R = FastRandom.GetInt(0, population.Size); var candidate = population.CreateEmptyIndividual(); foreach (var orginalElement in orginal.GetGenes()) { double probXover = FastRandom.GetDouble(); if (probXover < XoverProbability || i == R) { // simple mutation double newElement = individual1.GetGene(i) + F * (individual2.GetGene(i) - individual3.GetGene(i)); candidate.ReplaceGene(i, newElement); } else { candidate.ReplaceGene(i, orginalElement); } i++; } var fit = fitness.Evaluate(candidate); if (fit < orginal.Fitness) { newGeneration.Add(candidate); } else { newGeneration.Add(orginal); } } CurrentGenerationsNumber++; population.Individuals = newGeneration; return(population); }
/// <summary> /// Cross the specified parents generating the children. /// </summary> /// <param name="parents">The parents.</param> /// <returns>The offspring (children) of the parents.</returns> public override IList <IIndividual> Cross(IList <IIndividual> parents) { // This xover need same length if (parents[0].Length != parents[1].Length) { return(parents); } // minimal parents lenght if (parents[0].Length <= minParentSize) { return(parents); } // cross points var crossPoints = FastRandom.GetUniqueInts(2, 1, parents[0].Length - 2); // new individuals int firstIndex = crossPoints[0]; int secondIndex = crossPoints[1]; if (secondIndex < firstIndex) { secondIndex = crossPoints[0]; firstIndex = crossPoints[1]; } var firstChild = CreateChild(parents[0], parents[1], firstIndex, secondIndex); var secondChild = CreateChild(parents[1], parents[0], firstIndex, secondIndex); return(new List <IIndividual>() { firstChild, secondChild }); }
/// <summary> /// Mutate the specified individual in population. /// </summary> /// <param name="individual">The individual to be mutated.</param> /// <param name="mut_probability">The mutation probability to mutate each individual.</param> public override void Mutate(IIndividual individual, float mutation_probabilty) { if (FastRandom.GetDouble() <= mutation_probabilty) { var indexes = FastRandom.GetUniqueInts(2, 0, individual.Length); SwapGenes(indexes[0], indexes[1], individual); } }
/// <summary> /// Selects the number of individuals from the generation. /// </summary> /// <param name="number">Number of selected.</param> /// <param name="generation">Cur. generation</param> /// <returns>Selected individuals.</returns> public IList <IIndividual> SelectIndividuals(int number, IPopulation generation) { // previous generation var candidates = generation.Individuals.ToList(); // new indiviudals var selected = new List <IIndividual>(); // determine the winner by fitness while (selected.Count < number) { var randomIndexes = FastRandom.GetUniqueInts(2, 0, candidates.Count); var tournamentWinner = candidates.Where((c, i) => randomIndexes.Contains(i)).OrderBy(c => c.Fitness).First(); selected.Add(tournamentWinner.Clone() as IIndividual); } return(selected); }