Skip to content

Commit

Permalink
Merge branch 'release/3.1.2'
Browse files Browse the repository at this point in the history
  • Loading branch information
giacomelli committed Sep 10, 2022
2 parents a3e29ab + 6e2da87 commit b91cd50
Show file tree
Hide file tree
Showing 40 changed files with 525 additions and 200 deletions.
3 changes: 3 additions & 0 deletions .github/CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
## How to contribute to GeneticSharp
The idea behind GeneticSharp is to provide the basic and classic components that allow any programmer to quickly create a genetic algorithm using the .NET platform. Therefore, most of the basics and classic operators (crossovers, mutations, selections, reinsertions, and terminations) are implemented on it.

Having said that is not the goal of GeneticSharp to implement or provide all the possible ways to use a genetic algorithm, so, any PR that is not related to new operators, performance improvements, or bug fixing has a great chance to be rejected, but, feel free to read the contributing guidelines below and give a try.

### Did you find a bug?

Expand Down
3 changes: 3 additions & 0 deletions .github/ISSUE_TEMPLATE/bug_report.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ Steps to reproduce the behavior:
**Expected behavior**
A clear and concise description of what you expected to happen.

**Sample code**
Provide a sample code exposing the bug.

**Screenshots**
If applicable, add screenshots to help explain your problem.

Expand Down
3 changes: 3 additions & 0 deletions .github/ISSUE_TEMPLATE/question.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,6 @@ Did you search for your answer at GeneticSharp's Stack Overflow [tag](https://st

**Ask a question**
If you did not find your answer at wiki and Stack Overflow tag, please, describe your question.

** Sample code **
Provide a sample code of what you have tried so far.
2 changes: 1 addition & 1 deletion appveyor.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
version: 3.0.{build}
version: 3.1.2.{build}
os: Visual Studio 2022
configuration: Release
environment:
Expand Down
2 changes: 1 addition & 1 deletion buildLibrariesNuget.cmd
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
SET PACKAGE_VERSION="3.0.0"
SET PACKAGE_VERSION="3.1.2"

mkdir .\src\nuget

Expand Down
2 changes: 1 addition & 1 deletion buildTemplatesNuget.cmd
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
SET PACKAGE_VERSION=3.0.0
SET PACKAGE_VERSION=3.1.2

cd .\src\Templates

Expand Down
19 changes: 19 additions & 0 deletions src/GeneticSharp.Benchmarks/RandomizationsBenchmark.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using BenchmarkDotNet.Attributes;
using System.Threading.Tasks;

namespace GeneticSharp.Benchmarks
{
Expand Down Expand Up @@ -53,6 +54,15 @@ public void Basic_GetUniqueInts()
{
_basic.GetUniqueInts(_arrayLength, _min, _max);
}

[Benchmark]
public void Basic_GetInt_Threads()
{
Parallel.For(0, 100, i =>
{
_basic.GetInt(_min, _max);
});
}
#endregion

#region FastRandom
Expand Down Expand Up @@ -97,6 +107,15 @@ public void FastRandom_GetUniqueInts()
{
_fastRandom.GetUniqueInts(_arrayLength, _min, _max);
}

[Benchmark]
public void FastRandom_GetInt_Threads()
{
Parallel.For(0, 100, i =>
{
_fastRandom.GetInt(_min, _max);
});
}
#endregion
}
}
16 changes: 16 additions & 0 deletions src/GeneticSharp.Benchmarks/SelectionsBenchmark.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,5 +54,21 @@ public ISelection Tournament()
target.SelectChromosomes(_chromosomesNumber, _generation);
return target;
}

[Benchmark]
public ISelection Rank()
{
var target = new RankSelection();
target.SelectChromosomes(_chromosomesNumber, _generation);
return target;
}

[Benchmark]
public ISelection Truncation()
{
var target = new TruncationSelection();
target.SelectChromosomes(_chromosomesNumber, _generation);
return target;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -125,22 +125,6 @@ public void ReplaceGenes_NullGenes_Exception()
});
}

