private void when_asked_to_create_child() { var random = new TestRandomSource(_randomToReturn); _strategy = new RandomStrategy(_length); _strategy.SetRandomSource(random); _result = _strategy.CreateChild(null, null, _geneSet); }
public string GetBest(int length, string geneSet, Func<string, int> getFitness, Action<int, int, string, string> displayChild) { _randomStrategy = new RandomStrategy(length); int maxIndividualsInPool = geneSet.Length * 3; int generationCount = 1; var uniqueIndividuals = new HashSet<string>(); var parents = GenerateParents(geneSet) .Where(x => uniqueIndividuals.Add(x.Genes)) .Take(maxIndividualsInPool) .ToList(); foreach (var individual in parents) { individual.Fitness = getFitness(individual.Genes); } parents = parents.OrderBy(x => x.Fitness).ToList(); var bestParent = parents.First(); displayChild(generationCount, bestParent.Fitness, bestParent.Genes, bestParent.Strategy.Description); var children = GenerateChildren(parents, new[] { _randomStrategy }, geneSet) .Where(x => uniqueIndividuals.Add(x.Genes)); int lastParentLine = NumberOfParentLines - 1; int currentParentLine = lastParentLine; var parentLines = Enumerable.Range(0, NumberOfParentLines) .Select(x => parents.ToList()) .ToArray(); var strategies = Enumerable.Range(0, NumberOfParentLines) .Select(x => _strategies.ToList()) .ToArray(); double halfMaxAllowableSecondsWithoutImprovement = MaxSecondsWithoutImprovement / 2; IEqualityComparer<Individual> individualGenesComparer = new IndividualGenesComparer(); var stopwatch = new Stopwatch(); stopwatch.Start(); do { var potentialParents = new List<Individual>(); foreach (var child in children .TakeWhile(x => potentialParents.Count < maxIndividualsInPool)) { child.Fitness = getFitness(child.Genes); potentialParents.Add(child); if (bestParent.Fitness > child.Fitness) { bestParent = child; var ancestors = GetAncestors(bestParent).ToList(); strategies[currentParentLine] = GetStrategyPool(ancestors); if (ancestors.Count > maxIndividualsInPool) { maxIndividualsInPool = ancestors.Count; } displayChild(generationCount, bestParent.Fitness, bestParent.Genes, bestParent.Strategy.Description); } } generationCount++; parentLines[currentParentLine] = parentLines[currentParentLine] .Concat(potentialParents) .OrderBy(x => x.Fitness) .Take(maxIndividualsInPool) .ToList(); if (parentLines[currentParentLine][0].Fitness == bestParent.Fitness || stopwatch.Elapsed.TotalSeconds < halfMaxAllowableSecondsWithoutImprovement) { if (--currentParentLine < 0) { currentParentLine = lastParentLine; } } else { parentLines[currentParentLine] = parentLines .SelectMany(x => x.Take(5)) .Distinct(individualGenesComparer) .ToList(); } children = GenerateChildren(parentLines[currentParentLine], strategies[currentParentLine], geneSet) .Where(x => uniqueIndividuals.Add(GetCanonicalGenes(x.Genes))); } while (bestParent.Fitness > 0 && stopwatch.Elapsed.TotalSeconds <= MaxSecondsWithoutImprovement); return bestParent.Genes; }