Skip to content

Commit

Permalink
Merge branch 'feature/issue-62-add-ability-set-prgn-initial-seed' int…
Browse files Browse the repository at this point in the history
…o develop
  • Loading branch information
giacomelli committed Sep 10, 2022
2 parents 77fa88a + 442983f commit da02f63
Show file tree
Hide file tree
Showing 9 changed files with 98 additions and 65 deletions.
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
}
}
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}");
}
}
}
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));
}
}
}
}

22 changes: 18 additions & 4 deletions src/GeneticSharp.Domain/Randomizations/BasicRandomization.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,13 @@ public class BasicRandomization : RandomizationBase
{
private static readonly Random _globalRandom = new Random();
private static readonly object _globalLock = new object();
private static int? _seed;

/// <summary>
/// Random number generator
/// </summary>
private static readonly ThreadLocal<Random> s_threadRandom = new ThreadLocal<Random>(NewRandom);

private static ThreadLocal<Random> _threadRandom = new ThreadLocal<Random>(NewRandom);
/// <summary>
/// Creates a new instance of Random. The seed is derived
/// from a global (static) instance of Random, rather
Expand All @@ -28,15 +29,28 @@ private static Random NewRandom()
{
lock (_globalLock)
{
return new Random(_globalRandom.Next());
return new Random(_seed ?? _globalRandom.Next());
}
}

/// <summary>
/// Returns an instance of Random which can be used freely
/// within the current thread.
/// </summary>
private static Random Instance { get { return s_threadRandom.Value; } }
private static Random Instance { get { return _threadRandom.Value; } }

/// <summary>
/// Resets the pseudorandom number generator (System.Random) initial seed.
/// </summary>
/// <param name="seed">The seed. Use null to reset to default one.</param>
/// <remarks>
/// Can be useful on situation where you need to generate the same result with the same parameter.
/// </remarks>
public static void ResetSeed(int? seed)
{
_seed = seed;
_threadRandom = new ThreadLocal<Random>(NewRandom);
}

/// <summary>
/// Gets an integer value between minimum value (inclusive) and maximum value (exclusive).
Expand Down
18 changes: 16 additions & 2 deletions src/GeneticSharp.Domain/Randomizations/FastRandomRandomization.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,12 @@ public class FastRandomRandomization : RandomizationBase
{
private static readonly FastRandom _globalRandom = new FastRandom(DateTime.Now.Millisecond);
private static readonly object _globalLock = new object();
private static int? _seed;

/// <summary>
/// Random number generator
/// </summary>
private static readonly ThreadLocal<FastRandom> _threadRandom = new ThreadLocal<FastRandom>(NewRandom);
private static ThreadLocal<FastRandom> _threadRandom = new ThreadLocal<FastRandom>(NewRandom);

/// <summary>
/// Creates a new instance of FastRandom. The seed is derived
Expand All @@ -27,7 +28,7 @@ private static FastRandom NewRandom()
{
lock (_globalLock)
{
return new FastRandom(_globalRandom.Next(0, int.MaxValue));
return new FastRandom(_seed ?? _globalRandom.Next(0, int.MaxValue));
}
}

Expand All @@ -37,6 +38,19 @@ private static FastRandom NewRandom()
/// </summary>
private static FastRandom Instance { get { return _threadRandom.Value; } }

/// <summary>
/// Resets the pseudorandom number generator (SharpNeatLib.Maths.FastRandom) initial seed.
/// </summary>
/// <param name="seed">The seed. Use null to reset to default one.</param>
/// <remarks>
/// Can be useful on situation where you need to generate the same result with the same parameter.
/// </remarks>
public static void ResetSeed(int? seed)
{
_seed = seed;
_threadRandom = new ThreadLocal<FastRandom>(NewRandom);
}

/// <summary>
/// Gets an integer value between minimum value (inclusive) and maximum value (exclusive).
/// </summary>
Expand Down
6 changes: 2 additions & 4 deletions src/GeneticSharp.Domain/Randomizations/RandomizationBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@ namespace GeneticSharp
/// Base class for randomization.
/// </summary>
public abstract class RandomizationBase : IRandomization
{
#region Methods
{
/// <summary>
/// Gets an integer value between minimum value (inclusive) and maximum value (exclusive).
/// </summary>
Expand Down Expand Up @@ -103,7 +102,6 @@ public float GetFloat(float min, float max)
public virtual double GetDouble(double min, double max)
{
return min + ((max - min) * GetDouble());
}
#endregion
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,18 @@ namespace GeneticSharp
/// </summary>
public static class RandomizationProvider
{
#region Constructors
/// <summary>
/// Initializes static members of the <see cref="RandomizationProvider"/> class.
/// </summary>
static RandomizationProvider()
{
Current = new FastRandomRandomization();
}
#endregion

#region Properties
/// <summary>
/// Gets or sets the current IRandomization implementation.
/// </summary>
/// <value>The current.</value>
public static IRandomization Current { get; set; }
#endregion
}
}
50 changes: 0 additions & 50 deletions src/GeneticSharp.Domain/Randomizations/Randomizations.cd

This file was deleted.

0 comments on commit da02f63

Please sign in to comment.