private static IEnumerable <Chromosome <TGene, TFitness> > GetImprovment(MutateChromosomeDelegate newChild, GenerateParentDelegate generateParent) { var bestParent = generateParent(); yield return(bestParent); while (true) { var child = newChild(bestParent); if (bestParent.Fitness.CompareTo(child.Fitness) > 0) { continue; } if (child.Fitness.CompareTo(bestParent.Fitness) <= 0) { bestParent = child; continue; } yield return(child); bestParent = child; } // ReSharper disable once IteratorNeverReturns }
private static Chromosome <TGene, TFitness> Crossover(IReadOnlyList <TGene> parentGenes, int index, IList <Chromosome <TGene, TFitness> > parents, GetFitnessDelegate getFitness, CrossoverDelegate crossover, MutateChromosomeDelegate mutate, GenerateParentDelegate generateParent) { var donorIndex = Rand.Random.Next(0, parents.Count); if (donorIndex == index) { donorIndex = (donorIndex + 1) % parents.Count; } var childGenes = crossover(parentGenes, parents[donorIndex].Genes); if (childGenes == null) { // parent and donor are indistinguishable parents[donorIndex] = generateParent(); return(mutate(parents[index])); } var fitness = getFitness(childGenes); return(new Chromosome <TGene, TFitness>(childGenes, fitness, Strategy.Crossover)); }
private static IEnumerable <Chromosome <TGene, TFitness> > GetImprovement(MutateChromosomeDelegate newChild, GenerateParentDelegate generateParent, int?maxAge = null) { var bestParent = generateParent(); var parent = bestParent; yield return(bestParent); var historicalFitnesses = new List <TFitness> { bestParent.Fitness }; while (true) { var child = newChild(parent); if (parent.Fitness.CompareTo(child.Fitness) > 0) { if (maxAge == null) { continue; } parent.Age++; if (parent.Age < maxAge) { continue; } var index = historicalFitnesses.BinarySearch(child.Fitness); if (index < 0) { index = ~index; } var difference = historicalFitnesses.Count - index; var proportionSimilar = (double)difference / historicalFitnesses.Count; var exp = Math.Exp(-proportionSimilar); if (Rand.Random.NextDouble() < exp) { parent = child; continue; } bestParent.Age = 0; parent = bestParent; continue; } if (parent.Fitness.CompareTo(child.Fitness) == 0) { child.Age = parent.Age + 1; parent = child; continue; } child.Age = 0; parent = child; if (bestParent.Fitness.CompareTo(child.Fitness) >= 0) { continue; } bestParent = child; historicalFitnesses.Add(bestParent.Fitness); yield return(bestParent); } // ReSharper disable once IteratorNeverReturns }