/// <summary> /// Performs the selection of chromosomes from the generation specified. /// </summary> /// <param name="number">The number of chromosomes to select.</param> /// <param name="generation">The generation where the selection will be made.</param> /// <returns> /// The selected chromosomes. /// </returns> protected override IList<IChromosome> PerformSelectChromosomes(int number, Generation generation) { var chromosomes = generation.Chromosomes; var selected = new List<IChromosome>(); var sumFitness = chromosomes.Sum(c => c.Fitness.Value); var rouleteWheel = new List<double>(); var accumulativePercent = 0.0; double stepSize = 1.0 / number; foreach (var c in chromosomes) { accumulativePercent += c.Fitness.Value / sumFitness; rouleteWheel.Add(accumulativePercent); } var pointer = RandomizationProvider.Current.GetDouble(); for (int i = 0; i < number; i++) { if (pointer > 1.0) { pointer -= 1.0; } var chromosomeIndex = rouleteWheel.Select((value, index) => new { Value = value, Index = index }).FirstOrDefault(r => r.Value >= pointer).Index; selected.Add(chromosomes[chromosomeIndex]); pointer += stepSize; } return selected; }
/// <summary> /// Performs the selection of chromosomes from the generation specified. /// </summary> /// <param name="number">The number of chromosomes to select.</param> /// <param name="generation">The generation where the selection will be made.</param> /// <returns> /// The selected chromosomes. /// </returns> protected override IList<IChromosome> PerformSelectChromosomes(int number, Generation generation) { var chromosomes = generation.Chromosomes; var rouleteWheel = new List<double>(); double stepSize = 1.0 / number; CalculateCumulativePercentFitness(chromosomes, rouleteWheel); var pointer = RandomizationProvider.Current.GetDouble(); return SelectFromWheel( number, chromosomes, rouleteWheel, () => { if (pointer > 1.0) { pointer -= 1.0; } var currentPointer = pointer; pointer += stepSize; return currentPointer; }); }
public void SelectChromosomes_Generation_ChromosomesSelected() { var target = new EliteSelection(); var c1 = MockRepository.GeneratePartialMock<ChromosomeBase> (2); c1.Fitness = 0.1; var c2 = MockRepository.GeneratePartialMock<ChromosomeBase>(2); c2.Fitness = 0.5; var c3 = MockRepository.GeneratePartialMock<ChromosomeBase>(2); c3.Fitness = 0; var c4 = MockRepository.GeneratePartialMock<ChromosomeBase>(2); c4.Fitness = 0.7; var generation = new Generation (1, new List<IChromosome> () { c1, c2, c3, c4 }); var actual = target.SelectChromosomes(2, generation); Assert.AreEqual(2, actual.Count); Assert.AreEqual (0.7, actual [0].Fitness); Assert.AreEqual (0.5, actual [1].Fitness); actual = target.SelectChromosomes(3, generation); Assert.AreEqual(3, actual.Count); Assert.AreEqual (0.7, actual [0].Fitness); Assert.AreEqual (0.5, actual [1].Fitness); Assert.AreEqual (0.1, actual [2].Fitness); }
/// <summary> /// Performs the selection of chromosomes from the generation specified. /// </summary> /// <param name="number">The number of chromosomes to select.</param> /// <param name="generation">The generation where the selection will be made.</param> /// <returns> /// The selected chromosomes. /// </returns> protected override IList<IChromosome> PerformSelectChromosomes(int number, Generation generation) { if (Size > generation.Chromosomes.Count) { throw new SelectionException( this, "The tournament size is greater than available chromosomes. Tournament size is {0} and generation {1} available chromosomes are {2}.".With(Size, generation.Number, generation.Chromosomes.Count)); } var candidates = generation.Chromosomes.ToList(); var selected = new List<IChromosome>(); while (selected.Count < number) { var randomIndexes = RandomizationProvider.Current.GetUniqueInts(Size, 0, candidates.Count); var tournamentWinner = candidates.Where((c, i) => randomIndexes.Contains(i)).OrderByDescending(c => c.Fitness).First(); selected.Add(tournamentWinner); if (!AllowWinnerCompeteNextTournament) { candidates.Remove(tournamentWinner); } } return selected; }
public void SelectChromosomes_Generation_ChromosomesSelected() { var target = new StochasticUniversalSamplingSelection(); var c1 = new ChromosomeStub(); c1.Fitness = 0.1; var c2 = new ChromosomeStub(); c2.Fitness = 0.5; var c3 = new ChromosomeStub(); c3.Fitness = 0; var c4 = new ChromosomeStub(); c4.Fitness = 0.7; var generation = new Generation(1, new List<IChromosome>() { c1, c2, c3, c4 }); // Fitness sum: 0.1 + 0.5 + 0 + 0.7 = 1.3 // c1: 8% = 0.08 // c2: 38% = 0.46 // c3: 0% = 0.46 // c4: 54% = 1.00 var rnd = MockRepository.GenerateMock<IRandomization>(); rnd.Expect(r => r.GetDouble()).Return(0.3); RandomizationProvider.Current = rnd; // Step size 1/2 = 0.5 var actual = target.SelectChromosomes(2, generation); Assert.AreEqual(2, actual.Count); Assert.AreEqual(c2.Fitness, actual[0].Fitness); // 0.3 Assert.AreEqual(c4.Fitness, actual[1].Fitness); // 0.8 // Step size 1/3 = 0.33 actual = target.SelectChromosomes(3, generation); Assert.AreEqual(3, actual.Count); Assert.AreEqual(c2.Fitness, actual[0].Fitness); // 0.3 Assert.AreEqual(c4.Fitness, actual[1].Fitness); // 0.63 Assert.AreEqual(c4.Fitness, actual[2].Fitness); // 0.96 // Step size 1/4 = 0.25 actual = target.SelectChromosomes(4, generation); Assert.AreEqual(4, actual.Count); Assert.AreEqual(c2.Fitness, actual[0].Fitness); // 0.3 Assert.AreEqual(c4.Fitness, actual[1].Fitness); // 0.55 Assert.AreEqual(c4.Fitness, actual[2].Fitness); // 0.80 Assert.AreEqual(c1.Fitness, actual[3].Fitness); // 0.05 // Step size 1/5 = 0.20 actual = target.SelectChromosomes(5, generation); Assert.AreEqual(5, actual.Count); Assert.AreEqual(c2.Fitness, actual[0].Fitness); // 0.3 Assert.AreEqual(c4.Fitness, actual[1].Fitness); // 0.5 Assert.AreEqual(c4.Fitness, actual[2].Fitness); // 0.7 Assert.AreEqual(c4.Fitness, actual[3].Fitness); // 0.9 Assert.AreEqual(c2.Fitness, actual[4].Fitness); // 0.1 }
public void Constructor_OkArguments_Instanced() { var target = new Generation(1, new List<IChromosome>() { MockRepository.GenerateMock<IChromosome>(), MockRepository.GenerateMock<IChromosome>() }); Assert.AreEqual(1, target.Number); Assert.AreEqual(2, target.Chromosomes.Count); }
/// <summary> /// Selects the number of chromosomes from the generation specified. /// </summary> /// <returns>The selected chromosomes.</returns> /// <param name="number">The number of chromosomes to select.</param> /// <param name="generation">The generation where the selection will be made.</param> public IList<IChromosome> SelectChromosomes(int number, Generation generation) { if (number < m_minNumberChromosomes) { throw new ArgumentOutOfRangeException("number", "The number of selected chromosomes should be at least {0}.".With(m_minNumberChromosomes)); } ExceptionHelper.ThrowIfNull("generation", generation); return PerformSelectChromosomes(number, generation); }
public void End_AnyChromosomeWithoutFitness_Exception() { var target = new Generation(1, new List<IChromosome>() { new ChromosomeStub() { Fitness = 0.2 }, new ChromosomeStub() { Fitness = null}, new ChromosomeStub() { Fitness = 0.1 } }); ExceptionAssert.IsThrowing(new InvalidOperationException("There is unknown problem in current generation, because a chromosome has no fitness value."), () => { target.End(2); }); }
public void End_ChromosomeNumberGreaterThan_Take() { var target = new Generation(1, new List<IChromosome>() { new ChromosomeStub() { Fitness = 0.2 }, new ChromosomeStub() { Fitness = 0.3 }, new ChromosomeStub() { Fitness = 0.1 } }); target.End(2); Assert.AreEqual(2, target.Chromosomes.Count); Assert.AreEqual(0.3, target.Chromosomes[0].Fitness); Assert.AreEqual(0.2, target.Chromosomes[1].Fitness); }
public void SelectChromosomes_TournamentSize3AllowWinnerCompeteNextTournamentFalse_ChromosomesSelected() { var target = new TournamentSelection(3, false); var c0 = MockRepository.GeneratePartialMock<ChromosomeBase>(2); c0.Fitness = 0.1; var c1 = MockRepository.GeneratePartialMock<ChromosomeBase>(2); c1.Fitness = 0.5; var c2 = MockRepository.GeneratePartialMock<ChromosomeBase>(2); c2.Fitness = 0; var c3 = MockRepository.GeneratePartialMock<ChromosomeBase>(2); c3.Fitness = 0.7; var c4 = MockRepository.GeneratePartialMock<ChromosomeBase>(2); c4.Fitness = 0.3; var c5 = MockRepository.GeneratePartialMock<ChromosomeBase>(2); c5.Fitness = 0.2; var generation = new Generation(1, new List<IChromosome>() { c0, c1, c2, c3, c4, c5 }); var mock = new MockRepository(); var rnd = mock.StrictMock<IRandomization>(); using (mock.Ordered()) { rnd.Expect(r => r.GetUniqueInts(3, 0, 6)).Return(new int[] { 0, 1, 2 }); rnd.Expect(r => r.GetUniqueInts(3, 0, 5)).Return(new int[] { 2, 3, 4 }); rnd.Expect(r => r.GetUniqueInts(3, 0, 4)).Return(new int[] { 0, 1, 2 }); rnd.Expect(r => r.GetUniqueInts(3, 0, 3)).Return(new int[] { 0, 1, 2 }); } RandomizationProvider.Current = rnd; mock.ReplayAll(); var actual = target.SelectChromosomes(4, generation); Assert.AreEqual(4, actual.Count); Assert.AreEqual(c1, actual[0]); Assert.AreEqual(c3, actual[1]); Assert.AreEqual(c4, actual[2]); Assert.AreEqual(c5, actual[3]); }
public void SelectChromosomes_TournamentSizeGreaterThanAvailableChromosomes_Exception() { var target = new TournamentSelection(3, true); var c0 = MockRepository.GeneratePartialMock<ChromosomeBase>(2); c0.Fitness = 0.1; var c1 = MockRepository.GeneratePartialMock<ChromosomeBase>(2); c1.Fitness = 0.5; var generation = new Generation(1, new List<IChromosome>() { c0, c1 }); ExceptionAssert.IsThrowing(new SelectionException(target, "The tournament size is greater than available chromosomes. Tournament size is 3 and generation 1 available chromosomes are 2."), () => { target.SelectChromosomes(2, generation); }); }
public void SelectChromosomes_Generation_ChromosomesSelected() { var target = new RouletteWheelSelection(); var c1 = MockRepository.GeneratePartialMock<ChromosomeBase> (2); c1.Fitness = 0.1; var c2 = MockRepository.GeneratePartialMock<ChromosomeBase>(2); c2.Fitness = 0.5; var c3 = MockRepository.GeneratePartialMock<ChromosomeBase>(2); c3.Fitness = 0; var c4 = MockRepository.GeneratePartialMock<ChromosomeBase>(2); c4.Fitness = 0.7; var generation = new Generation (1, new List<IChromosome> () { c1, c2, c3, c4 }); // Just one selected chromosome is c1. FlowAssert.IsAtLeastOneAttemptOk (100, () => { var actual = target.SelectChromosomes (2, generation); Assert.AreEqual(2, actual.Count); Assert.AreEqual(1, actual.Count(c => c.Fitness == 0.1)); }); // All selected chromosome is c1. FlowAssert.IsAtLeastOneAttemptOk (1000, () => { var actual = target.SelectChromosomes (2, generation); Assert.AreEqual(2, actual.Count); Assert.IsTrue(actual.All(c => c.Fitness == 0.1)); }); // Just one selected chromosome is c2. FlowAssert.IsAtLeastOneAttemptOk(100, () => { var actual = target.SelectChromosomes(2, generation); Assert.AreEqual(2, actual.Count); Assert.AreEqual(1, actual.Count(c => c.Fitness == 0.5)); }); // All selected chromosome is c2. FlowAssert.IsAtLeastOneAttemptOk(1000, () => { var actual = target.SelectChromosomes(2, generation); Assert.AreEqual(2, actual.Count); Assert.IsTrue(actual.All(c => c.Fitness == 0.5)); }); // None selected chromosome is c3. FlowAssert.IsAtLeastOneAttemptOk(100, () => { var actual = target.SelectChromosomes(2, generation); Assert.AreEqual(2, actual.Count); Assert.AreEqual(0, actual.Count(c => c.Fitness == 0.0)); }); // Just one selected chromosome is c4. FlowAssert.IsAtLeastOneAttemptOk(100, () => { var actual = target.SelectChromosomes(2, generation); Assert.AreEqual(2, actual.Count); Assert.AreEqual(1, actual.Count(c => c.Fitness == 0.7)); }); // All selected chromosome is c4. FlowAssert.IsAtLeastOneAttemptOk(1000, () => { var actual = target.SelectChromosomes(2, generation); Assert.AreEqual(2, actual.Count); Assert.IsTrue(actual.All(c => c.Fitness == 0.7)); }); }
/// <summary> /// Creates a new generation. /// </summary> /// <param name="chromosomes">The chromosomes for new generation.</param> public void CreateNewGeneration(IList<IChromosome> chromosomes) { ExceptionHelper.ThrowIfNull("chromosomes", chromosomes); chromosomes.ValidateGenes(); CurrentGeneration = new Generation(++GenerationsNumber, chromosomes); Generations.Add(CurrentGeneration); GenerationStrategy.RegisterNewGeneration(this); }
/// <summary> /// Performs the selection of chromosomes from the generation specified. /// </summary> /// <param name="number">The number of chromosomes to select.</param> /// <param name="generation">The generation where the selection will be made.</param> /// <returns>The select chromosomes.</returns> protected override IList<IChromosome> PerformSelectChromosomes(int number, Generation generation) { var ordered = generation.Chromosomes.OrderByDescending (c => c.Fitness); return ordered.Take (number).ToList (); }
/// <summary> /// Performs the selection of chromosomes from the generation specified. /// </summary> /// <param name="number">The number of chromosomes to select.</param> /// <param name="generation">The generation where the selection will be made.</param> /// <returns>The select chromosomes.</returns> protected override IList<IChromosome> PerformSelectChromosomes(int number, Generation generation) { var chromosomes = generation.Chromosomes; var rouletteWheel = new List<double>(); var rnd = RandomizationProvider.Current; CalculateCumulativePercentFitness(chromosomes, rouletteWheel); return SelectFromWheel(number, chromosomes, rouletteWheel, () => rnd.GetDouble()); }
/// <summary> /// Performs the selection of chromosomes from the generation specified. /// </summary> /// <returns>The selected chromosomes.</returns> /// <param name="number">The number of chromosomes to select.</param> /// <param name="generation">The generation where the selection will be made.</param> protected abstract IList<IChromosome> PerformSelectChromosomes(int number, Generation generation);