/// <summary> /// Gets a new Decision Vector, based on an average of the matching elements from each parent. /// </summary> /// <param name="parents">A list of parent <see cref="DecisionVector"/>s.</param> /// <returns>A new <see cref="DecisionVector"/>.</returns> /// <exception cref="ArgumentOutOfRangeException"> /// Thrown if: /// - there are less than two parents; or /// - the parents have different length or zero length decision vectors; or /// - any of the parents have non-continuous Decision Vector elements. /// </exception> public DecisionVector Operate(params DecisionVector[] parents) { if (parents.Length < 2) { throw new ArgumentOutOfRangeException(nameof(parents), "There must be at least two parents."); } if (parents.Any(p => p.GetContinuousElements().Count == 0)) { throw new ArgumentOutOfRangeException(nameof(parents), "Parents must have non-zero length decision vectors."); } if (parents.Any(p => p.GetContinuousElements().Count != parents.First().Count)) { throw new ArgumentOutOfRangeException(nameof(parents), "Parents must have the same length and fully continuous decision vectors."); } return(DecisionVector.CreateFromArray( parents.First().GetDecisionSpace(), parents .Select(p => p.Select(v => (double)v)) .Aggregate((p1, p2) => p1.Select((v, i) => v + p2.ElementAt(i))) .Select(v => v / parents.Length))); }
/// <summary> /// Gets a new Decision Vector, based on selecting each element from one parent or the other. /// This selection can be biased towards the first parent (if <see cref="crossoverBias"/> is greater than 0.5) /// or towards the second parent (if <see cref="crossoverBias"/> is less than 0.5). /// </summary> /// <remarks> /// The two decision vectors can be different lengths. /// If so, for each element that only exists in the longer parent, if the shorter parent is selected, /// that element is removed. /// </remarks> /// <param name="parents">Two <see cref="DecisionVector"/>s to use as a parents.</param> /// <returns>A new <see cref="DecisionVector"/>.</returns> public DecisionVector Operate(params DecisionVector[] parents) { var firstParent = parents[0]; var secondParent = parents[1]; var numDims = Math.Max(firstParent.Count, secondParent.Count); var dims = new List <IVariable>(); var newVector = new List <object>(); for (var d = 0; d < numDims; d++) { var parentToUse = rngManager.Rng.NextDouble() < crossoverBias ? firstParent : secondParent; if (parentToUse.Count < (d + 1)) { continue; } dims.Add(parentToUse.GetDecisionSpace().ElementAt(d)); newVector.Add(parentToUse.ElementAt(d)); } return(DecisionVector.CreateFromArray(new DecisionSpace(dims), newVector)); }
/// <summary> /// Gets a new Decision Vector with elements which have potentially been mutated. /// Uses <see cref="IVariable"/> to wrap the added number, ensuring a valid Decision Vector is always created. /// </summary> /// <param name="decisionVector">The existing Decision Vector.</param> /// <returns>A new Decision Vector.</returns> public DecisionVector Operate(DecisionVector decisionVector) { var locationsToMutate = rngManager.GetLocations( decisionVector.Count, maximumNumberOfMutations, true, mutationProbability); var newDv = decisionVector.Select(i => (double)i).ToArray(); var newDs = decisionVector.GetDecisionSpace(); foreach (var location in locationsToMutate) { var mutation = rngManager.Rng.Next( minimum, includeZero ? maximum : maximum - 1); if (!includeZero) { if (mutation >= 0) { mutation += 1; } } newDv[location] = Convert.ToDouble(newDs.ElementAt(location).AddOrWrap(newDv[location], mutation)); } return(DecisionVector.CreateFromArray(newDs, newDv)); }
public void ThreeCitiesInATriangle_CorrectlyCalculatesDistances(params double[][] cityLocations) { var tsp = new TravellingSalesman("Test Triangle", cityLocations, DecisionVector.CreateFromArray(DecisionSpace.CreateForUniformIntArray(4, 0, 2), new[] { 0, 1, 2, 0 })); Assert.Equal(12.0, tsp.Evaluate(tsp.GetGlobalOptimum()).ElementAt(0)); }
public static List <Individual> CreateNewIndividualsFromArray(double[][] testValues) { var ds = DecisionSpace.CreateForUniformDoubleArray(testValues.ElementAt(0).Length, double.MinValue, double.MaxValue); var dvs = testValues.Select(v => DecisionVector.CreateFromArray(ds, v)); return(dvs.Select(v => new Individual(v)).ToList()); }
/// <summary> /// Gets a new Decision Vector where elements have potentially been mutated. /// Uses <see cref="IVariable"/> to implement the random number generation, so only valid individuals can be created. /// </summary> /// <param name="decisionVector">The existing Decision Vector.</param> /// <returns>A new <see cref="DecisionVector"/>.</returns> /// <exception cref="ArgumentException">Thrown when Decision Vector is zero length.</exception> public DecisionVector Operate(DecisionVector decisionVector) { if (decisionVector.Count == 0) { throw new ArgumentException("Decision Vector must not be empty.", nameof(decisionVector)); } var locationsToMutate = rngManager.GetLocations( decisionVector.Count, maximumNumberOfMutations, true, mutationProbability); var newDv = new object[decisionVector.Count]; var newDs = decisionVector.GetDecisionSpace(); for (var i = 0; i < decisionVector.Count; i++) { // Variable may be mutated multiple times. var numTimesToMutate = locationsToMutate.Count(l => l == i); if (numTimesToMutate == 0) { newDv[i] = decisionVector.ElementAt(i); } else { for (var j = 0; j < numTimesToMutate; j++) { newDv[i] = newDs.ElementAt(i).GetNextRandom(rngManager.Rng); } } } return(DecisionVector.CreateFromArray(newDs, newDv)); }
/// <summary> /// Gets a new Decision Vector whose elements have potentially been mutated. /// </summary> /// <param name="decisionVector">The existing Decision Vector.</param> /// <returns>A new Decision Vector.</returns> /// <exception cref="ArgumentException">Thrown when the Decision Vector has less than 2 elements.</exception> public DecisionVector Operate(DecisionVector decisionVector) { if (decisionVector.Count < 2) { throw new ArgumentException("Decision Vector must more than one element.", nameof(decisionVector)); } if (rngManager.Rng.NextDouble() >= mutationProbability) { return(decisionVector); } var locationsToSwap = rngManager.GetLocations( decisionVector.Count, 2, false, 1); // New vector - swap elements var vector = decisionVector.ToList(); var firstItem = vector.ElementAt(locationsToSwap.ElementAt(0)); var secondItem = vector.ElementAt(locationsToSwap.ElementAt(1)); vector.RemoveAt(locationsToSwap.ElementAt(0)); vector.Insert(locationsToSwap.ElementAt(0), secondItem); vector.RemoveAt(locationsToSwap.ElementAt(1)); vector.Insert(locationsToSwap.ElementAt(1), firstItem); // Assumption, we are swapping the values of the items, not the actual dimensions. return(DecisionVector.CreateFromArray( decisionVector.GetDecisionSpace(), vector)); }
/// <summary> /// Gets a new Decision Vector, based on simulating the operation of a single-point binary crossover. /// </summary> /// <param name="parents">Two <see cref="DecisionVector"/>s to use as a parents.</param> /// <returns>A new <see cref="DecisionVector"/>.</returns> public DecisionVector Operate(params DecisionVector[] parents) { if (parents[0].GetContinuousElements().Count == 0) { throw new ArgumentOutOfRangeException(nameof(parents), "Parents must have non-zero length continuous Decision Vector."); } if (parents[1].GetContinuousElements().Count == 0) { throw new ArgumentOutOfRangeException(nameof(parents), "Parents must have non-zero length continuous Decision Vector."); } var firstParent = Vector <double> .Build.DenseOfEnumerable( parents[0].GetContinuousElements().Select(d => (double)d)); var secondParent = Vector <double> .Build.DenseOfEnumerable( parents[1].GetContinuousElements().Select(d => (double)d)); // Multiply by -1 randomly to ensure either possibility is equally possible. var multiplier = rngManager.Rng.NextBoolean() ? -1 : 1; // Get beta value var beta = getBetaFromU(rngManager.Rng.NextDouble()); // Create child var child = 0.5 * ((1 - beta * multiplier) * firstParent + (1 + beta * multiplier) * secondParent); return(DecisionVector.CreateFromArray(parents[0].GetDecisionSpace(), child.ToArray())); }
public void TwoEqualVectors_WithSameSpace_AreEqual() { var values2 = exampleContinuousVector.ToArray(); var dv1 = DecisionVector.CreateFromArray(continuousSpace, exampleContinuousVector); var dv2 = DecisionVector.CreateFromArray(continuousSpace, values2); Assert.True(dv1.Equals(dv2)); }
public void TwoDifferentVectors_WithSameSpace_AreNotEqual() { var values2 = exampleContinuousVector.Select(i => i - 1).ToArray(); var dv1 = DecisionVector.CreateFromArray(continuousSpace, exampleContinuousVector); var dv2 = DecisionVector.CreateFromArray(continuousSpace, values2); Assert.False(dv1.Equals(dv2)); }
public void TwoEqualVectors_WithDifferentSpace_AreNotEqual() { var space2 = ObjectCreators.GetDecisionSpace(Dims, MinValueContinuous - 1, MaxValueContinuous + 1); var dv1 = DecisionVector.CreateFromArray(continuousSpace, exampleContinuousVector); var dv2 = DecisionVector.CreateFromArray(space2, exampleContinuousVector); Assert.False(dv1.Equals(dv2)); }
private bool replaceHyperParametersFrom(IEnumerable <IVariable> decisionSpace, IEnumerable <object> values) { HyperParameters = DecisionVector.CreateFromArray( new DecisionSpace(decisionSpace), values); return(true); }
public void TwoDim_CorrectlyIdentifiesIllegalSolution() { var evaluator = new Ellipsoidal(2); var ds = DecisionSpace.CreateForUniformDoubleArray(2, double.MinValue, double.MaxValue); var legal = evaluator.GetLegality(DecisionVector.CreateFromArray(ds, new[] { 11.0, -12.0 })); Assert.False(legal); }
public void TwoDim_EvaluatesCorrectValues(double[] values) { var evaluator = new Rastrigin(2); var ds = evaluator.GetGlobalOptimum().GetDecisionSpace(); var result = evaluator.Evaluate(DecisionVector.CreateFromArray(ds, new[] { values[0], values[1] })); Assert.True(Math.Abs(values[2] - result.ElementAt(0)) < 0.001); }
public void CreateInitialVertices_WithStepSizeZero_Throws() { var initialVertex = DecisionVector.CreateFromArray( DecisionSpace.CreateForUniformDoubleArray(3, double.MinValue, double.MaxValue), Enumerable.Repeat(0.0, 3)); Assert.Throws <ArgumentOutOfRangeException>(() => Simplex.CreateInitialVertices(initialVertex, 0)); }
public MutationRandomSwapTests() { testDv = DecisionVector.CreateFromArray( DecisionSpace.CreateForUniformDoubleArray(8, double.MinValue, double.MaxValue), new double[8] { 7, 6, 5, 4, 3, 2, 1, 0 }); }
public void TwoDim_CorrectlyIdentifiesLegalSolution() { var evaluator = new Ellipsoidal(2); var ds = evaluator.GetGlobalOptimum().GetDecisionSpace(); var legal = evaluator.GetLegality(DecisionVector.CreateFromArray(ds, new[] { 1.0, 1.0 })); Assert.True(legal); }
public void TwoDim_EvaluatesCorrectValues(double[] values) { var evaluator = new Ellipsoidal(2); var ds = evaluator.GetGlobalOptimum().GetDecisionSpace(); var result = evaluator.Evaluate(DecisionVector.CreateFromArray(ds, new[] { values[0], values[1] })); Assert.Equal(values[2], result.ElementAt(0)); }
public MutationReplaceWithRandomNumberTests() { testDv = DecisionVector.CreateFromArray( DecisionSpace.CreateForUniformDoubleArray(8, 0, 10), new double[8] { 7, 6, 5, 4, 3, 2, 1, 0 }); }
/// <summary> /// Creates an evaluator for the Rosenbrock Function. /// Assumes unconstrained, even though normally checked on a [-5, 10] basis. /// Global optimum is at [1,1,1,...] /// </summary> /// <param name="numDims">Number of input dimensions</param> public Rosenbrock(int numDims) : base( "Rosenbrock Function", DecisionVector.CreateFromArray( DecisionSpace.CreateForUniformDoubleArray(numDims, double.MinValue, double.MaxValue, -5.0, 10.0), Enumerable.Repeat(1.0, numDims).ToArray())) { }
public void CorrectlyIdentifiesLegalSolution() { var evaluator = new Zdt3(); var ds = evaluator.GetOptimalParetoFront(1).ElementAt(0).GetDecisionSpace(); var legal = evaluator.GetLegality(DecisionVector.CreateFromArray(ds, ds.Select(d => d.GetNextRandom(new SystemRandomSource())))); Assert.True(legal); }
/// <summary> /// Creates an evaluator for Salomon's Function. /// Assumes unconstrained, even though normally checked on a +/-100 basis /// Global optimum is at [0,0,0,...] /// </summary> /// <param name="numDims">Number of input dimensions</param> public Salomon(int numDims) : base( "Salomon's Function", DecisionVector.CreateFromArray( DecisionSpace.CreateForUniformDoubleArray(numDims, double.MinValue, double.MaxValue, -100, 100), new double[numDims])) { }
/// <summary> /// Creates an evaluator for the Generalised Rastrigin Function. /// Assumes unconstrained, even though normally checked on a +/-5.12 basis /// Global optimum is at [0,0,0,...] /// </summary> /// <param name="numDims">Number of input dimensions</param> public Rastrigin(int numDims) : base( "Generalised Rastrigin Function", DecisionVector.CreateFromArray( DecisionSpace.CreateForUniformDoubleArray(numDims, double.MinValue, double.MaxValue, -5.12, 5.12), new double[numDims])) { }
/// <summary> /// Creates an evaluator for the Styblinski-Tang Function. /// Constrained on [-5, 5] /// Global optimum is at [-2.903534, -2.903534, -2.903534,...] /// </summary> /// <param name="numDims">Number of input dimensions</param> public StyblinskiTang(int numDims) : base( "Styblinski-Tang Function", DecisionVector.CreateFromArray( DecisionSpace.CreateForUniformDoubleArray(numDims, -5, 5, -4.5, 2.5), Enumerable.Repeat(-2.903534, numDims).ToArray())) { }
/// <summary> /// Creates an evaluator for the Schwefel Function. /// Constrained on [-500, 500] /// Global optimum is at [420.9687, 420.9687, 420.9687,...] /// </summary> /// <param name="numDims">Number of input dimensions</param> public Schwefel(int numDims) : base( "Schwefel Function", DecisionVector.CreateFromArray( DecisionSpace.CreateForUniformDoubleArray(numDims, -500.0, 500.0, -250, 475), Enumerable.Repeat(420.9687, numDims).ToArray())) { }
public void CorrectlyIdentifiesIllegalSolution() { var evaluator = new Zdt3(); var ds = DecisionSpace.CreateForUniformDoubleArray(30, -2, -1, -2, -1); var legal = evaluator.GetLegality(DecisionVector.CreateFromArray(ds, ds.Select(d => d.GetNextRandom(new SystemRandomSource())))); Assert.False(legal); }
/// <summary> /// Creates an evaluator for the Ellipsoidal Function. /// Constrained on [-10, 10] /// Global optimum is at [0,0,0,...] /// </summary> /// <param name="numDims">Number of input dimensions</param> public Ellipsoidal(int numDims) : base( "Ellipsoidal Function", DecisionVector.CreateFromArray( DecisionSpace.CreateForUniformDoubleArray(numDims, -10, 10, -5, 5), new double[numDims])) { }
public RandomNumberManagerTests() { testDv = DecisionVector.CreateFromArray( DecisionSpace.CreateForUniformIntArray(8, 0, 7), new int[8] { 7, 6, 5, 4, 3, 2, 1, 0 }); rngManager = new RandomNumberManager(new MersenneTwister(123456789)); }
public CrossoverSimulatedBinaryTests() { var decisionSpaceUniform = DecisionSpace.CreateForUniformDoubleArray( 4, double.MinValue, double.MaxValue); parent1 = DecisionVector.CreateFromArray( decisionSpaceUniform, new[] { 0.5, 1.5, 2.5, 3.5 }); parent2 = DecisionVector.CreateFromArray( decisionSpaceUniform, new[] { 4.5, 3.5, 2.5, 1.5 }); }
private void updateDecisionVector(bool add = true) { var elements = decisionVector.Select(d => (double)d).ToList(); elements[0] += add ? 0.01 : -0.01; var space = decisionVector.GetDecisionSpace(); decisionVector = DecisionVector.CreateFromArray( space, elements); }