Ejemplo n.º 1
0
        private List <Configuration> GenerateFirstSamples(IOptimizationProblem problem)
        {
            List <Configuration> returnList = new List <Configuration>();
            int dimensionsCount             = problem.DimensionsCount;

            returnList.Add(new Configuration(dimensionsCount));

            for (int i = 0; i < dimensionsCount; i++)
            {
                double min  = problem.GetMinForDimension(i);
                double max  = problem.GetMaxForDimension(i);
                double step = problem.GetStepForDimension(i);

                List <Configuration> newConfigurations = new List <Configuration>();

                foreach (Configuration conf in returnList)
                {
                    for (double j = min; j < max; j += step)
                    {
                        Configuration configuration = conf.Clone();
                        configuration.SetValueForDimension(i, j);
                        newConfigurations.Add(configuration);
                    }

                    conf.SetValueForDimension(i, max);
                }

                returnList.AddRange(newConfigurations);
            }

            return(returnList);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Initializes the algorithm.
        /// </summary>
        /// <param name="problem">The problem.</param>
        /// <param name="location">The theta.</param>
        /// <param name="residuals">The initial residuals.</param>
        /// <param name="searchDirection">The initial search direction.</param>
        /// <returns>The state to be passed to the <see cref="UpdateDirection" /> function.</returns>
        protected override object InitializeAlgorithm(IOptimizationProblem <double, IDifferentiableCostFunction <double> > problem, Vector <double> location, Vector <double> residuals, out Vector <double> searchDirection)
        {
            // the initial search direction is along the residuals,
            // which makes the initial step a regular gradient descent.
            searchDirection = residuals;

            // return some state information
            return(null);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Metoda de optimizare care gaseste solutia problemei
        /// </summary>
        ///
        public Chromosome Solve(IOptimizationProblem p, int populationSize, int maxGenerations, double crossoverRate, double mutationRate)
        {
            //throw new Exception("Aceasta metoda trebuie completata");

            Chromosome[] population = new Chromosome[populationSize];
            for (int i = 0; i < population.Length; i++)
            {
                population[i] = p.MakeChromosome();
                p.ComputeFitness(population[i]);
            }

            for (int gen = 0; gen < maxGenerations; gen++)
            {
                Chromosome[] newPopulation = new Chromosome[populationSize];
                //newPopulation[0] = Selection.GetBest(population); // elitism
                List <Chromosome> indivizi = new List <Chromosome>();
                for (int i = 0; i < populationSize; i++)
                {
                    indivizi.Add(population[i]);
                    for (int j = 0; j < 3; ++j)
                    {
                        do
                        {
                            Chromosome c = Selection.Tournament(population);
                            if (indivizi.Contains(c) == false)
                            {
                                indivizi.Add(c);
                                break;
                            }
                        } while (true);
                    }

                    Chromosome individ_potential = Crossover.Arithmetic(population[i], indivizi, crossoverRate, mutationRate);

                    indivizi.Clear();

                    p.ComputeFitness(individ_potential);

                    if (individ_potential.Fitness >= population[i].Fitness)
                    {
                        newPopulation[i] = individ_potential;
                    }
                    else
                    {
                        newPopulation[i] = population[i];
                    }
                }

                for (int i = 0; i < populationSize; i++)
                {
                    population[i] = newPopulation[i];
                }
            }

            return(Selection.GetBest(population));
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Initializes the algorithm.
        /// </summary>
        /// <param name="problem">The problem.</param>
        /// <param name="location">The theta.</param>
        /// <param name="residuals">The initial residuals.</param>
        /// <param name="searchDirection">The initial search direction.</param>
        /// <returns>The state to be passed to the <see cref="UpdateDirection" /> function.</returns>
        protected override object InitializeAlgorithm(IOptimizationProblem <double, IDifferentiableCostFunction <double> > problem, Vector <double> location, Vector <double> residuals, out Vector <double> searchDirection)
        {
            searchDirection = -residuals.Normalize(2);

            // at this point, no previous gradient exists
            var previousGradient = Vector <double> .Build.Dense(residuals.Count, Vector <double> .Zero);

            // no state required
            return(new State(previousGradient, problem));
        }
Ejemplo n.º 5
0
        private Tuple <double, Configuration> Optimize(IOptimizationProblem problem, int depth)
        {
            if (depth > _searchDepth)
            {
                return(null);
            }

            List <Configuration> firstSamples = GenerateFirstSamples(problem);
            List <Tuple <double, Configuration> > evaluations = new List <Tuple <double, Configuration> >(firstSamples.Count);

            foreach (Configuration sample in firstSamples)
            {
                evaluations.Add(new Tuple <double, Configuration>(problem.Evaluate(sample), sample));
            }

            //REEVALUATE FIRST x percent if evaluation function is unstable
            for (int j = 1; j < 11; j++)
            {
                evaluations.Sort((x, y) => x.Item1.CompareTo(y.Item1));
                int maxIndex = evaluations.Count / (2 * j);
                for (int i = 0; i < maxIndex; i++)
                {
                    evaluations[i] = new Tuple <double, Configuration>((evaluations[i].Item1 + problem.Evaluate(evaluations[i].Item2)) / 2, evaluations[i].Item2);
                }
            }

            evaluations.Sort((x, y) => x.Item1.CompareTo(y.Item1));

            List <IOptimizationProblem> newProblems = new List <IOptimizationProblem>(_spaceCoverageIndex);

            for (int i = 0; i < _spaceCoverageIndex; i++)
            {
                if (i < evaluations.Count)
                {
                    newProblems.Add(new SubOptimizationProblem(evaluations[i].Item2, problem));
                }
            }

            Tuple <double, Configuration> best = evaluations[0];

            foreach (IOptimizationProblem newProblem in newProblems)
            {
                Tuple <double, Configuration> optimal = Optimize(newProblem, depth + 1);
                if (optimal != null)
                {
                    if (optimal.Item1 < best.Item1)
                    {
                        best = optimal;
                    }
                }
            }

            return(best);
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Initializes the algorithm.
        /// </summary>
        /// <param name="problem">The problem.</param>
        /// <param name="location">The theta.</param>
        /// <param name="residuals">The initial residuals.</param>
        /// <param name="searchDirection">The initial search direction.</param>
        /// <returns>The state to be passed to the <see cref="UpdateDirection" /> function.</returns>
        protected override object InitializeAlgorithm(IOptimizationProblem <double, IDifferentiableCostFunction <double> > problem, Vector <double> location, Vector <double> residuals, out Vector <double> searchDirection)
        {
            // determine a preconditioner
            var preconditioner = GetPreconditioner(problem, location);

            // get the preconditioned residuals
            var preconditionedResiduals = preconditioner.Inverse() * residuals;

            // the initial search direction is along the residuals,
            // which makes the initial step a regular gradient descent.
            searchDirection = preconditionedResiduals;

            // return some state information
            return(new State(problem, preconditionedResiduals));
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Minimizes the specified problem.
        /// </summary>
        /// <param name="problem">The problem.</param>
        public override IOptimizationResult <double> Minimize(IOptimizationProblem <double, IDifferentiableCostFunction <double> > problem)
        {
            var maxIterations   = MaxIterations;
            var increaseFactor  = _stepIncreaseFactor;
            var decreaseFactor  = _stepDecreaseFactor;
            var initialStepSize = _initialStepSize;
            // ReSharper disable once ExceptionNotDocumented
            var threshold = ErrorTolerance;

            // obtain the initial cost
            var costFunction = problem.CostFunction;
            var cost         = 0D;
            var previousCost = double.MaxValue;

            // obtain the initial coefficients
            var coefficients     = problem.GetInitialCoefficients();
            var coefficientCount = coefficients.Count;

            // we need to store that last iteration's gradients
            var previousGradient = Vector <double> .Build.Dense(coefficientCount, Vector <double> .Zero);

            var secondPreviousGradient = Vector <double> .Build.Dense(coefficientCount, Vector <double> .Zero);

            // initialize the step widths
            var stepWidths = Vector <double> .Build.Dense(coefficientCount, initialStepSize);

            // loop over all allowed iterations
            for (var i = 0; i < maxIterations; ++i)
            {
                // obtain the cost
                cost = costFunction.CalculateCost(coefficients);

                // determine the change in cost
                var costChange = cost - previousCost;
                if (Math.Abs(costChange) <= threshold)
                {
                    Debug.WriteLine("Stopping REGD at iteration {0}/{1} because costChange |{2}| <= {3}", i, maxIterations, costChange, threshold);
                    break;
                }

                // determine changes in gradient direction
                var gradient = costFunction.Jacobian(coefficients);
                var gradientDirectionIndicator         = gradient.PointwiseMultiply(previousGradient);
                var previousGradientDirectionIndicator = previousGradient.PointwiseMultiply(secondPreviousGradient);

                // update step sizes for each individual coefficient
                for (var p = 0; p < coefficientCount; ++p)
                {
                    var gradientInOppositeDirection     = gradientDirectionIndicator[p] < 0;
                    var gradientInSameDirection         = gradientDirectionIndicator[p] > 0;
                    var previousGradientInSameDirection = previousGradientDirectionIndicator[p] >= 0;
                    if (gradientInOppositeDirection)
                    {
                        // decrease step size for this coefficient
                        stepWidths[p] *= decreaseFactor;
                    }
                    else if (gradientInSameDirection && previousGradientInSameDirection) // TODO check that condition
                    {
                        // increase step size for this coefficient
                        stepWidths[p] *= increaseFactor;
                    }
                    else
                    {
                        // keep step size for this coefficient
                        stepWidths[p] *= 1.0D;
                    }
                }

                // determine the coefficient delta to apply
                var delta = gradient.MapIndexed((index, g) => Math.Sign(g) * stepWidths[index]);
                coefficients -= delta;

                // store values for the next iteration
                previousCost           = cost;
                secondPreviousGradient = previousGradient;
                previousGradient       = gradient;
            }

            return(new OptimizationResult <double>(cost, coefficients));
        }
Ejemplo n.º 8
0
 /// <summary>
 /// Initializes a new instance of the <see cref="State"/> class.
 /// </summary>
 /// <param name="previousGradient">The previous gradient.</param>
 public State(Vector <double> previousGradient, IOptimizationProblem <double, IDifferentiableCostFunction <double> > problem)
 {
     PreviousGradient = previousGradient;
     Problem          = problem;
 }
Ejemplo n.º 9
0
        public double[] Optimize(IOptimizationProblem problem)
        {
            Tuple <double, Configuration> configuration = Optimize(problem, 0);

            return(configuration.Item2.Value);
        }
Ejemplo n.º 10
0
 public SubOptimizationProblem(Configuration sample, IOptimizationProblem parentProblem)
 {
     _sample        = sample;
     _parentProblem = parentProblem;
 }
Ejemplo n.º 11
0
 /// <summary>
 /// Minimizes the specified problem.
 /// </summary>
 /// <param name="problem">The problem.</param>
 /// <returns>IOptimizationResult&lt;TData&gt;.</returns>
 public abstract IOptimizationResult <TData> Minimize(IOptimizationProblem <TData, TCostFunction> problem);
Ejemplo n.º 12
0
        /// <summary>
        /// Minimizes the specified problem.
        /// </summary>
        /// <param name="problem">The problem.</param>
        /// <returns>IOptimizationResult&lt;TData&gt;.</returns>
        public sealed override IOptimizationResult <double> Minimize(IOptimizationProblem <double, TCostFunction> problem)
        {
            var maxIterations = MaxIterations;

            // The idea is that we should stop the operation if ||residuals|| < epsilon.
            // Since the norm calculation requires taking the square root,
            // we instead square epsilon and compare against that.
            var epsilonSquare = ErrorToleranceSquared;

            // fetch a starting point and obtain the problem size
            var location         = problem.GetInitialCoefficients();
            var problemDimension = location.Count;

            // we want to restart nonlinear CG at least every n steps,
            // and use this variable as a counter.
            var iterationsUntilReset = problemDimension;

            // now we determine the initial residuals, which are defined to
            // be the opposite gradient direction
            var costFunction = problem.CostFunction;
            var residuals    = -costFunction.Jacobian(location);

            // the initial search direction is along the residuals,
            // which makes the initial step a regular gradient descent.
            // However, some CG algorithms (especially when using a preconditioner)
            // might yield slightly different directions, so we'll leave that to
            // the initialization function.
            Vector <double> direction; // = residuals

            // initialize the algorithm
            object state = InitializeAlgorithm(problem, location, residuals, out direction);

            // determine the initial error
            var delta         = residuals * residuals;
            var initialDelta  = delta;
            var previousAlpha = 0.0D;

            // loop for the maximum iteration count
            for (var i = 0; i < maxIterations; ++i)
            {
                // stop if the gradient change is below the threshold
                if (delta <= epsilonSquare * initialDelta) // TODO the scaling with initialDelta does do some trouble every now and then ...
                {
                    Debug.WriteLine("Stopping CG/S/FR at iteration {0}/{1} because cost |{2}| <= {3}", i, maxIterations, delta, epsilonSquare * initialDelta);
                    break;
                }

                // var cost = costFunction.CalculateCost(x);

                // perform a line search to find the minimum along the given direction
                var alpha = PerformLineSearch(costFunction, location, direction, previousAlpha);
                previousAlpha = alpha;
                location     += alpha * direction;

                // obtain the new residuals
                residuals = -costFunction.Jacobian(location);

                // obtain the update parameter
                var shouldContinue = UpdateDirection(state, location, residuals, ref direction, ref delta);

                // Conjugate Gradient can generate only n conjugate search directions
                // in n-dimensional space, so we'll reset the algorithm every n steps in order
                // to give nonlinear optimization a chance.
                // Alternatively, when the implementation decides that the resulting search direction
                // would be non-A-conjugate (e.g. non-orthogonal to all previous search directions),
                // reset is triggered as well.
                var shouldReset = (--iterationsUntilReset == 0) || !shouldContinue;
                if (shouldReset)
                {
                    // reset the search direction to point towards the current
                    // residuals (which are opposite of the gradient!)
                    direction = residuals.Normalize(2);

                    // reset the counter
                    iterationsUntilReset = problemDimension;

                    // reset the previous alpha
                    previousAlpha = 0.0D;
                }
            }

            // that's it.
            var cost = costFunction.CalculateCost(location);

            return(new OptimizationResult <double>(cost, location));
        }
Ejemplo n.º 13
0
 /// <summary>
 /// Initializes the algorithm.
 /// </summary>
 /// <param name="problem">The problem.</param>
 /// <param name="location">The location.</param>
 /// <param name="residuals">The initial residuals.</param>
 /// <param name="searchDirection">The initial search direction.</param>
 /// <returns>The state to be passed to the <see cref="UpdateDirection" /> function.</returns>
 protected abstract object InitializeAlgorithm([NotNull] IOptimizationProblem <double, TCostFunction> problem, Vector <double> location, Vector <double> residuals, out Vector <double> searchDirection);
Ejemplo n.º 14
0
 /// <summary>
 /// Initializes a new instance of the <see cref="State"/> class.
 /// </summary>
 /// <param name="problem">The problem.</param>
 /// <param name="previousPreconditionedResiduals">The previous preconditioned residuals.</param>
 public State(IOptimizationProblem <double, IDifferentiableCostFunction <double> > problem, Vector <double> previousPreconditionedResiduals)
 {
     Problem = problem;
     PreviousPreconditionedResiduals = previousPreconditionedResiduals;
 }
Ejemplo n.º 15
0
 /// <summary>
 /// Gets a preconditioner for the residuals.
 /// </summary>
 /// <param name="problem">The problem.</param>
 /// <param name="theta">The coefficients to optimize.</param>
 /// <returns>MathNet.Numerics.LinearAlgebra.Matrix&lt;System.Double&gt;.</returns>
 private Matrix <double> GetPreconditioner([NotNull, UsedImplicitly] IOptimizationProblem <double, IDifferentiableCostFunction <double> > problem, Vector <double> theta)
 {
     // sadly we have no clue.
     return(Matrix <double> .Build.DiagonalIdentity(theta.Count));
 }