[Test]
public void ReplaceGenes_GenesExceedChromosomeLength_Exception()
{
var target = Substitute.For<ChromosomeBase>(3);

Assert.Catch<ArgumentException>(() =>
{
target.ReplaceGenes(0, new Gene[] { new Gene(1), new Gene(2), new Gene(3), new Gene(4) });
}, "The number of genes to be replaced is greater than available space, there is 3 genes between the index 0 and the end of chromosome, but there is 4 genes to be replaced.");

Assert.Catch<ArgumentException>(() =>
{
target.ReplaceGenes(1, new Gene[] { new Gene(1), new Gene(2), new Gene(3) });
}, "The number of genes to be replaced is greater than available space, there is 2 genes between the index 1 and the end of chromosome, but there is 3 genes to be replaced.");
}

[Test]
public void ReplaceGenes_ValidIndex_Replaced()
{
Expand Down
4 changes: 3 additions & 1 deletion src/GeneticSharp.Domain.UnitTests/FlowAssert.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ public static void IsAtLeastOneOk(params Action[] flows)
public static void IsAtLeastOneAttemptOk(int maxAttempts, Action flow)
{
bool ok = false;
string failedMessage = null;

for(int i = 0; i < maxAttempts; i++)
{
Expand All @@ -63,10 +64,11 @@ public static void IsAtLeastOneAttemptOk(int maxAttempts, Action flow)
Debug.WriteLine(ex.Message);
Debug.WriteLine(ex.StackTrace);
ok = false;
failedMessage = ex.Message;
}
}

Assert.IsTrue(ok);
Assert.IsTrue(ok, $"All {maxAttempts} attempts failed\n\n{failedMessage}");
}
}
}
11 changes: 10 additions & 1 deletion src/GeneticSharp.Domain.UnitTests/GeneticAlgorithmTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System.Threading.Tasks;
using NUnit.Framework;
using NSubstitute;
using System.Security.Cryptography;

namespace GeneticSharp.Domain.UnitTests
{
Expand Down Expand Up @@ -536,7 +537,15 @@ public void Start_UsingAllConfigurationCombinationsAvailable_AllRun()
target.Termination = new GenerationNumberTermination(25);
target.CrossoverProbability = reinsertion.CanExpand ? 0.75f : 1f;

target.Start();
try
{
target.Start();
}
catch(Exception ex)
{
throw new Exception($"GA start failed using selection:{s}, crossover:{c}, mutation:{m} and reinsertion:{r}. Error: {ex.Message}", ex);
}

Assert.AreEqual(25, target.Population.Generations.Count);
}
}
Expand Down
32 changes: 32 additions & 0 deletions src/GeneticSharp.Domain.UnitTests/Populations/PopulationTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,38 @@ public void EndCurrentGeneration_BestChromosomeChanged_ChangeEventRaise()

Assert.IsTrue(eventRaise);
}

/// <summary>
/// https://github.com/giacomelli/GeneticSharp/issues/70
/// </summary>
[Test]
public void EndCurrentGeneration_Issue70_Solved()
{
var target = new Population(100, 100, new ChromosomeStub());

var eventRaise = false;
IChromosome lastChromosome = null;

target.BestChromosomeChanged += (e, a) =>
{
eventRaise = true;

if (lastChromosome != null && lastChromosome.Fitness == target.BestChromosome.Fitness)
Assert.Fail("BestChromosomeChanged should only be raised if fitness is different.");

lastChromosome = target.BestChromosome;
};

target.CreateInitialGeneration();
target.CurrentGeneration.Chromosomes.Each(c => c.Fitness = 0);
target.CurrentGeneration.Chromosomes[1].Fitness = 1;
target.EndCurrentGeneration();

target.CurrentGeneration.Chromosomes[0].Fitness = 1;
target.EndCurrentGeneration();

Assert.IsTrue(eventRaise);
}
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,26 @@ public void GetUniqueInts_Length_ArrayWithUniqueInts()
Assert.IsTrue(actual[0] >= 2);
});
}

[Test]
public void ResetSeed_GetInt_SameResults()
{
BasicRandomization.ResetSeed(1);
var target = new BasicRandomization();
var actual = new int[10];

for (int i = 0; i < actual.Length; i++)
{
actual[i] = target.GetInt(int.MinValue, int.MaxValue);
}

BasicRandomization.ResetSeed(1);

for (int i = 0; i < actual.Length; i++)
{
Assert.AreEqual(actual[i], target.GetInt(int.MinValue, int.MaxValue));
}
}
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,26 @@ public void GetInt_NegativeValues_Negative()
var actual = target.GetInt(-10, -9);
Assert.AreEqual(-10, actual);
}

