public void Should_cut_and_Produce_Child_properly() { for (int x = 0; x < 100; x++) { var parentA = new CrossoverTestModel(new[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }); var parentB = new CrossoverTestModel(new[] { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }); var options = new EvolutionOptions() { CollectionSize = parentA.Bits.Count }; // 10 items var child = new SinglePointCrossover <CrossoverTestModel>(options).Produce(parentA, parentB); _output.WriteLine(child.ToString()); // asserts var cutPoint = child.Bits.Select((b, i) => (bit: b, index: i)).First(e => e.bit == 1).index; var bitsBeforeCutPoint = child.Bits.Where((b, i) => i < cutPoint).ToList(); var bitsAfterCutPoint = child.Bits.Where((b, i) => i >= cutPoint).ToList(); child.Bits.Should().HaveSameCount(parentA.Bits); child.Bits.Should().HaveCount(bitsBeforeCutPoint.Count + bitsAfterCutPoint.Count); bitsBeforeCutPoint.Should().AllBeEquivalentTo(0); bitsAfterCutPoint.Should().AllBeEquivalentTo(1); } }
public void Test1() { _output.WriteLine("Truncate selection"); var options1 = new EvolutionOptions { CollectionSize = 8 }; Evolve <ActivateBitModel>(options: options1, generationsCount: 10); _output.WriteLine("\n-----------------------\n"); _output.WriteLine("Proportional selection"); var options2 = new EvolutionOptions { NaturalSelection = SelectionTypes.Proportional, CollectionSize = 8 }; Evolve <ActivateBitModel>(options: options2, generationsCount: 10); _output.WriteLine("\n-----------------------\n"); _output.WriteLine("Truncate + Single-Point Crossover"); var options3 = new EvolutionOptions { CollectionSize = 8, Crossover = CrossoverTypes.SinglePoint }; Evolve <ActivateBitModel>(options: options3, generationsCount: 10); _output.WriteLine("\n-----------------------\n"); _output.WriteLine("Truncate + Slice Crossover"); var options4 = new EvolutionOptions { CollectionSize = 8, Crossover = CrossoverTypes.Slice }; Evolve <ActivateBitModel>(options: options4, generationsCount: 10); }
protected PointedCrossover(EvolutionOptions options, int cutPoints = 1) : base(options) { CutPoints = cutPoints; GenesCount = CalculateGenesCount(options.CollectionSize); if (GenesCount <= cutPoints) { throw new InvalidOperationException($"It is not possible to split the current model data using {cutPoints} cut points."); } }
public static Population <T> Mutate <T>(Population <T> population, EvolutionOptions options) where T : class, IEvolutionaryIndividual, new() { var mutator = options.GetMutation <T>(); foreach (var individual in population) { mutator.Mutate(individual); } return(population); }
internal static MutationBase <T> GetMutation <T>(this EvolutionOptions options) where T : class, new() { switch (options.Mutation) { case MutationTypes.Addition: return(new AdditionMutation <T>(options)); case MutationTypes.Uniform: default: return(new UniformMutation <T>(options)); } }
internal static INaturalSelection <T> GetSelection <T>(this EvolutionOptions options) where T : class, IEvolutionaryIndividual, new() { switch (options.NaturalSelection) { case SelectionTypes.Proportional: return(new ProportionalSelection <T>(options.NaturalSelectionRate)); case SelectionTypes.Truncate: default: return(new TruncateSelection <T>(options.NaturalSelectionRate)); } }
public Evolution(int maxGenerations = 100) { _maxGenerations = maxGenerations; var options = new EvolutionOptions { PopulationSize = 100, MaxNumberValue = 100, CollectionSize = 4, Crossover = CrossoverTypes.Slice, Mutation = MutationTypes.Addition, }; _geneticEvolution = new GeneticEvolution <SnakeGA>(options); }
internal static CrossoverBase <T> GetCrossover <T>(this EvolutionOptions options) where T : class, new() { switch (options.Crossover) { case CrossoverTypes.SinglePoint: return(new SinglePointCrossover <T>(options)); case CrossoverTypes.Slice: return(new SliceCrossover <T>(options)); case CrossoverTypes.Uniform: default: return(new UniformCrossover <T>(options)); } }
protected void Evolve <T>(int generationsCount = 50, EvolutionOptions options = null, Func <EvolutionResult <T>, bool> stopCondition = null) where T : class, IEvolutionaryIndividual, new() { var geneticEvolution = new GeneticEvolution <T>(options ?? EvolutionOptions.Default); geneticEvolution.EvolveUntil(stopCondition ?? (r => r.Generation.Number == generationsCount), result => { _output.WriteLine($"Gen. : #{geneticEvolution.CurrentGeneration.Number}"); _output.WriteLine($"Best : {result.BestIndividual}"); _output.WriteLine($"Avg : {result.AverageIndividual}"); _output.WriteLine($"Worst: {result.WorstIndividual}"); _output.WriteLine($"------------------------------"); _output.WriteLine($"Avg.Fitness: {result.AverageFitness}"); _output.WriteLine(""); return(result.Generation.Number < 500); // safe stop }); }
public void Test1() { var options = new EvolutionOptions { PopulationSize = 300, NaturalSelectionRate = 0.5, MutationRate = 0.01, Mutation = MutationTypes.Addition, CollectionSize = FindSecretSentenceModel.SECRET.Length, MinNumberValue = 32, // ascii table start MaxNumberValue = 126 // ascii table end }; Evolve <FindSecretSentenceModel>(options: options, stopCondition: r => { return(r.BestIndividual.Fitness == 100); // stop when achieve 100% fitness }); }
public static Population <T> Breed <T>(Population <T> population, EvolutionOptions options) where T : class, IEvolutionaryIndividual, new() { var newIndividuals = new List <T>(); var crossover = options.GetCrossover <T>(); var orderedPopulation = population.OrderByDescending(i => i.Fitness).ToList(); while (newIndividuals.Count != options.PopulationSize) { foreach (var individual in orderedPopulation) { var partner = population.ElementAt(RandomData.GetInt(population.Count())); var newIndividual = crossover.Produce(individual, partner); newIndividuals.Add(newIndividual); if (newIndividuals.Count == options.PopulationSize) { break; } } } return(new Population <T>(newIndividuals)); }
protected CrossoverBase(EvolutionOptions options) { Builder = options.GenerateBuilder <T>(); }
public DungeonGeneratorEvolution( IMapDescription <TNode> mapDescription, List <IPerformanceAnalyzer <DungeonGeneratorConfiguration <TNode>, Individual <TNode> > > analyzers, EvolutionOptions options, string resultsDirectory) : base(analyzers, options, resultsDirectory) { this.mapDescription = mapDescription; }
public SinglePointCrossover(EvolutionOptions options) : base(options, cutPoints: 1) { }
protected MutationBase(EvolutionOptions options) { _options = options; Builder = options.GenerateBuilder <T>(); }
public UniformMutation(EvolutionOptions options) : base(options) { }
internal static Builder <T> GenerateBuilder <T>(this EvolutionOptions options) where T : class, new() { return(new Builder <T>().WithCollectionDegree(options.CollectionSize) .WithMinNumberValueOf(options.MinNumberValue) .WithMaxNumberValueOf(options.MaxNumberValue)); }
public SimpleDungeonGeneratorEvolution(IMapDescription <TNode> mapDescription, List <IPerformanceAnalyzer <DungeonGeneratorConfiguration <TNode>, Individual <TNode> > > analyzers, EvolutionOptions options, string resultsDirectory) : base(mapDescription, analyzers, options, resultsDirectory) { OnEvolutionStarted += () => generationNumber = 0; }
internal static bool IsInRange(this EvolutionOptions options, decimal value) { return(value >= options.MinNumberValue && value <= options.MaxNumberValue); }
public UniformCrossover(EvolutionOptions options) : base(options) { }
public SliceCrossover(EvolutionOptions options) : base(options, cutPoints: 2) { }
public AdditionMutation(EvolutionOptions options) : base(options) { _options = options; }