Skip to content

Commit

Permalink
Fix #61 - AlternatingPositionCrossover throw IndexOutOfRangeException
Browse files Browse the repository at this point in the history
  • Loading branch information
giacomelli committed Jun 12, 2019
1 parent 4f495a0 commit 267ca1c
Show file tree
Hide file tree
Showing 3 changed files with 130 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@
using GeneticSharp.Domain.Terminations;
using System.Diagnostics;
using GeneticSharp.Extensions.Tsp;

using GeneticSharp.Domain.UnitTests.Crossovers.Issues;

namespace GeneticSharp.Domain.UnitTests.Crossovers
{
[TestFixture]
Expand Down Expand Up @@ -165,5 +166,38 @@ public void GA_WithAlternatingPositionCrossover_Evolve()
population.Generations.First().BestChromosome.Fitness.Value,
population.Generations.Last().BestChromosome.Fitness.Value);
}

/// <summary>
/// https://github.com/giacomelli/GeneticSharp/issues/61
/// </summary>
[Test]
public void GA_Issue61_Solved()
{
const Int32 FinalAns = 4567213;
var chromosome = new Issue61.GuessNumberChromosome(FinalAns.ToString().Length);
var population = new Population(1000, 5000, chromosome);
var fitness = new Issue61.GuessNumberFitness(FinalAns);
var selection = new EliteSelection();
var crossover = new AlternatingPositionCrossover();
var mutation = new ReverseSequenceMutation();
var ga = new GeneticAlgorithm(population, fitness, selection, crossover, mutation);
ga.MutationProbability = 0.2f;
ga.CrossoverProbability = 0.75f;
ga.Termination = new OrTermination(
new FitnessThresholdTermination(1.0),
new FitnessStagnationTermination(200),
new GenerationNumberTermination(1000));
ga.Population.GenerationStrategy = new TrackingGenerationStrategy();
ga.Start();

foreach(var gen in ga.Population.Generations)
{
foreach(var chromossome in gen.Chromosomes)
{
// Asserts if AlternatingPositionCrossover generated only ordered chromossomes.
Assert.AreEqual(chromosome.Length, chromosome.GetGenes().Distinct().Count());
}
}
}
}
}
91 changes: 91 additions & 0 deletions src/GeneticSharp.Domain.UnitTests/Crossovers/Issues/Issue61.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
using GeneticSharp.Domain.Chromosomes;
using GeneticSharp.Domain.Fitnesses;
using GeneticSharp.Domain.Randomizations;
using System;
using System.Collections.Generic;
using System.Text;

namespace GeneticSharp.Domain.UnitTests.Crossovers.Issues
{
public class Issue61
{
public class GuessNumberChromosome : ChromosomeBase
{

private const Int32 MaxGeneValue = 10;
private const Int32 MinGeneValue = 0;

public static int[] powof10 = new int[10] {
1,
10,
100,
1000,
10000,
100000,
1000000,
10000000,
100000000,
1000000000
};

private readonly Int32 numberDigits;

public GuessNumberChromosome(Int32 numberDigits) : base(numberDigits)
{
this.numberDigits = numberDigits;
var initGenes = RandomizationProvider.Current.GetUniqueInts(this.Length, MinGeneValue, MaxGeneValue);
for (int i = 0; i < this.Length; i++)
{
this.ReplaceGene(i, new Gene(initGenes[i]));
}
}

public override IChromosome CreateNew()
{
return new GuessNumberChromosome(this.numberDigits);
}

public override Gene GenerateGene(int geneIndex)
{
return new Gene(RandomizationProvider.Current.GetInt(MinGeneValue, MaxGeneValue));
}

public Int32 ToGuessValue()
{
var genes = this.GetGenes();
return ToGuessValue(genes);
}

public static Int32 ToGuessValue(Gene[] genes)
{
int guessValue = 0;
for (int i = genes.Length - 1; i >= 0; i--)
{
guessValue += ((Int32)genes[i].Value * powof10[i]);
}
return guessValue;
}
}

public class GuessNumberFitness : IFitness
{
private Int32 finalAns;
private Int32 maxDiffValue;

public GuessNumberFitness(Int32 finalAns)
{
this.finalAns = finalAns;
Int32 digits = this.finalAns.ToString().Length;
this.maxDiffValue = Math.Max(Math.Abs(this.finalAns - Int32.Parse(new string('9', digits))), this.finalAns);
}

public double Evaluate(IChromosome chromosome)
{
var genes = chromosome.GetGenes();
int guessValue = GuessNumberChromosome.ToGuessValue(genes);
double fitness = 1.0 - (Math.Abs(this.finalAns - guessValue) / (double)this.maxDiffValue);
return fitness;
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,10 @@ private IChromosome CreateChild(IChromosome firstParent, IChromosome secondParen
for (int i = 0; i < firstParent.Length && childGenesIndex < firstParent.Length; i++)
{
AddChildGene(childGenes, ref childGenesIndex, firstParent.GetGene(i));
AddChildGene(childGenes, ref childGenesIndex, secondParent.GetGene(i));

// The childGenesIndes could be incremented by the previous AddChildGene call
if (childGenesIndex < secondParent.Length)
AddChildGene(childGenes, ref childGenesIndex, secondParent.GetGene(i));
}

child.ReplaceGenes(0, childGenes);
Expand Down

0 comments on commit 267ca1c

Please sign in to comment.