[Test]
public void ResetSeed_GetInt_SameResults()
{
FastRandomRandomization.ResetSeed(1);
var target = new FastRandomRandomization();
var actual = new int[10];

for (int i = 0; i < actual.Length; i++)
{
actual[i] = target.GetInt(int.MinValue, int.MaxValue);
}

FastRandomRandomization.ResetSeed(1);

for (int i = 0; i < actual.Length; i++)
{
Assert.AreEqual(actual[i], target.GetInt(int.MinValue, int.MaxValue));
}
}
}
}

59 changes: 51 additions & 8 deletions src/GeneticSharp.Domain.UnitTests/Selections/EliteSelectionTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@
using System.Collections.Generic;
using NUnit.Framework;
using NSubstitute;
using System.Linq;

namespace GeneticSharp.Domain.UnitTests.Selections
{
[TestFixture()]
[Category("Selections")]
public class EliteSelectionTest
{
[Test()]
[Test]
public void SelectChromosomes_InvalidNumber_Exception()
{
var target = new EliteSelection();
Expand All @@ -30,7 +31,7 @@ public void SelectChromosomes_InvalidNumber_Exception()
}, "The number of selected chromosomes should be at least 2.");
}

[Test()]
[Test]
public void SelectChromosomes_NullGeneration_Exception()
{
var target = new EliteSelection();
Expand All @@ -43,7 +44,7 @@ public void SelectChromosomes_NullGeneration_Exception()
Assert.AreEqual("generation", actual.ParamName);
}

[Test()]
[Test]
public void SelectChromosomes_Generation_ChromosomesSelected()
{
var target = new EliteSelection();
Expand All @@ -59,22 +60,64 @@ public void SelectChromosomes_Generation_ChromosomesSelected()
var c4 = Substitute.ForPartsOf<ChromosomeBase>(2);
c4.Fitness = 0.7;

var generation = new Generation(1, new List<IChromosome>() {
var generation1 = new Generation(1, new List<IChromosome>() {
c1, c2, c3
});

var generation2 = new Generation(1, new List<IChromosome>() {
c1, c2, c3, c4
});


var actual = target.SelectChromosomes(2, generation);
var actual = target.SelectChromosomes(2, generation1);
Assert.AreEqual(2, actual.Count);
Assert.AreEqual(0.7, actual[0].Fitness);
Assert.AreEqual(0.5, actual[1].Fitness);
Assert.AreEqual(0.5, actual[0].Fitness);
Assert.AreEqual(0.1, actual[1].Fitness);

actual = target.SelectChromosomes(3, generation);
actual = target.SelectChromosomes(3, generation2);
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>
/// https://github.com/giacomelli/GeneticSharp/issues/72
/// </summary>
[Test]
public void SelectChromosomes_Issue72_Solved()
{
var target = new EliteSelection();
var chromosomes = new IChromosome[10];

for (int i = 0; i < chromosomes.Length; i++)
{
var c = Substitute.ForPartsOf<ChromosomeBase>(2);
c.Fitness = i;
chromosomes[i] = c;
}

var generation3 = new Generation(3, chromosomes.Take(4).ToList());
var generation2 = new Generation(2, chromosomes.Skip(4).Take(3).ToList());
var generation1 = new Generation(1, chromosomes.Skip(7).Take(3).ToList());


var actual = target.SelectChromosomes(2, generation1);
Assert.AreEqual(2, actual.Count);
Assert.AreEqual(9, actual[0].Fitness);
Assert.AreEqual(8, actual[1].Fitness);

actual = target.SelectChromosomes(3, generation2);
Assert.AreEqual(3, actual.Count);
Assert.AreEqual(9, actual[0].Fitness);
Assert.AreEqual(6, actual[1].Fitness);
Assert.AreEqual(5, actual[2].Fitness);

actual = target.SelectChromosomes(2, generation3);
Assert.AreEqual(2, actual.Count);
Assert.AreEqual(9, actual[0].Fitness);
Assert.AreEqual(3, actual[1].Fitness);
}
}
}

Loading

0 comments on commit b91cd50

Please sign in to comment.