public void PositionBasedCrossoverApplyTest() { TestRandom random = new TestRandom(); Permutation parent1, parent2, expected, actual; // The following test is based on an example from Larranaga, 1999. Genetic Algorithms for the Traveling Salesman Problem. random.Reset(); random.IntNumbers = new int[] { 3, 1, 2, 5 }; parent1 = new Permutation(PermutationTypes.RelativeUndirected, new int[] { 0, 1, 2, 3, 4, 5, 6, 7 }); Assert.IsTrue(parent1.Validate()); parent2 = new Permutation(PermutationTypes.RelativeUndirected, new int[] { 1, 3, 5, 7, 6, 4, 2, 0 }); Assert.IsTrue(parent2.Validate()); expected = new Permutation(PermutationTypes.RelativeUndirected, new int[] { 0, 3, 5, 1, 2, 4, 6, 7 }); Assert.IsTrue(expected.Validate()); actual = PositionBasedCrossover.Apply(random, parent1, parent2); Assert.IsTrue(actual.Validate()); Assert.IsTrue(Auxiliary.PermutationIsEqualByPosition(expected, actual)); // perform a test when two permutations are of unequal length random.Reset(); bool exceptionFired = false; try { PositionBasedCrossover.Apply(random, new Permutation(PermutationTypes.RelativeUndirected, 8), new Permutation(PermutationTypes.RelativeUndirected, 6)); } catch (System.ArgumentException) { exceptionFired = true; } Assert.IsTrue(exceptionFired); }
public void Cross_ParentWithNoOrderedGenes_Exception() { var target = new PositionBasedCrossover(); var chromosome1 = MockRepository.GenerateStub <ChromosomeBase>(10); chromosome1.ReplaceGenes(0, new Gene[] { new Gene(8), new Gene(4), new Gene(7), new Gene(3), new Gene(6), new Gene(2), new Gene(5), new Gene(1), new Gene(9), new Gene(0) }); chromosome1.Expect(c => c.CreateNew()).Return(MockRepository.GenerateStub <ChromosomeBase>(10)); var chromosome2 = MockRepository.GenerateStub <ChromosomeBase>(10); chromosome2.ReplaceGenes(0, new Gene[] { new Gene(0), new Gene(1), new Gene(2), new Gene(3), new Gene(5), new Gene(5), new Gene(6), new Gene(7), new Gene(8), new Gene(9), }); chromosome2.Expect(c => c.CreateNew()).Return(MockRepository.GenerateStub <ChromosomeBase>(10)); ExceptionAssert.IsThrowing(new CrossoverException(target, "The Position-based Crossover (POS) can be only used with ordered chromosomes. The specified chromosome has repeated genes."), () => { target.Cross(new List <IChromosome>() { chromosome1, chromosome2 }); }); }
public void Cross_ParentWithNoOrderedGenes_Exception() { var target = new PositionBasedCrossover(); var chromosome1 = Substitute.For <ChromosomeBase>(10); chromosome1.ReplaceGenes(0, new Gene[] { new Gene(8), new Gene(4), new Gene(7), new Gene(3), new Gene(6), new Gene(2), new Gene(5), new Gene(1), new Gene(9), new Gene(0) }); chromosome1.CreateNew().Returns(Substitute.For <ChromosomeBase>(10)); var chromosome2 = Substitute.For <ChromosomeBase>(10); chromosome2.ReplaceGenes(0, new Gene[] { new Gene(0), new Gene(1), new Gene(2), new Gene(3), new Gene(5), new Gene(5), new Gene(6), new Gene(7), new Gene(8), new Gene(9), }); chromosome2.CreateNew().Returns(Substitute.For <ChromosomeBase>(10)); Assert.Catch <CrossoverException>(() => { target.Cross(new List <IChromosome>() { chromosome1, chromosome2 }); }, "The Position-based Crossover (POS) can be only used with ordered chromosomes. The specified chromosome has repeated genes."); }
private void EvolveGeneticStrategyButton_Click(object sender, RoutedEventArgs e) { OutputTextBlock.Text = "Evolving..."; Task.Run(() => { var chromosome = new BlackjackChromosome(); var fitness = new BlackjackFitness(); var population = new Population(Settings.GeneticSettings.MinPopulationSize, Settings.GeneticSettings.MaxPopulationSize, chromosome); ISelection selection; switch (Settings.GeneticSettings.SelectionType) { case SelectionType.Elite: selection = new EliteSelection(); break; case SelectionType.RouletteWheel: selection = new RouletteWheelSelection(); break; case SelectionType.StochasticUniversalSampling: selection = new StochasticUniversalSamplingSelection(); break; case SelectionType.Tournament: selection = new TournamentSelection(Settings.GeneticSettings.TournamentSize); break; default: throw new InvalidOperationException(); } ICrossover crossover; switch (Settings.GeneticSettings.CrossoverType) { case CrossoverType.AlternatingPosition: crossover = new AlternatingPositionCrossover(); break; case CrossoverType.CutAndSplice: crossover = new CutAndSpliceCrossover(); break; case CrossoverType.Cycle: crossover = new CycleCrossover(); break; case CrossoverType.OnePoint: crossover = new OnePointCrossover(); break; case CrossoverType.TwoPoint: crossover = new TwoPointCrossover(); break; case CrossoverType.OrderBased: crossover = new OrderBasedCrossover(); break; case CrossoverType.Ordered: crossover = new OrderedCrossover(); break; case CrossoverType.PartiallyMapped: crossover = new PartiallyMappedCrossover(); break; case CrossoverType.PositionBased: crossover = new PositionBasedCrossover(); break; case CrossoverType.ThreeParent: crossover = new ThreeParentCrossover(); break; case CrossoverType.Uniform: crossover = new UniformCrossover(Settings.Current.GeneticSettings.MixProbability); break; case CrossoverType.VotingRecombination: crossover = new VotingRecombinationCrossover(); break; default: throw new InvalidOperationException(); } var mutation = new UniformMutation(); var termination = new FitnessStagnationTermination(Settings.Current.GeneticSettings.NumStagnantGenerations); var taskExecutor = new ParallelTaskExecutor(); var ga = new GeneticAlgorithm( population, fitness, selection, crossover, mutation); ga.Termination = termination; ga.TaskExecutor = taskExecutor; ga.MutationProbability = Settings.GeneticSettings.MutationProbability; ga.CrossoverProbability = Settings.GeneticSettings.CrossoverProbability; var latestFitness = double.MinValue; ga.GenerationRan += (s, o) => { geneticStrategy = (IStrategy)ga.BestChromosome; var generationNumber = ga.GenerationsNumber; var bestFitness = ga.BestChromosome.Fitness.Value; var avgFitness = ga.Population.CurrentGeneration.Chromosomes.Average(c => c.Fitness.Value); Dispatcher.Invoke(() => { if (generationNumber == 1) { OutputTextBlock.Text = string.Empty; } OutputTextBlock.Text = $"Gen: {generationNumber}\tFit: {bestFitness}\tAvg: {avgFitness.ToString("0")}\n" + OutputTextBlock.Text; if (bestFitness != latestFitness) { latestFitness = bestFitness; var savedImageName = Settings.Current.GeneticSettings.SaveImagePerGeneration ? "gen" + generationNumber : null; StrategyViewer.Draw(GeneticStrategyCanvas, geneticStrategy, $"Best from generation {generationNumber}", savedImageName); } }, DispatcherPriority.Background); }; ga.TerminationReached += (s, o) => { Dispatcher.Invoke(() => { OutputTextBlock.Text = "Termination reached.\n" + OutputTextBlock.Text; TestGeneticStrategyButton.IsEnabled = true; }, DispatcherPriority.Background); }; ga.Start(); }); }
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 void Cross_ParentsWith8Genes_Cross() { var target = new PositionBasedCrossover(); // 1 2 3 4 5 6 7 8 var chromosome1 = MockRepository.GenerateStub <ChromosomeBase>(8); chromosome1.ReplaceGenes(0, new Gene[] { new Gene(1), new Gene(2), new Gene(3), new Gene(4), new Gene(5), new Gene(6), new Gene(7), new Gene(8) }); chromosome1.Expect(c => c.CreateNew()).Return(MockRepository.GenerateStub <ChromosomeBase>(8)); // 2 4 6 8 7 5 3 1 var chromosome2 = MockRepository.GenerateStub <ChromosomeBase>(8); chromosome2.ReplaceGenes(0, new Gene[] { new Gene(2), new Gene(4), new Gene(6), new Gene(8), new Gene(7), new Gene(5), new Gene(3), new Gene(1) }); chromosome2.Expect(c => c.CreateNew()).Return(MockRepository.GenerateStub <ChromosomeBase>(8)); // Child one: 1 4 6 2 3 5 7 8 // Child two: 4 2 3 8 7 6 5 1 var rnd = MockRepository.GenerateMock <IRandomization>(); rnd.Expect(r => r.GetInt(1, 7)).Return(3); rnd.Expect(r => r.GetUniqueInts(3, 0, 8)).Return(new int[] { 1, 2, 5 }); RandomizationProvider.Current = rnd; IList <IChromosome> actual = null;; TimeAssert.LessThan(40, () => { actual = target.Cross(new List <IChromosome>() { chromosome1, chromosome2 }); }); Assert.AreEqual(2, actual.Count); var childOne = actual [0]; var childTwo = actual [1]; Assert.AreEqual(8, childOne.Length); Assert.AreEqual(8, childTwo.Length); Assert.AreEqual(8, childOne.GetGenes().Distinct().Count()); Assert.AreEqual(8, childTwo.GetGenes().Distinct().Count()); Assert.AreEqual(1, childOne.GetGene(0).Value); Assert.AreEqual(4, childOne.GetGene(1).Value); Assert.AreEqual(6, childOne.GetGene(2).Value); Assert.AreEqual(2, childOne.GetGene(3).Value); Assert.AreEqual(3, childOne.GetGene(4).Value); Assert.AreEqual(5, childOne.GetGene(5).Value); Assert.AreEqual(7, childOne.GetGene(6).Value); Assert.AreEqual(8, childOne.GetGene(7).Value); Assert.AreEqual(4, childTwo.GetGene(0).Value); Assert.AreEqual(2, childTwo.GetGene(1).Value); Assert.AreEqual(3, childTwo.GetGene(2).Value); Assert.AreEqual(8, childTwo.GetGene(3).Value); Assert.AreEqual(7, childTwo.GetGene(4).Value); Assert.AreEqual(6, childTwo.GetGene(5).Value); Assert.AreEqual(5, childTwo.GetGene(6).Value); Assert.AreEqual(1, childTwo.GetGene(7).Value); }
public void Cross_ParentsWith6Genes_Cross() { var target = new PositionBasedCrossover(); // 1 5 4 0 3 2 var chromosome1 = MockRepository.GenerateStub <ChromosomeBase>(6); chromosome1.ReplaceGenes(0, new Gene[] { new Gene(1), new Gene(5), new Gene(4), new Gene(0), new Gene(3), new Gene(2) }); chromosome1.Expect(c => c.CreateNew()).Return(MockRepository.GenerateStub <ChromosomeBase>(6)); // 2 3 5 0 1 4 var chromosome2 = MockRepository.GenerateStub <ChromosomeBase>(6); chromosome2.ReplaceGenes(0, new Gene[] { new Gene(2), new Gene(3), new Gene(5), new Gene(0), new Gene(1), new Gene(4) }); chromosome2.Expect(c => c.CreateNew()).Return(MockRepository.GenerateStub <ChromosomeBase>(6)); // Child one: 4 3 5 0 1 2 // Child two: 2 5 4 0 3 1 var rnd = MockRepository.GenerateMock <IRandomization>(); rnd.Expect(r => r.GetInt(1, 5)).Return(3); rnd.Expect(r => r.GetUniqueInts(3, 0, 6)).Return(new int[] { 2, 4, 3 }); RandomizationProvider.Current = rnd; IList <IChromosome> actual = null;; TimeAssert.LessThan(40, () => { actual = target.Cross(new List <IChromosome>() { chromosome1, chromosome2 }); }); Assert.AreEqual(2, actual.Count); var childOne = actual[0]; var childTwo = actual[1]; Assert.AreEqual(6, childOne.Length); Assert.AreEqual(6, childTwo.Length); Assert.AreEqual(6, childOne.GetGenes().Distinct().Count()); Assert.AreEqual(6, childTwo.GetGenes().Distinct().Count()); Assert.AreEqual(4, childOne.GetGene(0).Value); Assert.AreEqual(3, childOne.GetGene(1).Value); Assert.AreEqual(5, childOne.GetGene(2).Value); Assert.AreEqual(0, childOne.GetGene(3).Value); Assert.AreEqual(1, childOne.GetGene(4).Value); Assert.AreEqual(2, childOne.GetGene(5).Value); Assert.AreEqual(2, childTwo.GetGene(0).Value); Assert.AreEqual(5, childTwo.GetGene(1).Value); Assert.AreEqual(4, childTwo.GetGene(2).Value); Assert.AreEqual(0, childTwo.GetGene(3).Value); Assert.AreEqual(3, childTwo.GetGene(4).Value); Assert.AreEqual(1, childTwo.GetGene(5).Value); }
public void Cross_ParentsWith8Genes_Cross() { var target = new PositionBasedCrossover(); // 1 2 3 4 5 6 7 8 var chromosome1 = Substitute.For <ChromosomeBase>(8); chromosome1.ReplaceGenes(0, new Gene[] { new Gene(1), new Gene(2), new Gene(3), new Gene(4), new Gene(5), new Gene(6), new Gene(7), new Gene(8) }); chromosome1.CreateNew().Returns(Substitute.For <ChromosomeBase>(8)); // 2 4 6 8 7 5 3 1 var chromosome2 = Substitute.For <ChromosomeBase>(8); chromosome2.ReplaceGenes(0, new Gene[] { new Gene(2), new Gene(4), new Gene(6), new Gene(8), new Gene(7), new Gene(5), new Gene(3), new Gene(1) }); chromosome2.CreateNew().Returns(Substitute.For <ChromosomeBase>(8)); // Child one: 1 4 6 2 3 5 7 8 // Child two: 4 2 3 8 7 6 5 1 var rnd = Substitute.For <IRandomization>(); rnd.GetInt(1, 7).Returns(3); rnd.GetUniqueInts(3, 0, 8).Returns(new int[] { 1, 2, 5 }); RandomizationProvider.Current = rnd; var actual = target.Cross(new List <IChromosome>() { chromosome1, chromosome2 }); Assert.AreEqual(2, actual.Count); var childOne = actual [0]; var childTwo = actual [1]; Assert.AreEqual(8, childOne.Length); Assert.AreEqual(8, childTwo.Length); Assert.AreEqual(8, childOne.GetGenes().Distinct().Count()); Assert.AreEqual(8, childTwo.GetGenes().Distinct().Count()); Assert.AreEqual(1, childOne.GetGene(0).Value); Assert.AreEqual(4, childOne.GetGene(1).Value); Assert.AreEqual(6, childOne.GetGene(2).Value); Assert.AreEqual(2, childOne.GetGene(3).Value); Assert.AreEqual(3, childOne.GetGene(4).Value); Assert.AreEqual(5, childOne.GetGene(5).Value); Assert.AreEqual(7, childOne.GetGene(6).Value); Assert.AreEqual(8, childOne.GetGene(7).Value); Assert.AreEqual(4, childTwo.GetGene(0).Value); Assert.AreEqual(2, childTwo.GetGene(1).Value); Assert.AreEqual(3, childTwo.GetGene(2).Value); Assert.AreEqual(8, childTwo.GetGene(3).Value); Assert.AreEqual(7, childTwo.GetGene(4).Value); Assert.AreEqual(6, childTwo.GetGene(5).Value); Assert.AreEqual(5, childTwo.GetGene(6).Value); Assert.AreEqual(1, childTwo.GetGene(7).Value); }
public void Cross_ParentsWith6Genes_Cross() { var target = new PositionBasedCrossover(); // 1 5 4 0 3 2 var chromosome1 = Substitute.For <ChromosomeBase>(6); chromosome1.ReplaceGenes(0, new Gene[] { new Gene(1), new Gene(5), new Gene(4), new Gene(0), new Gene(3), new Gene(2) }); chromosome1.CreateNew().Returns(Substitute.For <ChromosomeBase>(6)); // 2 3 5 0 1 4 var chromosome2 = Substitute.For <ChromosomeBase>(6); chromosome2.ReplaceGenes(0, new Gene[] { new Gene(2), new Gene(3), new Gene(5), new Gene(0), new Gene(1), new Gene(4) }); chromosome2.CreateNew().Returns(Substitute.For <ChromosomeBase>(6)); // Child one: 4 3 5 0 1 2 // Child two: 2 5 4 0 3 1 var rnd = Substitute.For <IRandomization>(); rnd.GetInt(1, 5).Returns(3); rnd.GetUniqueInts(3, 0, 6).Returns(new int[] { 2, 4, 3 }); RandomizationProvider.Current = rnd; var actual = target.Cross(new List <IChromosome>() { chromosome1, chromosome2 }); Assert.AreEqual(2, actual.Count); var childOne = actual[0]; var childTwo = actual[1]; Assert.AreEqual(6, childOne.Length); Assert.AreEqual(6, childTwo.Length); Assert.AreEqual(6, childOne.GetGenes().Distinct().Count()); Assert.AreEqual(6, childTwo.GetGenes().Distinct().Count()); Assert.AreEqual(4, childOne.GetGene(0).Value); Assert.AreEqual(3, childOne.GetGene(1).Value); Assert.AreEqual(5, childOne.GetGene(2).Value); Assert.AreEqual(0, childOne.GetGene(3).Value); Assert.AreEqual(1, childOne.GetGene(4).Value); Assert.AreEqual(2, childOne.GetGene(5).Value); Assert.AreEqual(2, childTwo.GetGene(0).Value); Assert.AreEqual(5, childTwo.GetGene(1).Value); Assert.AreEqual(4, childTwo.GetGene(2).Value); Assert.AreEqual(0, childTwo.GetGene(3).Value); Assert.AreEqual(3, childTwo.GetGene(4).Value); Assert.AreEqual(1, childTwo.GetGene(5).Value); }
public IList <IChromosome> PositionBasedCrossover() { var target = new PositionBasedCrossover(); return(target.Cross(CreateTwoParents())); }