private static DifferentialEvolutionSettings GetDefaultSettings(EvaluationSettings settings, int d) { if (settings == null) { settings = new EvaluationSettings(); } DifferentialEvolutionSettings deSettings = new DifferentialEvolutionSettings(); deSettings.Population = 8 * d + 4; deSettings.CrossoverProbability = 1.0 - 1.0 / 8.0 - 1.0 / d; deSettings.RelativePrecision = (settings.RelativePrecision < 0.0) ? Math.Pow(10.0, -(2.0 + 4.0 / d)) : settings.RelativePrecision; deSettings.AbsolutePrecision = (settings.AbsolutePrecision < 0.0) ? Math.Pow(10.0, -(4.0 + 8.0 / d)) : settings.AbsolutePrecision; deSettings.EvaluationBudget = (settings.EvaluationBudget < 0) ? 128 * d * d * d * d : settings.EvaluationBudget; /* * if (settings == null) { * deSettings.RelativePrecision = Math.Pow(10.0, -(2.0 + 4.0 / d)); * deSettings.AbsolutePrecision = MoreMath.Sqr(deSettings.RelativePrecision); * deSettings.EvaluationBudget = 128 * d * d * d * d; * } else { * deSettings.RelativePrecision = settings.RelativePrecision; * deSettings.AbsolutePrecision = settings.AbsolutePrecision; * deSettings.EvaluationBudget = settings.EvaluationBudget; * } */ return(deSettings); }
private static MultiExtremum FindGlobalExtremum(Func <IReadOnlyList <double>, double> function, IReadOnlyList <Interval> volume, MultiExtremumSettings settings, bool negate) { if (function == null) { throw new ArgumentNullException(nameof(function)); } if (volume == null) { throw new ArgumentNullException(nameof(volume)); } MultiFunctor f = new MultiFunctor(function, negate); DifferentialEvolutionSettings deSettings = GetDefaultSettings(settings, volume.Count); MultiExtremum extremum = FindGlobalExtremum(f, volume, deSettings); return(extremum); }
private static DifferentialEvolutionSettings GetDefaultSettings(MultiExtremumSettings settings, int d) { if (settings == null) { settings = new MultiExtremumSettings(); } DifferentialEvolutionSettings deSettings = new DifferentialEvolutionSettings(); deSettings.Population = 8 * d + 4; deSettings.CrossoverProbability = 1.0 - 1.0 / 8.0 - 1.0 / d; deSettings.RelativePrecision = (settings.RelativePrecision < 0.0) ? Math.Pow(10.0, -(2.0 + 4.0 / d)) : settings.RelativePrecision; deSettings.AbsolutePrecision = (settings.AbsolutePrecision < 0.0) ? Math.Pow(10.0, -(4.0 + 8.0 / d)) : settings.AbsolutePrecision; deSettings.EvaluationBudget = (settings.EvaluationBudget < 0) ? 128 * d * d * d * d : settings.EvaluationBudget; deSettings.Listener = settings.Listener; return(deSettings); }
private static DifferentialEvolutionSettings GetDefaultSettings(EvaluationSettings settings, int d) { DifferentialEvolutionSettings deSettings = new DifferentialEvolutionSettings(); deSettings.Population = 8 * d + 4; deSettings.CrossoverProbability = 1.0 - 1.0 / 8.0 - 1.0 / d; if (settings == null) { deSettings.RelativePrecision = Math.Pow(10.0, -(2.0 + 4.0 / d)); deSettings.AbsolutePrecision = MoreMath.Sqr(deSettings.RelativePrecision); deSettings.EvaluationBudget = 128 * d * d * d * d; } else { deSettings.RelativePrecision = settings.RelativePrecision; deSettings.AbsolutePrecision = settings.AbsolutePrecision; deSettings.EvaluationBudget = settings.EvaluationBudget; } return(deSettings); }
// Differential evolution is a global optimization algorithm over continuous inputs that is adapted from genetic algorithms for finite inputs. // The idea is to maintain a population of input vectors ("agents") and to vary that population over cycles ("generations") according to rules that incorporate // random mutation but on average tend to bring them closer to optima ("fitter"). private static MultiExtremum FindGlobalExtremum(MultiFunctor f, IReadOnlyList <Interval> volume, DifferentialEvolutionSettings settings) { int d = volume.Count; // Choose a number of agents that increases with dimension and required precision. int m = settings.Population; Debug.WriteLine("d={0} m={1}", d, m); Random rng = new Random(3); // Start with random points in the allowed region. double[][] points = new double[m][]; double[] values = new double[m]; for (int i = 0; i < m; i++) { points[i] = new double[d]; for (int j = 0; j < d; j++) { points[i][j] = volume[j].LeftEndpoint + rng.NextDouble() * volume[j].Width; } values[i] = f.Evaluate(points[i]); } while (f.EvaluationCount < settings.EvaluationBudget) { double[][] newPoints = new double[m][]; double[] newValues = new double[m]; for (int i = 0; i < m; i++) { // Mutation // construct donor vector int a = i; while (a == i) { a = rng.Next(m); } int b = i; while ((b == i) || (b == a)) { b = rng.Next(m); } int c = i; while ((c == i) || (c == b) || (c == a)) { c = rng.Next(m); } double[] donor = new double[d]; for (int j = 0; j < d; j++) { donor[j] = points[a][j] + mutationFactor * (points[b][j] - points[c][j]); if (donor[j] < volume[j].LeftEndpoint) { donor[j] = volume[j].LeftEndpoint; } if (donor[j] > volume[j].RightEndpoint) { donor[j] = volume[j].RightEndpoint; } } // Recombination double[] trial = new double[d]; int k = rng.Next(d); for (int j = 0; j < d; j++) { if ((j == k) || (rng.NextDouble() < settings.CrossoverProbability)) { trial[j] = donor[j]; } else { trial[j] = points[i][j]; } } // Selection double value = f.Evaluate(trial); if (value <= values[i]) { newPoints[i] = trial; newValues[i] = value; } else { newPoints[i] = points[i]; newValues[i] = values[i]; } } points = newPoints; values = newValues; // Check termination criteria int minIndex = -1; double minValue = Double.MaxValue; double maxValue = Double.MinValue; for (int i = 0; i < m; i++) { if (values[i] < minValue) { minValue = values[i]; minIndex = i; } if (values[i] > maxValue) { maxValue = values[i]; } } double range = maxValue - minValue; double tol = settings.ComputePrecision(minValue); if (range <= tol) { MultiExtremum result = new MultiExtremum(f.EvaluationCount, settings, points[minIndex], f.IsNegated ? -values[minIndex] : values[minIndex], Math.Max(range, 0.75 * tol), null); return(result); } else if (settings.Listener != null) { MultiExtremum report = new MultiExtremum(f.EvaluationCount, settings, points[minIndex], f.IsNegated ? -values[minIndex] : values[minIndex], Math.Max(range, 0.75 * tol), null); settings.Listener(report); } } throw new NonconvergenceException(); }
// Differential evoluation is a global optimization algorithm over continuous inputs that is adapted from genetic algorithms for finite inputs. // The idea is maintain a population of input vectors ("agents") and to vary that population over cycles ("generations") according to rules that incorporate // random mutation but on average tend to bring them closer to optima ("fitter"). private static MultiExtremum FindGlobalExtremum(MultiFunctor f, IList<Interval> volume, DifferentialEvolutionSettings settings) { int d = volume.Count; // Choose a number of agents that increases with dimension and required precision. int m = settings.Population; Debug.WriteLine("d={0} m={1}", d, m); Random rng = new Random(3); //Random rng = new Random(1001110000); // Start with random points in the allowed region. double[][] points = new double[m][]; double[] values = new double[m]; for (int i = 0; i < m; i++) { points[i] = new double[d]; for (int j = 0; j < d; j++) { points[i][j] = volume[j].LeftEndpoint + rng.NextDouble() * volume[j].Width; } values[i] = f.Evaluate(points[i]); } while (f.EvaluationCount < settings.EvaluationBudget) { //double mutationFactor = 0.5 + 0.5 * rng.NextDouble(); double[][] newPoints = new double[m][]; double[] newValues = new double[m]; for (int i = 0; i < m; i++) { // Mutation // construct donor vector int a = i; while (a == i) a = rng.Next(m); int b = i; while ((b == i) || (b == a)) b = rng.Next(m); int c = i; while ((c == i) || (c == b) || (c == a)) c = rng.Next(m); double[] donor = new double[d]; for (int j = 0; j < d; j++) { donor[j] = points[a][j] + mutationFactor * (points[b][j] - points[c][j]); if (donor[j] < volume[j].LeftEndpoint) donor[j] = volume[j].LeftEndpoint; if (donor[j] > volume[j].RightEndpoint) donor[j] = volume[j].RightEndpoint; } // Recombination double[] trial = new double[d]; int k = rng.Next(d); for (int j = 0; j < d; j++) { if ((j == k) || (rng.NextDouble() < settings.CrossoverProbability)) { trial[j] = donor[j]; } else { trial[j] = points[i][j]; } } // Selection double value = f.Evaluate(trial); if (value <= values[i]) { newPoints[i] = trial; newValues[i] = value; } else { newPoints[i] = points[i]; newValues[i] = values[i]; } } points = newPoints; values = newValues; // Check termination criteria int minIndex = -1; double minValue = Double.MaxValue; double maxValue = Double.MinValue; for (int i = 0; i < m; i++) { if (values[i] < minValue) { minValue = values[i]; minIndex = i; } if (values[i] > maxValue) maxValue = values[i]; } double range = maxValue - minValue; double tol = settings.ComputePrecision(minValue); if (range <= tol) { MultiExtremum result = new MultiExtremum(f.EvaluationCount, settings, points[minIndex], f.IsNegated ? -values[minIndex] : values[minIndex], Math.Max(range, 0.75 * tol), null); return (result); } //settings.OnUpdate(new MultiExtremum(points[minIndex], values[minIndex], null, f.EvaluationCount)); } throw new NonconvergenceException(); }
private static DifferentialEvolutionSettings GetDefaultSettings(EvaluationSettings settings, int d) { DifferentialEvolutionSettings deSettings = new DifferentialEvolutionSettings(); deSettings.Population = 8 * d + 4; deSettings.CrossoverProbability = 1.0 - 1.0 / 8.0 - 1.0 / d; if (settings == null) { deSettings.RelativePrecision = Math.Pow(10.0, -(2.0 + 4.0 / d)); deSettings.AbsolutePrecision = MoreMath.Sqr(deSettings.RelativePrecision); deSettings.EvaluationBudget = 128 * d * d * d * d; } else { deSettings.RelativePrecision = settings.RelativePrecision; deSettings.AbsolutePrecision = settings.AbsolutePrecision; deSettings.EvaluationBudget = settings.EvaluationBudget; } return (deSettings); }