protected override DecisionVector GetNewDecisionVector() { if (InitialVerticesStillUnevaluated.Count > 0) { // Still creating the first simplex return(InitialVerticesStillUnevaluated.First()); } else { //We're into the optimisation if (VerticesNotEvaluated.Count == 0) { try { //Create new individual var newDv = OperationsManager.PerformOperation((Simplex)Population, CurrentOperation); VerticesNotEvaluated.Add(newDv); return(newDv); } catch (ArgumentOutOfRangeException) { // We have gone 'out of bounds' - this is it for this optimisation. return(DecisionVector.CreateForEmpty()); } } else { //Provide the same individual back again return(VerticesNotEvaluated.First()); } } }
/// <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 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)); }
/// <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 static void ZDT3_Function(DecisionVector v, double[] obj, int trial) //range [0,1], optimal range x1=[0,1],xi=0 for other i { int n = 30; double[] var = new double[n]; if (trial == 0) { for (int j = 0; j < n; j++) { var[j] = v.CurrentVector[j]; obj[1] += var[j]; } obj[1] = 1 + 9 * (obj[1] - var[0]) / (n - 1); obj[1] = obj[1] * (1 - Math.Sqrt(var[0] / obj[1]) - var[0] / obj[1] * Math.Sin(10 * Math.PI * var[0])); obj[0] = var[0]; } if (trial == 1) { for (int j = 0; j < n; j++) { var[j] = v.TrialVector[j]; obj[1] += var[j]; } obj[1] = 1 + 9 * (obj[1] - var[0]) / (n - 1); obj[1] = obj[1] * (1 - Math.Sqrt(var[0] / obj[1]) - var[0] / obj[1] * Math.Sin(10 * Math.PI * var[0])); obj[0] = var[0]; } }
public static void ZDT6_Function(DecisionVector V, double[] obj, int trial) //range [0,1], optimal range x1=[0,1],xi=0 for other i { int n = 10; double[] var = new double[n]; if (trial == 0) { for (int j = 0; j < n; j++) { var[j] = V.CurrentVector[j]; obj[1] += var[j]; } obj[1] = 1 + 9 * Math.Pow((obj[1] - var[0]) / (n - 1), 0.25); obj[0] = 1 - Math.Exp(-4 * var[0]) * Math.Pow(Math.Sin(6 * Math.PI * var[0]), 6); obj[1] = obj[1] * (1 - Math.Pow(obj[0] / obj[1], 2)); } if (trial == 1) { for (int j = 0; j < n; j++) { var[j] = V.TrialVector[j]; obj[1] += var[j]; } obj[1] = 1 + 9 * Math.Pow((obj[1] - var[0]) / (n - 1), 0.25); obj[0] = 1 - Math.Exp(-4 * var[0]) * Math.Pow(Math.Sin(6 * Math.PI * var[0]), 6); obj[1] = obj[1] * (1 - Math.Pow(obj[0] / obj[1], 2)); } }
public static void ZDT4_Function(DecisionVector V, double[] obj, int trial) //range [0,1], optimal range x1=[0,1],xi=0 for other i { int n = 10; double[] var = new double[n]; if (trial == 0) { var[0] = V.CurrentVector[0]; for (int j = 1; j < n; j++) { var[j] = V.CurrentVector[j]; obj[1] += (Math.Pow(var[j], 2) - 10 * Math.Cos(4 * Math.PI * var[j])); } obj[1] = 1 + 10 * (n - 1) + obj[1]; obj[1] = obj[1] * (1 - Math.Sqrt(var[0] / obj[1])); obj[0] = var[0]; } if (trial == 1) { var[0] = V.TrialVector[0]; for (int j = 1; j < n; j++) { var[j] = V.TrialVector[j]; obj[1] += (Math.Pow(var[j], 2) - 10 * Math.Cos(4 * Math.PI * var[j])); } obj[1] = 1 + 10 * (n - 1) + obj[1]; obj[1] = obj[1] * (1 - Math.Sqrt(var[0] / obj[1])); obj[0] = var[0]; } }
public static void IBeamFunction(DecisionVector v, double[] obj, int trial) { double[] x = new double[4]; if (trial == 0) { x[0] = v.CurrentVector[0]; x[1] = v.CurrentVector[1]; x[2] = v.CurrentVector[2]; x[3] = v.CurrentVector[3]; v.inFeasible = 0; obj[0] = 2 * x[1] * x[3] + x[2] * (x[0] - 2 * x[3]); obj[1] = 60000 / (x[2] * Math.Pow(x[0] - 2 * x[3], 3) + 2 * x[1] * x[3] * (4 * Math.Pow(x[3], 2) + 3 * x[0] * (x[0] - 2 * x[3]))); if ((16 - obj[1] * 0.3 - (15000 * x[1]) / (Math.Pow(x[0] - 2 * x[3], 3) * Math.Pow(x[2], 3) + 2 * x[3] * Math.Pow(x[1], 3))) < 0) { obj[2]++; } v.inFeasible = (int)obj[2]; } if (trial == 1) { x[0] = v.TrialVector[0]; x[1] = v.TrialVector[1]; x[2] = v.TrialVector[2]; x[3] = v.TrialVector[3]; v.inFeasible = 0; obj[0] = 2 * x[1] * x[3] + x[2] * (x[0] - 2 * x[3]); obj[1] = 60000 / (x[2] * Math.Pow(x[0] - 2 * x[3], 3) + 2 * x[1] * x[3] * (4 * Math.Pow(x[3], 2) + 3 * x[0] * (x[0] - 2 * x[3]))); if ((16 - obj[1] * 0.3 - (15000 * x[1]) / (Math.Pow(x[0] - 2 * x[3], 3) * Math.Pow(x[2], 3) + 2 * x[3] * Math.Pow(x[1], 3))) < 0) { obj[2]++; } v.inFeasible = (int)obj[2]; } }
/// <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 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)); }
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)); }
public static void KUR_Function(DecisionVector v, double[] obj, int trial) // range [-10e2,10e2], optimal range [0,2] { double[] var = new double[3]; if (trial == 0) { for (int i = 0; i < v.Dimension; i++) { var[i] = v.CurrentVector[i]; } for (int j = 0; j < 3; j++) { if (j < 2) { obj[0] += -10 * Math.Exp(-0.2 * Math.Sqrt(Math.Pow(var[j], 2) + Math.Pow(var[j + 1], 2))); } obj[1] += Math.Pow(Math.Abs(var[j]), 0.8) + 5 * Math.Sin(Math.Pow(var[j], 3)); } } if (trial == 1) { for (int i = 0; i < v.Dimension; i++) { var[i] = v.TrialVector[i]; } for (int j = 0; j < 3; j++) { if (j < 2) { obj[0] += -10 * Math.Exp(-0.2 * Math.Sqrt(Math.Pow(var[j], 2) + Math.Pow(var[j + 1], 2))); } obj[1] += Math.Pow(Math.Abs(var[j]), 0.8) + 5 * Math.Sin(Math.Pow(var[j], 3)); } } }
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 MutationRandomSwapTests() { testDv = DecisionVector.CreateFromArray( DecisionSpace.CreateForUniformDoubleArray(8, double.MinValue, double.MaxValue), new double[8] { 7, 6, 5, 4, 3, 2, 1, 0 }); }
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 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 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 MutationReplaceWithRandomNumberTests() { testDv = DecisionVector.CreateFromArray( DecisionSpace.CreateForUniformDoubleArray(8, 0, 10), new double[8] { 7, 6, 5, 4, 3, 2, 1, 0 }); }
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 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 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 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); }
/// <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())) { }
/// <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 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 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); }
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); }