/// <summary> /// Initializes a new instance of the <see cref="GeneticSharp.Domain.GeneticAlgorithm"/> class. /// </summary> /// <param name="population">The chromosomes population.</param> /// <param name="fitness">The fitness evaluation function.</param> /// <param name="selection">The selection operator.</param> /// <param name="crossover">The crossover operator.</param> /// <param name="mutation">The mutation operator.</param> public GeneticAlgorithm( IPopulation population, IFitness fitness, ISelection selection, ICrossover crossover, IMutation mutation) { ExceptionHelper.ThrowIfNull("population", population); ExceptionHelper.ThrowIfNull("fitness", fitness); ExceptionHelper.ThrowIfNull("selection", selection); ExceptionHelper.ThrowIfNull("crossover", crossover); ExceptionHelper.ThrowIfNull("mutation", mutation); Population = population; Fitness = fitness; Selection = selection; Crossover = crossover; Mutation = mutation; Reinsertion = new ElitistReinsertion(); Termination = new GenerationNumberTermination(1); CrossoverProbability = DefaultCrossoverProbability; MutationProbability = DefaultMutationProbability; TimeEvolving = TimeSpan.Zero; State = GeneticAlgorithmState.NotStarted; TaskExecutor = new LinearTaskExecutor(); }
public IReinsertion Elitist() { var target = new ElitistReinsertion(); target.SelectChromosomes(new Population(10, 10, new TspChromosome(_numberOfCities)), new List <IChromosome>(), _parents); return(target); }
public void SelectChromosomes_offspringSizeLowerThanMinSize_Selectoffspring() { var target = new ElitistReinsertion(); var population = new Population(6, 8, MockRepository.GenerateStub <ChromosomeBase> (2)); var offspring = new List <IChromosome> () { MockRepository.GenerateStub <ChromosomeBase> (2), MockRepository.GenerateStub <ChromosomeBase> (2), MockRepository.GenerateStub <ChromosomeBase> (3), MockRepository.GenerateStub <ChromosomeBase> (4) }; var parents = new List <IChromosome> () { MockRepository.GenerateStub <ChromosomeBase> (5), MockRepository.GenerateStub <ChromosomeBase> (6), MockRepository.GenerateStub <ChromosomeBase> (7), MockRepository.GenerateStub <ChromosomeBase> (8) }; parents [0].Fitness = 0.2; parents [1].Fitness = 0.3; parents [2].Fitness = 0.5; parents [3].Fitness = 0.7; var selected = target.SelectChromosomes(population, offspring, parents); Assert.AreEqual(6, selected.Count); Assert.AreEqual(2, selected [0].Length); Assert.AreEqual(2, selected [1].Length); Assert.AreEqual(3, selected [2].Length); Assert.AreEqual(4, selected [3].Length); Assert.AreEqual(8, selected [4].Length); Assert.AreEqual(7, selected [5].Length); }
private static IAlgoritmo CriaAlgoritmoGenetico(Dictionary <string, string[]> dict, List <string> flat, Problema problema) { int populacaoMin, populacaoMax; IPopulation population; ISelection selection; ICrossover crossover; IMutation mutation; ITermination termination; IReinsertion reinsertion; float crossoverProbability, mutationProbability; var p = dict.ValueOrDefault("p", "50,100").Split(new[] { ',' }); if (p.Length != 2 || !int.TryParse(p[0], out populacaoMin) || !int.TryParse(p[1], out populacaoMax)) { throw new ArgumentException("Faixa de população inválida."); } population = new Population(populacaoMin, populacaoMax, new CromossomoViajante(problema.Mapa.Locais.Count)); switch (dict.ValueOrDefault("s", "t")) { case "e": selection = new EliteSelection(); break; case "r": selection = new RouletteWheelSelection(); break; case "s": selection = new StochasticUniversalSamplingSelection(); break; case "t": selection = new TournamentSelection(); break; default: throw new ArgumentException("Seleção inválida."); } switch (dict.ValueOrDefault("c", "o")) { case "s": crossover = new CutAndSpliceCrossover(); break; case "c": crossover = new CycleCrossover(); break; case "o": crossover = new OrderedCrossover(); break; case "ob": crossover = new OrderBasedCrossover(); break; case "op": crossover = new OnePointCrossover(); break; case "pm": crossover = new PartiallyMappedCrossover(); break; case "p": crossover = new PositionBasedCrossover(); break; case "tpa": crossover = new ThreeParentCrossover(); break; case "tp": crossover = new TwoPointCrossover(); break; case "u": crossover = new UniformCrossover(); break; default: throw new ArgumentException("Crossover inválido."); } switch (dict.ValueOrDefault("m", "r")) { case "d": mutation = new DisplacementMutation(); break; case "f": mutation = new FlipBitMutation(); break; case "i": mutation = new InsertionMutation(); break; case "s": mutation = new PartialShuffleMutation(); break; case "r": mutation = new ReverseSequenceMutation(); break; case "t": mutation = new TworsMutation(); break; case "u": mutation = new UniformMutation(); break; default: throw new ArgumentException("Mutação inválida."); } switch (dict.ValueOrDefault("t", "s")) { case "s": termination = new FitnessStagnationTermination(); break; case "t": termination = new FitnessThresholdTermination(); break; case "g": termination = new GenerationNumberTermination(); break; default: throw new ArgumentException("Terminação inválida."); } switch (dict.ValueOrDefault("e", "e")) { case "e": reinsertion = new ElitistReinsertion(); break; case "p": reinsertion = new PureReinsertion(); break; case "u": reinsertion = new UniformReinsertion(); break; default: throw new ArgumentException("Reinserção inválida."); } if (!float.TryParse(dict.ValueOrDefault("cp", "0,75"), out crossoverProbability)) { throw new ArgumentException("Probabilidade de crossover inválida."); } if (!float.TryParse(dict.ValueOrDefault("mp", "0,25"), out mutationProbability)) { throw new ArgumentException("Probabilidade de mutação inválida."); } return(new AlgoritmoGenetico(problema, population, selection, crossover, crossoverProbability, mutation, mutationProbability, termination, reinsertion)); }
public static DynamoGeneticAlgorithm CreateGeneticAlgorithm(Population population, [DefaultArgument("Evo.DynamoGeneticAlgorithm.Default()")] object selection, [DefaultArgument("Evo.DynamoGeneticAlgorithm.Default()")] object crossover, [DefaultArgument("Evo.DynamoGeneticAlgorithm.Default()")] object mutation, [DefaultArgument("Evo.DynamoGeneticAlgorithm.Default()")] object termination, [DefaultArgument("Evo.DynamoGeneticAlgorithm.Default()")] int?selectionSize, double crossoverProbability = DynamoGeneticAlgorithm.DefaultCrossoverProbability, double mutationProbability = DynamoGeneticAlgorithm.DefaultMutationProbability) { IChromosome exemplaryChromome = population.CurrentGeneration.Chromosomes[0]; ChromosomeType chromosomeType = 0; if (exemplaryChromome is BinaryChromosome) { chromosomeType = ((BinaryChromosome)exemplaryChromome).ChromosomeType; } else if (exemplaryChromome is CombinatorialChromosome) { chromosomeType = ((CombinatorialChromosome)exemplaryChromome).ChromosomeType; } else if (exemplaryChromome is DoubleChromosome) { chromosomeType = ((DoubleChromosome)exemplaryChromome).ChromosomeType; } ISelection selectionMethod = null; if (selection == null) { selectionMethod = new EliteSelection(); } else { if (selection is EliteSelection) { selectionMethod = selection as EliteSelection; } else if (selection is RouletteWheelSelection) { selectionMethod = selection as RouletteWheelSelection; } else if (selection is StochasticUniversalSamplingSelection) { selectionMethod = selection as StochasticUniversalSamplingSelection; } else if (selection is TournamentSelection) { selectionMethod = selection as TournamentSelection; } else { throw new CrossoverException("Invalid selection input. A valid object returned by a node of the Selections category should be used."); } } ICrossover crossoverMethod = null; if (crossover == null) { crossoverMethod = new UniformCrossover(0.5f); } else { if (crossover is AlternatingPositionCrossover) { if (chromosomeType != ChromosomeType.CombinatorialChromosome) { throw new CrossoverException("The Alternating-position Crossover (AP) can be only used with combinatorial chromosomes. The specified individuals are not combinatorial chromosomes."); } crossoverMethod = crossover as AlternatingPositionCrossover; } else if (crossover is CutAndSpliceCrossover) { if (chromosomeType == ChromosomeType.DoubleChromosome) { throw new CrossoverException("The Cut and Splice Crossover (AP) can be only used with binary and combinatorial chromosomes. The specified individuals are double chromosomes."); } crossoverMethod = crossover as CutAndSpliceCrossover; } else if (crossover is CycleCrossover) { if (chromosomeType != ChromosomeType.CombinatorialChromosome) { throw new CrossoverException("The Cycle Crossover (CX) can be only used with combinatorial chromosomes. The specified individuals are not combinatorial chromosomes."); } crossoverMethod = crossover as CycleCrossover; } else if (crossover is OnePointCrossover) { if (chromosomeType == ChromosomeType.DoubleChromosome) { throw new CrossoverException("The One-point Crossover can be only used with binary and combinatorial chromosomes. The specified individuals are double chromosomes."); } crossoverMethod = crossover as OnePointCrossover; } else if (crossover is OrderBasedCrossover) { if (chromosomeType != ChromosomeType.CombinatorialChromosome) { throw new CrossoverException("The Order Based Crossover (OX2) can be only used with combinatorial chromosomes. The specified individuals are not combinatorial chromosomes."); } crossoverMethod = crossover as OrderBasedCrossover; } else if (crossover is OrderedCrossover) { if (chromosomeType != ChromosomeType.CombinatorialChromosome) { throw new CrossoverException("The Ordered Crossover (OX1) can be only used with combinatorial chromosomes. The specified individuals are not combinatorial chromosomes."); } crossoverMethod = crossover as OrderedCrossover; } else if (crossover is PartiallyMappedCrossover) { if (chromosomeType != ChromosomeType.CombinatorialChromosome) { throw new CrossoverException("The Partially-mapped Crossover (PMX) can be only used with combinatorial chromosomes. The specified individuals are not combinatorial chromosomes."); } crossoverMethod = crossover as PartiallyMappedCrossover; } else if (crossover is PositionBasedCrossover) { if (chromosomeType != ChromosomeType.CombinatorialChromosome) { throw new CrossoverException("The Position Based Crossover (POS) can be only used with combinatorial chromosomes. The specified individuals are not combinatorial chromosomes."); } crossoverMethod = crossover as PositionBasedCrossover; } else if (crossover is SimulatedBinaryCrossover) { if (chromosomeType != ChromosomeType.DoubleChromosome) { throw new CrossoverException("The Simulated Binary Crossover (SBX) can be only used with double chromosomes. The specified individuals are not double chromosomes."); } crossoverMethod = crossover as SimulatedBinaryCrossover; } else if (crossover is ThreeParentCrossover) { if (chromosomeType == ChromosomeType.DoubleChromosome) { throw new CrossoverException("The Three-parent Crossover can be only used with binary and combinatorial chromosomes. The specified individuals are double chromosomes."); } crossoverMethod = crossover as ThreeParentCrossover; } else if (crossover is TwoPointCrossover) { if (chromosomeType == ChromosomeType.DoubleChromosome) { throw new CrossoverException("The Two-point Crossover can be only used with binary and combinatorial chromosomes. The specified individuals are double chromosomes."); } crossoverMethod = crossover as TwoPointCrossover; } else if (crossover is UniformCrossover) { if (chromosomeType == ChromosomeType.DoubleChromosome) { throw new CrossoverException("The Uniform Crossover can be only used with binary and combinatorial chromosomes. The specified individuals are double chromosomes."); } crossoverMethod = crossover as UniformCrossover; } else if (crossover is VotingRecombinationCrossover) { if (chromosomeType == ChromosomeType.DoubleChromosome) { throw new CrossoverException("The Voting Recombination Crossover (VR) can be only used with binary and combinatorial chromosomes. The specified individuals are double chromosomes."); } crossoverMethod = crossover as VotingRecombinationCrossover; } else { throw new CrossoverException("Invalid crossover input. A valid object returned by a node of the Crossovers category should be used."); } } IMutation mutationMethod = null; if (mutation == null) { mutationMethod = new FlipBitMutation(); } else { if (mutation is DisplacementMutation) { if (chromosomeType == ChromosomeType.DoubleChromosome) { throw new CrossoverException("The Displacement Mutation can be only used on binary and combinatorial chromosomes. The specified individuals are double chromosomes."); } mutationMethod = mutation as DisplacementMutation; } else if (mutation is FlipBitMutation) { if (chromosomeType != ChromosomeType.BinaryChromosome) { throw new CrossoverException("The Flip Bit Mutation can be only used on binary chromosomes. The specified individuals are not binary chromosomes."); } mutationMethod = mutation as FlipBitMutation; } else if (mutation is GaussianMutation) { if (chromosomeType != ChromosomeType.DoubleChromosome) { throw new CrossoverException("The Gaussian Mutation can be only used on double chromosomes. The specified individuals are not double chromosomes."); } mutationMethod = mutation as GaussianMutation; } else if (mutation is InsertionMutation) { if (chromosomeType == ChromosomeType.DoubleChromosome) { throw new CrossoverException("The Displacement Mutation can be only used on binary and combinatorial chromosomes. The specified individuals are double chromosomes."); } mutationMethod = mutation as InsertionMutation; } else if (mutation is PartialShuffleMutation) { if (chromosomeType == ChromosomeType.DoubleChromosome) { throw new CrossoverException("The Displacement Mutation (PSM) can be only used on binary and combinatorial chromosomes. The specified individuals are double chromosomes."); } mutationMethod = mutation as PartialShuffleMutation; } else if (mutation is PolynomialMutation) { if (chromosomeType != ChromosomeType.DoubleChromosome) { throw new CrossoverException("The Polynomial Mutation can be only used on double chromosomes. The specified individuals are not double chromosomes."); } mutationMethod = mutation as PolynomialMutation; } else if (mutation is ReverseSequenceMutation) { if (chromosomeType == ChromosomeType.DoubleChromosome) { throw new CrossoverException("The Displacement Mutation (RSM) can be only used on binary and combinatorial chromosomes. The specified individuals are double chromosomes."); } mutationMethod = mutation as ReverseSequenceMutation; } else if (mutation is TworsMutation) { if (chromosomeType == ChromosomeType.DoubleChromosome) { throw new CrossoverException("The Displacement Mutation can be only used on binary and combinatorial chromosomes. The specified individuals are double chromosomes."); } mutationMethod = mutation as TworsMutation; } else if (mutation is UniformMutation) { if (chromosomeType != ChromosomeType.BinaryChromosome) { throw new CrossoverException("The Uniform Mutation can be only used on binary chromosomes. The specified individuals are not binary chromosomes."); } mutationMethod = mutation as UniformMutation; } else { throw new CrossoverException("Invalid mutation input. A valid object returned by a node of Mutations category should be used."); } } ElitistReinsertion reinsertionMethod = new ElitistReinsertion(); ITermination terminationMethod = null; if (termination == null) { terminationMethod = new FitnessStagnationTermination(100); } else { if (termination is FitnessStagnationTermination) { terminationMethod = termination as FitnessStagnationTermination; } else if (termination is FitnessThresholdTermination) { terminationMethod = termination as FitnessThresholdTermination; } else if (termination is GenerationNumberTermination) { terminationMethod = termination as GenerationNumberTermination; } else if (termination is TimeEvolvingTermination) { terminationMethod = termination as TimeEvolvingTermination; } else if (termination is AndTermination) { terminationMethod = termination as AndTermination; } else if (termination is OrTermination) { terminationMethod = termination as OrTermination; } else { throw new CrossoverException("Invalid termination input. An object returned by nodes of Terminations library should be used."); } } if (selectionSize == null) { selectionSize = (int)Math.Round(0.5 * population.MaxSize); } else if (!(selectionSize is int)) { throw new CrossoverException("Defined selection size is not an integer."); } else if (selectionSize > population.MaxSize) { throw new CrossoverException("Selection size cannot be greater than population size."); } var algorithm = new DynamoGeneticAlgorithm(population, selectionMethod, crossoverMethod, mutationMethod, reinsertionMethod, terminationMethod) { SelectionSize = (int)selectionSize, CrossoverProbability = (float)crossoverProbability, MutationProbability = (float)mutationProbability, Timer = Stopwatch.StartNew() }; algorithm.Timer.Start(); return(algorithm); }
public void Solve(Maze maze) { const int NumberOfGenes = 5000; const float MutationRate = 0.02f; const float CrossOverRate = 0.6f; var selection = new EliteSelection(); var crossover = new UniformCrossover(); var mutation = new UniformMutation(true); var chromosome = new MazeSolverChromosome(NumberOfGenes); var reinsertion = new ElitistReinsertion(); var population = new Population(50, 100, chromosome); var fitness = new MazeWalkerFitness(maze); IChromosome best = chromosome; best.Fitness = fitness.Evaluate(best); var ga = new GeneticAlgorithm(population, fitness, selection, crossover, mutation); ga.MutationProbability = MutationRate; ga.Reinsertion = reinsertion; ga.Termination = new OrTermination( new FitnessStagnationTermination(this.stagnationThreshold), new TimeEvolvingTermination(TimeSpan.FromSeconds(this.maxRunTimeInSeconds))); ga.CrossoverProbability = CrossOverRate; ga.TaskExecutor = new SmartThreadPoolTaskExecutor() { MinThreads = Environment.ProcessorCount, MaxThreads = Environment.ProcessorCount }; ga.GenerationRan += (sender, eventargs) => { if (this.generateUpdateImages) { if (ga.GenerationsNumber == 1 || ga.GenerationsNumber % this.updateImageFrequency == 0) { var winnerSteps = FillMazeStepsWalked(maze, ga.BestChromosome); ImageDraw(winnerSteps, $"gen{ga.GenerationsNumber}.png"); } } if (ga.GenerationsNumber % 10 == 0) { Console.WriteLine( $"{ga.GenerationsNumber} generations completed. Best fitness: {ga.BestChromosome.Fitness}. Best so far: {best.Fitness}. Time evolving: {ga.TimeEvolving.TotalMinutes} min."); } if (ga.BestChromosome.Fitness > best.Fitness) { best = ga.BestChromosome.Clone(); // ga.Population.CurrentGeneration.Chromosomes.Add(best); } }; ga.TerminationReached += (sender, eventargs) => { Console.WriteLine($"Termination Reached"); var winnerSteps = FillMazeStepsWalked(maze, best); ImageDraw(winnerSteps, "best.png"); var serializer = new XmlSerializer(typeof(string[])); using (var sw = new StreamWriter("bestchromosome.xml")) { serializer.Serialize(sw, best.GetGenes().Select(g => g.Value as string).ToArray()); } if (this.animate) { File.Delete("output.gif"); this.gif.Save("output.gif"); } }; if (this.generateUpdateImages) { this.ImageDraw(maze, "gen0.png"); } ga.Start(); }