Skip to content
Open
Show file tree
Hide file tree
Changes from 12 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion global.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"sdk": {
"version": "6.0.400"
"version": "8"
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The GeneticSharp is officially only supporting .NET 6, so it's not a good idea to change it here.

When I have some time available, I will make a PR to support .NET 9.

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
using System;
using System.Linq;
using NUnit.Framework;

namespace GeneticSharp.Domain.UnitTests.Chromosomes
{
[TestFixture]
public class SelfAdaptiveChromosomeTest
{
[Test]
public void Constructor_ValidParameters_InitializesCorrectly()
{
int length = 10;
double minValue = 0.0;
double maxValue = 1.0;
double initMutationProvVal = 0.05;

var chromosome = new SelfAdaptiveChromosome(length, minValue, maxValue, initMutationProvVal);

Assert.AreEqual(length, chromosome.Length);
}

[Test]
public void Clone_ValidChromosome_ClonesCorrectly()
{
int length = 10;
var chromosome = new SelfAdaptiveChromosome(length);

var clone = chromosome.Clone() as SelfAdaptiveChromosome;

Assert.IsNotNull(clone);
Assert.AreEqual(chromosome.Length, clone.Length);
}

[Test]
public void CreateNew_ValidChromosome_CreatesNewInstance()
{
int length = 10;
var chromosome = new SelfAdaptiveChromosome(length);

var newChromosome = chromosome.CreateNew() as SelfAdaptiveChromosome;

Assert.IsNotNull(newChromosome);
Assert.AreEqual(length, newChromosome.Length);
}

[Test]
public void GenerateGene_ValidIndex_GeneratesGeneWithinRange()
{
int length = 10;
double minValue = 0.0;
double maxValue = 1.0;
var chromosome = new SelfAdaptiveChromosome(length, minValue, maxValue);

for (int i = 0; i < length; i++)
{
var gene = chromosome.GenerateGene(i);
Assert.IsTrue((double)gene.Value >= minValue && (double)gene.Value <= maxValue);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public void GetCrossoverTypes_NoArgs_AllAvailableCrossovers()
{
var actual = CrossoverService.GetCrossoverTypes();

Assert.AreEqual(12, actual.Count);
Assert.AreEqual(13, actual.Count);
var index = -1;
Assert.AreEqual(typeof(AlternatingPositionCrossover), actual[++index]);
Assert.AreEqual(typeof(CutAndSpliceCrossover), actual[++index]);
Expand All @@ -22,18 +22,20 @@ public void GetCrossoverTypes_NoArgs_AllAvailableCrossovers()
Assert.AreEqual(typeof(OrderedCrossover), actual[++index]);
Assert.AreEqual(typeof(PartiallyMappedCrossover), actual[++index]);
Assert.AreEqual(typeof(PositionBasedCrossover), actual[++index]);
Assert.AreEqual(typeof(SelfAdaptiveCrossover), actual[++index]);
Assert.AreEqual(typeof(ThreeParentCrossover), actual[++index]);
Assert.AreEqual(typeof(TwoPointCrossover), actual[++index]);
Assert.AreEqual(typeof(UniformCrossover), actual[++index]);
Assert.AreEqual(typeof(VotingRecombinationCrossover), actual[++index]);

}

[Test()]
public void GetCrossoverNames_NoArgs_AllAvailableCrossoversNames()
{
var actual = CrossoverService.GetCrossoverNames();

Assert.AreEqual(12, actual.Count);
Assert.AreEqual(13, actual.Count);
var index = -1;
Assert.AreEqual("Alternating-position (AP)", actual[++index]);
Assert.AreEqual("Cut and Splice", actual[++index]);
Expand All @@ -43,6 +45,7 @@ public void GetCrossoverNames_NoArgs_AllAvailableCrossoversNames()
Assert.AreEqual("Ordered (OX1)", actual[++index]);
Assert.AreEqual("Partially Mapped (PMX)", actual[++index]);
Assert.AreEqual("Position-based (POS)", actual[++index]);
Assert.AreEqual("Self Adaptive Crossover", actual[++index]);
Assert.AreEqual("Three Parent", actual[++index]);
Assert.AreEqual("Two-Point", actual[++index]);
Assert.AreEqual("Uniform", actual[++index]);
Expand Down
15 changes: 8 additions & 7 deletions src/GeneticSharp.Domain.UnitTests/GeneticAlgorithmTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -493,8 +493,7 @@ public void Start_UsingAllConfigurationCombinationsAvailable_AllRun()
var crossovers = CrossoverService.GetCrossoverNames();
var mutations = MutationService.GetMutationNames().Where(m => !m.Equals("Flip Bit"));
var reinsertions = ReinsertionService.GetReinsertionNames();
var chromosome = new OrderedChromosomeStub();


foreach (var s in selections)
{
foreach (var c in crossovers)
Expand All @@ -508,6 +507,8 @@ public void Start_UsingAllConfigurationCombinationsAvailable_AllRun()
var mutation = MutationService.CreateMutationByName(m);
var reinsertion = ReinsertionService.CreateReinsertionByName(r);

IChromosome chromosome =(IChromosome) (((crossover is SelfAdaptiveCrossover) || (mutation is SelfAdaptiveMutation)) ? new SelfAdaptiveChromosome(6, 0,6) : new OrderedChromosomeStub());

if (crossover.IsOrdered ^ mutation.IsOrdered)
{
continue;
Expand All @@ -523,12 +524,12 @@ public void Start_UsingAllConfigurationCombinationsAvailable_AllRun()
mutation = new UniformMutation(1);
}

var population = new Population(50, 50, chromosome.Clone()){ GenerationStrategy = new TrackingGenerationStrategy() };
var fitness = new FitnessStub() { SupportsParallel = false };

var target = new GeneticAlgorithm(
new Population(50, 50, chromosome.Clone())
{
GenerationStrategy = new TrackingGenerationStrategy()
},
new FitnessStub() { SupportsParallel = false },
population,
fitness,
selection,
crossover,
mutation);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,29 +13,31 @@ public void GetMutationTypes_NoArgs_AllAvailableMutations()
{
var actual = MutationService.GetMutationTypes();

Assert.AreEqual(7, actual.Count);
Assert.AreEqual(8, actual.Count);
Assert.AreEqual(typeof(DisplacementMutation), actual[0]);
Assert.AreEqual(typeof(FlipBitMutation), actual[1]);
Assert.AreEqual(typeof(InsertionMutation), actual[2]);
Assert.AreEqual(typeof(PartialShuffleMutation), actual[3]);
Assert.AreEqual(typeof(ReverseSequenceMutation), actual[4]);
Assert.AreEqual(typeof(TworsMutation), actual[5]);
Assert.AreEqual(typeof(UniformMutation), actual[6]);
Assert.AreEqual(typeof(SelfAdaptiveMutation), actual[5]);
Assert.AreEqual(typeof(TworsMutation), actual[6]);
Assert.AreEqual(typeof(UniformMutation), actual[7]);
}

[Test()]
public void GetMutationNames_NoArgs_AllAvailableMutationsNames()
{
var actual = MutationService.GetMutationNames();

Assert.AreEqual(7, actual.Count);
Assert.AreEqual(8, actual.Count);
Assert.AreEqual("Displacement", actual[0]);
Assert.AreEqual("Flip Bit", actual[1]);
Assert.AreEqual("Insertion", actual[2]);
Assert.AreEqual("Partial Shuffle (PSM)", actual[3]);
Assert.AreEqual("Reverse Sequence (RSM)", actual[4]);
Assert.AreEqual("Twors", actual[5]);
Assert.AreEqual("Uniform", actual[6]);
Assert.AreEqual("Self Adaptive Mutation", actual[5]);
Assert.AreEqual("Twors", actual[6]);
Assert.AreEqual("Uniform", actual[7]);
}

[Test()]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
using System;
using System.Linq;
using NUnit.Framework;

namespace GeneticSharp.Domain.UnitTests.Mutations
{
[TestFixture]
public class SelfAdaptiveMutationTest
{
[Test]
public void Constructor_ValidParameters_InitializesCorrectly()
{
double tau = 0.1;
double minMutationRate = 0.05;
double maxMutationRate = 0.9;

var mutation = new SelfAdaptiveMutation(tau, minMutationRate, maxMutationRate);
}



[Test]
public void PerformMutate_ValidChromosome_MutatesCorrectly()
{
int length = 100;
var chromosome = new SelfAdaptiveChromosome(length, 0,20);
var mutation = new SelfAdaptiveMutation();
var random = new Random();



mutation.Mutate(chromosome, 1.0f);

// Check if mutation probabilities are within the expected range
for (int i = 0; i < length; i++)
{
Assert.That(chromosome.GetMutationProbability(i), Is.InRange(mutation.MinMutationRate, mutation.MaxMutationRate));
}

// Check if genes have been mutated
var genes = chromosome.GetGenes();
for (int i = 0; i < length; i++)
{
Assert.That((double)genes[i].Value, Is.InRange(chromosome._minValue, chromosome._maxValue));
}
}


}
}
3 changes: 2 additions & 1 deletion src/GeneticSharp.Domain.UnitTests/Populations/FitnessStub.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System;
using System.Linq;
using System.Threading;

Expand All @@ -21,7 +22,7 @@ public double Evaluate(IChromosome chromosome)
}

var genes = chromosome.GetGenes();
double f = genes.Sum(g => (int)g.Value) / 20f;
double f = genes.Sum(g => Convert.ToInt32(g.Value)) / 20f;

if (f > 1)
{
Expand Down
68 changes: 68 additions & 0 deletions src/GeneticSharp.Domain/Chromosomes/SelfAdaptiveChromosome.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
using System;
using System.Collections.Generic;
using System.Linq;

namespace GeneticSharp
{
public class SelfAdaptiveChromosome : ChromosomeBase
{
Dictionary<int, double> _mutationProbabilities;
int _length;
double _initMutationProvVal;
public readonly double _minValue, _maxValue;

public SelfAdaptiveChromosome(int length, double minValue = double.MinValue, double maxValue = double.MaxValue, double initMutationProvVal = 0.05)
: base(length)
{
_length = length;
_minValue = minValue;
_maxValue = maxValue;
_initMutationProvVal = initMutationProvVal;
_mutationProbabilities = new Dictionary<int, double>();

var random = RandomizationProvider.Current;
for (int i = 0; i < length; i++)
{
var g = new Gene(random.GetDouble(minValue, maxValue));
base.ReplaceGene(i, g);
}
}

public double GetMutationProbability(int index)
{
double d;
if (!_mutationProbabilities.TryGetValue(index, out d))
return _initMutationProvVal;
return d;
}

public void SetMutationProbability(int index, double prov)
{
if(prov != _initMutationProvVal)
_mutationProbabilities[index] = prov;
}

public override IChromosome Clone()
{
SelfAdaptiveChromosome c = (SelfAdaptiveChromosome)base.Clone();
c._mutationProbabilities = _mutationProbabilities.ToDictionary(r => r.Key, r => r.Value);
return c;
}


public override IChromosome CreateNew()
{
var e = new SelfAdaptiveChromosome(_length, _minValue, _maxValue, _initMutationProvVal);
return e;
}

public override Gene GenerateGene(int geneIndex)
{
var random = RandomizationProvider.Current;
double value = random.GetDouble(_minValue, _maxValue);
var g = new Gene(value);
base.ReplaceGene(geneIndex, g);
return new Gene(value);
}
}
}
58 changes: 58 additions & 0 deletions src/GeneticSharp.Domain/Crossovers/SelfAdaptiveCrossover.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using GeneticSharp;

namespace GeneticSharp
{
[DisplayName("Self Adaptive Crossover")]
public class SelfAdaptiveCrossover : CrossoverBase
{
public SelfAdaptiveCrossover() : base(2, 2) { }

protected override IList<IChromosome> PerformCross(IList<IChromosome> parents)
{
var parent1 = parents[0] as SelfAdaptiveChromosome;
var parent2 = parents[1] as SelfAdaptiveChromosome;

if (parent1 == null || parent2 == null)
{
throw new ArgumentException("Both parents must be of type SelfAdaptiveChromosome.");
}

IList<IChromosome> ret = UniformCrossover(parent1, parent2);
return ret;
}

private IList<IChromosome> UniformCrossover(SelfAdaptiveChromosome parent1, SelfAdaptiveChromosome parent2)
{
int length = parent1.Length;


SelfAdaptiveChromosome offspring1 = (SelfAdaptiveChromosome)parent1.Clone();
SelfAdaptiveChromosome offspring2 = (SelfAdaptiveChromosome)parent2.Clone();

for (int i = 0; i < length; i++)
{
if (RandomizationProvider.Current.GetDouble() < 0.5)
{
var v = offspring1.GetMutationProbability(i);
offspring1.SetMutationProbability(i,offspring2.GetMutationProbability(i));
offspring2.SetMutationProbability(i, v);
}


if (RandomizationProvider.Current.GetDouble() < 0.5)
{
var g = offspring1.GetGene(i);
offspring1.ReplaceGene(i, offspring2.GetGene(i));
offspring2.ReplaceGene(i, g);
}

}

return new List<IChromosome>() { offspring1, offspring2 };
}
}
}
Loading