protected AdditiveMove(AdditiveMove original, Cloner cloner) : base(original, cloner) { this.Dimension = original.Dimension; this.MoveDistance = original.MoveDistance; if (original.RealVector != null) this.RealVector = cloner.Clone(original.RealVector); }
public double[] CheckConstraints(RealVector r, int objectives) { if (r.Length < 10 * objectives) throw new Exception("The dimensionality of the problem(ProblemSize) must be larger than ten times the number of objectives "); double n = r.Length; double M = objectives; double ratio = n / M; double[] res = new double[objectives]; double[] constraints = new double[objectives]; for (int j = 0; j < objectives; j++) { double sum = 0; for (int i = (int)(j * ratio); i < (j + 1) + ratio; i++) { sum += r[i]; } sum /= (int)ratio; res[j] = sum; } for (int j = 0; j < M - 1; j++) { double d1 = res[objectives - 1] + 4 * res[j] - 1; constraints[j] = d1 < 0 ? -d1 : 0; } double min = Double.PositiveInfinity; for (int i = 0; i < res.Length - 1; i++) { for (int j = 0; j < i; j++) { double d2 = res[i] + res[j]; if (min < d2) min = d2; } } double d = 2 * res[objectives - 1] + min - 1; constraints[constraints.Length - 1] = d < 0 ? -d : 0; return constraints; }
/// <summary> /// Evaluates the test function for a specific <paramref name="point"/>. /// </summary> /// <param name="point">N-dimensional point for which the test function should be evaluated.</param> /// <returns>The result value of the Sum Squares function at the given point.</returns> public static double Apply(RealVector point) { double result = 0; for (int i = 0; i < point.Length; i++) { result += (i + 1) * point[i] * point[i]; } return result; }
public override double[] Evaluate(RealVector r, int objectives) { if (r.Length < objectives) { throw new ArgumentException("The dimensionality of the problem(ProblemSize) must be larger than or equal to the number of objectives"); } double[] res = new double[objectives]; //calculate g(Xm) double g = 0; for (int i = objectives; i < r.Length; i++) { g += Math.Pow(r[i], 0.1); } //phi definition Func<double, double> phi; phi = (double x) => { return Math.PI / (4 * (1 + g)) * (1 + 2 * g * x); }; //calculating f0...fM-1 for (int i = 0; i < objectives; i++) { double f = i == 0 ? 1 : (Math.Sin(phi(r[objectives - i - 1]) * Math.PI / 2)) * (1 + g); for (int j = 0; j < objectives - i - 1; j++) { f *= Math.Cos(phi(r[j]) * Math.PI / 2); } res[i] = f; } return res; }
protected override double G(RealVector y) { double sum = 0.0; for (int i = 1; i < y.Length; i++) { sum += HG(y[i]); } return 1 + 9 * Math.Pow(sum / (y.Length - 1), 0.25); }
/// <summary> /// Performs a breeder genetic algorithm manipulation on the given <paramref name="vector"/>. /// </summary> /// <param name="random">A random number generator.</param> /// <param name="vector">The real vector to manipulate.</param> /// <param name="bounds">The lower and upper bound (1st and 2nd column) of the positions in the vector. If there are less rows than dimensions, the rows are cycled.</param> /// <param name="searchIntervalFactor">The factor determining the size of the search interval.</param> public static void Apply(IRandom random, RealVector vector, DoubleMatrix bounds, DoubleValue searchIntervalFactor) { int length = vector.Length; double prob, value; do { value = Sigma(random); } while (value == 0); prob = 1.0 / (double)length; bool wasMutated = false; for (int i = 0; i < length; i++) { if (random.NextDouble() < prob) { double range = bounds[i % bounds.Rows, 1] - bounds[i % bounds.Rows, 0]; if (random.NextDouble() < 0.5) { vector[i] = vector[i] + value * searchIntervalFactor.Value * range; } else { vector[i] = vector[i] - value * searchIntervalFactor.Value * range; } wasMutated = true; } } // make sure at least one gene was mutated if (!wasMutated) { int pos = random.Next(length); double range = bounds[pos % bounds.Rows, 1] - bounds[pos % bounds.Rows, 0]; if (random.NextDouble() < 0.5) { vector[pos] = vector[pos] + value * searchIntervalFactor.Value * range; } else { vector[pos] = vector[pos] - value * searchIntervalFactor.Value * range; } } }
/// <summary> /// Checks if all elements of the given <paramref name="vector"/> are inside the bounds and if not, elements are set to the respective values of the bounds. /// </summary> /// <param name="bounds">The lower and upper bound (1st and 2nd column) of the positions in the vector. If there are less rows than dimensions, the rows are cycled.</param> /// <param name="vector">The vector to check.</param> /// <returns>The corrected real vector.</returns> public static void Apply(RealVector vector, DoubleMatrix bounds) { for (int i = 0; i < vector.Length; i++) { double min = bounds[i % bounds.Rows, 0], max = bounds[i % bounds.Rows, 1]; if (vector[i] < min) vector[i] = min; if (vector[i] > max) vector[i] = max; } }
/// <summary> /// Mutates the endogenous strategy parameters. /// </summary> /// <param name="random">The random number generator to use.</param> /// <param name="vector">The strategy vector to manipulate.</param> /// <param name="generalLearningRate">The general learning rate dampens the mutation over all dimensions.</param> /// <param name="learningRate">The learning rate dampens the mutation in each dimension.</param> public static void Apply(IRandom random, RealVector vector, double generalLearningRate, double learningRate) { NormalDistributedRandom N = new NormalDistributedRandom(random, 0.0, 1.0); double generalMultiplier = Math.Exp(generalLearningRate * N.NextDouble()); for (int i = 0; i < vector.Length; i++) { vector[i] *= generalMultiplier * Math.Exp(learningRate * N.NextDouble()); } }
public override double[] Evaluate(RealVector r, int objectives) { if (r.Length < 10 * objectives) throw new Exception("The dimensionality of the problem(ProblemSize) must be larger than ten times the number of objectives "); double n = r.Length; double M = objectives; double ratio = n / M; double[] res = new double[objectives]; for (int j = 0; j < objectives; j++) { double sum = 0; for (int i = (int)(j * ratio); i < (j + 1) + ratio; i++) { sum += r[i]; } sum /= (int)ratio; res[j] = sum; } for (int j = 0; j < M - 1; j++) { if (res[objectives - 1] + 4 * res[j] - 1 < 0) return IllegalValue(objectives, GetMaximization(objectives)); } double min = Double.PositiveInfinity; for (int i = 0; i < res.Length - 1; i++) { for (int j = 0; j < i; j++) { double d = res[i] + res[j]; if (min < d) min = d; } } if (2 * res[objectives - 1] + min - 1 < 0) return IllegalValue(objectives, GetMaximization(objectives)); return res; }
public override double[] Evaluate(RealVector r, int objectives) { if (r.Length < objectives) { throw new ArgumentException("The dimensionality of the problem(ProblemSize) must be larger than or equal to the number of objectives"); } double[] res = new double[objectives]; //calculate g(Xm) double sum = 0; int length = r.Length - objectives + 1; for (int i = r.Length - length; i < r.Length; i++) { double d = r[i] - 0.5; sum += d * d - Math.Cos(20 * Math.PI * d); } double g = 100 * (length + sum); //calculating f0...fM-1 for (int i = 0; i < objectives; i++) { double f = i == 0 ? 1 : (Math.Sin(r[objectives - i - 1] * Math.PI / 2)) * (1 + g); for (int j = 0; j < objectives - i - 1; j++) { f *= Math.Cos(r[j] * Math.PI / 2); } res[i] = f; } return res; }
/// <summary> /// Performs an adaptive normally distributed all position manipulation on the given /// <paramref name="vector"/>. /// </summary> /// <exception cref="InvalidOperationException">Thrown when the strategy vector is not /// as long as the vector to get manipulated.</exception> /// <param name="sigma">The strategy vector determining the strength of the mutation.</param> /// <param name="random">A random number generator.</param> /// <param name="vector">The real vector to manipulate.</param> /// <returns>The manipulated real vector.</returns> public static void Apply(IRandom random, RealVector vector, RealVector sigma) { if (sigma == null || sigma.Length == 0) throw new ArgumentException("ERROR: Vector containing the standard deviations is not defined.", "sigma"); NormalDistributedRandom N = new NormalDistributedRandom(random, 0.0, 1.0); for (int i = 0; i < vector.Length; i++) { vector[i] = vector[i] + (N.NextDouble() * sigma[i % sigma.Length]); } }
public override double[] Evaluate(RealVector r, int objectives) { if (objectives != 2) throw new ArgumentException("The CIGTAB problem must always have 2 objectives"); double x = r[0]; double a = 1000; double sum = x * x; for (int i = 1; i < r.Length - 1; i++) { sum += a * r[i] * r[i]; } sum += a * a * r[r.Length - 1] * r[r.Length - 1]; //objective1 double f0 = 1 / (a * a * r.Length) * sum; x = x - 2; sum = x * x; for (int i = 1; i < r.Length - 1; i++) { sum += a * (r[i] - 2) * (r[i] - 2); } sum += a * a * (r[r.Length - 1] - 2) * (r[r.Length - 1] - 2); //objective0 double f1 = 1 / (a * a * r.Length) * sum; return new double[] { f0, f1 }; }
protected override double Evaluate(double quality, RealVector point, AdditiveMove move) { RealVectorAdditiveMoveWrapper wrapper = new RealVectorAdditiveMoveWrapper(move, point); var eval = EvaluatorParameter.ActualValue as MultinormalEvaluator; if (eval != null) return eval.Evaluate(wrapper); throw new InvalidOperationException("evaluator is not a multinormal evaluator"); }
public override double[] Evaluate(RealVector r, int objectives) { if (r.Length < objectives) { throw new ArgumentException("The dimensionality of the problem(ProblemSize) must be larger than or equal to the number of objectives"); } double[] res = new double[objectives]; //calculate g(Xm) double g = 0, length = length = r.Length - objectives + 1; for (int i = objectives; i < r.Length; i++) { g += r[i]; } g = 1.0 + 9.0 / length * g; if (length == 0) { g = 1; } //calculating f0...fM-2 for (int i = 0; i < objectives - 1; i++) { res[i] = r[i]; } //calculate fM-1 double h = objectives; for (int i = 0; i < objectives - 1; i++) { h -= res[i] / (1 + g) * (1 + Math.Sin(3 * Math.PI * res[i])); } res[objectives - 1] = (1 + g) * h; return res; }
protected override double G(RealVector y) { double sum = 0.0; for (int i = 1; i < y.Length; i++) { sum += y[i] * y[i] - 10 * Math.Cos(4 * Math.PI * y[i]); } return 1 + 10 * (y.Length - 1) + sum; }
public override double[] Evaluate(RealVector r) { double g = 0; for (int i = 1; i < r.Length; i++) g += r[i]; g = 1.0 + 9.0 * g / (r.Length - 1); double f0 = r[0]; double f1 = g * (1.0 - Math.Sqrt(r[0] / g)); return new double[] { f0, f1 }; }
protected override IEnumerable<double[]> GetOptimalParetoFront(int objectives) { List<double[]> res = new List<double[]>(); for (int i = 0; i <= 500; i++) { RealVector r = new RealVector(objectives); r[0] = 1 / 500.0 * i; res.Add(this.Evaluate(r, objectives)); } return res; }
public override double[] Evaluate(RealVector r) { double g = 0; for (int i = 1; i < r.Length; i++) g += r[i]; g = 1.0 + 9.0 * Math.Pow(g / (r.Length - 1), 0.25); double f1 = 1 - Math.Exp(-4 * r[0]) * Math.Pow(Math.Sin(6 * Math.PI * r[0]), 6); double d = f1 / g; double f2 = g * (1.0 - d * d); return new double[] { f1, f2 }; }
/// <summary> /// Performs the arithmetic crossover on all positions by calculating x = alpha * p1 + (1 - alpha) * p2. /// </summary> /// <exception cref="ArgumentException">Thrown when the parent vectors are of different length or alpha is outside the range [0;1].</exception> /// <param name="random">The random number generator.</param> /// <param name="parent1">The first parent vector.</param> /// <param name="parent2">The second parent vector.</param> /// <param name="alpha">The alpha parameter (<see cref="AlphaParameter"/>).</param> /// <returns>The vector resulting from the crossover.</returns> public static RealVector Apply(IRandom random, RealVector parent1, RealVector parent2, DoubleValue alpha) { int length = parent1.Length; if (length != parent2.Length) throw new ArgumentException("UniformAllPositionsArithmeticCrossover: The parent vectors are of different length.", "parent1"); if (alpha.Value < 0 || alpha.Value > 1) throw new ArgumentException("UniformAllPositionsArithmeticCrossover: Parameter alpha must be in the range [0;1]", "alpha"); RealVector result = new RealVector(length); for (int i = 0; i < length; i++) { result[i] = alpha.Value * parent1[i] + (1 - alpha.Value) * parent2[i]; } return result; }
/// <summary> /// Evaluates the test function for a specific <paramref name="point"/>. /// </summary> /// <param name="point">N-dimensional point for which the test function should be evaluated.</param> /// <returns>The result value of the Zakharov function at the given point.</returns> public static double Apply(RealVector point) { int length = point.Length; double s1 = 0; double s2 = 0; for (int i = 0; i < length; i++) { s1 += point[i] * point[i]; s2 += 0.5 * i * point[i]; } return s1 + (s2 * s2) + (s2 * s2 * s2 * s2); }
public override double[] Evaluate(RealVector r) { double g = 0; for (int i = 1; i < r.Length; i++) { double v = r[i]; g += v * v - 10 * Math.Cos(4 * Math.PI * v); } g = 1.0 + 10.0 * (r.Length - 1) + g; double d = r[0] / g; double f0 = r[0]; double f1 = 1 - Math.Sqrt(d); return new double[] { f0, f1 }; }
public static AdditiveMove[] Apply(IRandom random, RealVector vector, double contiguity, int sampleSize, double maxManipulation, DoubleMatrix bounds) { AdditiveMove[] moves = new AdditiveMove[sampleSize]; for (int i = 0; i < sampleSize; i++) { int index = random.Next(vector.Length); double strength = 0, min = bounds[index % bounds.Rows, 0], max = bounds[index % bounds.Rows, 1]; do { strength = PolynomialOnePositionManipulator.Apply(random, contiguity) * maxManipulation; } while (vector[index] + strength < min || vector[index] + strength > max); moves[i] = new AdditiveMove(index, strength); } return moves; }
/// <summary> /// Performs a random convex crossover on the two given parents. /// </summary> /// <exception cref="ArgumentException">Thrown when two parents are not of the same length.</exception> /// <param name="random">The random number generator.</param> /// <param name="parent1">The first parent vector for the crossover.</param> /// <param name="parent2">The second parent vector for the crossover.</param> /// <returns>The newly created real vector, resulting from the random convex crossover.</returns> public static RealVector Apply(IRandom random, RealVector parent1, RealVector parent2) { if (parent1.Length != parent2.Length) throw new ArgumentException("ERROR in RandomConvexCrossover: the two parents are not of the same length"); int length = parent1.Length; double[] result = new double[length]; double factor = random.NextDouble(); for (int i = 0; i < length; i++) result[i] = (factor * parent1[i]) + ((1 - factor) * parent2[i]); return new RealVector(result); }
private IEnumerable<RealVector> GetCenters(int nDim) { RealVector r0 = new RealVector(nDim); for (int i = 0; i < r0.Length; i++) r0[i] = 5; yield return r0; for (int i = 1; i < 1 << nDim; i++) { RealVector r = new RealVector(nDim); for (int j = 0; j < nDim; j++) { r[j] = (i >> j) % 2 == 0 ? Random.NextDouble() + 4.5 : Random.NextDouble() + 14.5; } yield return r; } }
/// <summary> /// Perfomrs a heuristic crossover on the two given parents. /// </summary> /// <exception cref="ArgumentException">Thrown when two parents are not of the same length.</exception> /// <param name="random">The random number generator.</param> /// <param name="betterParent">The first parent for the crossover operation.</param> /// <param name="worseParent">The second parent for the crossover operation.</param> /// <returns>The newly created real vector, resulting from the heuristic crossover.</returns> public static RealVector Apply(IRandom random, RealVector betterParent, RealVector worseParent) { if (betterParent.Length != worseParent.Length) throw new ArgumentException("HeuristicCrossover: the two parents are not of the same length"); int length = betterParent.Length; double[] result = new double[length]; double factor = random.NextDouble(); for (int i = 0; i < length; i++) { result[i] = betterParent[i] + factor * (betterParent[i] - worseParent[i]); } return new RealVector(result); }
public static AdditiveMove[] Apply(IRandom random, RealVector vector, double sigma, int sampleSize, DoubleMatrix bounds) { AdditiveMove[] moves = new AdditiveMove[sampleSize]; NormalDistributedRandom N = new NormalDistributedRandom(random, 0, sigma); for (int i = 0; i < sampleSize; i++) { int index = random.Next(vector.Length); double strength = 0, min = bounds[index % bounds.Rows, 0], max = bounds[index % bounds.Rows, 1]; do { strength = N.NextDouble(); } while (vector[index] + strength < min || vector[index] + strength > max); moves[i] = new AdditiveMove(index, strength); } return moves; }
public override double[] Evaluate(RealVector r, int objectives) { if (objectives != 2) throw new ArgumentException("The Schaffer N1 problem must always have 2 objectives"); if (r.Length != 1) return null; double x = r[0]; //objective1 double f0 = x * x; //objective0 double f1 = x - 2; f1 *= f1; return new double[] { f0, f1 }; }
/// <summary> /// Performs a discrete crossover operation on multiple parents. /// </summary> /// <exception cref="ArgumentException">Thrown when the vectors of the parents are of different length.</exception> /// <param name="random">A random number generator.</param> /// <param name="parents">An array containing the parents that should be crossed.</param> /// <returns>The newly created real vector, resulting from the crossover operation.</returns> public static RealVector Apply(IRandom random, ItemArray<RealVector> parents) { int length = parents[0].Length; for (int i = 0; i < parents.Length; i++) { if (parents[i].Length != length) throw new ArgumentException("DiscreteCrossover: The parents' vectors are of different length.", "parents"); } RealVector result = new RealVector(length); for (int i = 0; i < length; i++) { result[i] = parents[random.Next(parents.Length)][i]; } return result; }
/// <summary> /// Performs the polynomial mutation on a single position in the real vector. /// </summary> /// <param name="random">The random number generator to use.</param> /// <param name="vector">The vector that should be manipulated.</param> /// <param name="contiguity">A parameter describing the shape of the probability density function which influences the strength of the manipulation.</param> /// <param name="maxManipulation">The maximum strength of the manipulation.</param> public static void Apply(IRandom random, RealVector vector, DoubleValue contiguity, DoubleValue maxManipulation) { if (contiguity.Value < 0) throw new ArgumentException("PolynomialAllPositionManipulator: Contiguity value is smaller than 0", "contiguity"); double u, delta = 0; for (int index = 0; index < vector.Length; index++) { u = random.NextDouble(); if (u < 0.5) { delta = Math.Pow(2 * u, 1.0 / (contiguity.Value + 1)) - 1.0; } else if (u >= 0.5) { delta = 1.0 - Math.Pow(2.0 - 2.0 * u, 1.0 / (contiguity.Value + 1)); } vector[index] += delta * maxManipulation.Value; } }
public override double[] Evaluate(RealVector r, int objectives) { if (objectives != 2) throw new ArgumentException("The Kursawe problem must always have 2 objectives"); //objective 1 double f0 = 0.0; for (int i = 0; i < r.Length - 1; i++) { f0 += -10 * Math.Exp(-0.2 * Math.Sqrt(r[i] * r[i] + r[i + 1] * r[i + 1])); } //objective2 double f1 = 0.0; for (int i = 0; i < r.Length; i++) { f1 += Math.Pow(Math.Abs(r[i]), 0.8) + 5 * Math.Sin(Math.Pow(r[i], 3)); } return new double[] { f0, f1 }; }
protected abstract AdditiveMove[] GenerateMoves(IRandom random, RealVector realVector, DoubleMatrix bounds);