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);
        }
Beispiel #2
0
        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);
        }
Beispiel #3
0
        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);
        }
Beispiel #4
0
        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);
        }
Beispiel #5
0
        // 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);
        }