public virtual ContinuousSolution Minimize(CostFunction f, int max_iterations)
 {
     return(Minimize((x, lower_bounds, upper_bounds, constraints) =>
     {
         return f.Evaluate(x);
     },
                     (x, gradX, lower_bounds, upper_bounds, constraints) =>
     {
         f.CalcGradient(x, gradX);
     },
                     (improvement, iterations) =>
     {
         return iterations > max_iterations;
     }));
 }
Example #2
0
        public void Minimize(double x_0, CostFunction f, int max_iterations)
        {
            double x  = x_0;
            double fx = f.Evaluate(x);

            double newtonX = 0;

            double denominator = 0;

            ContinuousSolution best_solution = new ContinuousSolution(new double[] { x }, fx);

            double?improvement = null;

            for (int k = 0; k < max_iterations; ++k)
            {
                f.CalcGradient(x, out denominator);
                if (Math.Abs(denominator) < ZERO)
                {
                    break;
                }

                newtonX = x - fx / denominator;

                if (Math.Abs(newtonX - x) < SIGMA)
                {
                    break;
                }
                x = newtonX;

                fx = f.Evaluate(x);

                if (best_solution.TryUpdateSolution(new double[] { x }, fx, out improvement))
                {
                    OnSolutionUpdated(best_solution, k);
                }

                OnStepped(new ContinuousSolution(new double[] { x }, fx), k);
            }
        }
        public static bool LineSearch(double[] x_0, double fx_0, double[] direction, out double[] x_out, out double fx_out, out double alpha, CostFunction f)
        {
            int dimension = x_0.Length;

            double[] Vfx = new double[dimension];
            x_out  = new double[dimension];
            alpha  = 1.0;
            fx_out = double.MaxValue;

            f.CalcGradient(x_0, Vfx);

            double direction_length = 0;

            for (int d = 0; d < dimension; ++d)
            {
                direction_length += direction[d] * direction[d];
            }
            direction_length = Math.Sqrt(direction_length);

            if (direction_length > 0)
            {
                for (int d = 0; d < dimension; ++d)
                {
                    direction[d] /= direction_length;
                }
            }

            double p = 0.0;

            for (int d = 0; d < dimension; ++d)
            {
                p += (direction[d] * Vfx[d]);
            }

            //Console.WriteLine("p: {0}", p);


            if (double.IsNaN(p))
            {
                return(false);
            }

            if (p >= 0.0) // not in the descending direction return false;
            {
                return(false);
            }


            for (int k = 0; ; ++k)
            {
                for (int d = 0; d < dimension; ++d)
                {
                    x_out[d] = x_0[d] + alpha * direction[d];
                }
                fx_out = f.Evaluate(x_out);

                if (fx_out < fx_0 + SIGMA * alpha * p)
                {
                    return(true);
                }
                else
                {
                    if (k == 0)
                    {
                        double enumerator = (p + fx_0 - fx_out);
                        if (enumerator == 0)
                        {
                            alpha = 0.5 * p / enumerator;
                        }
                        else
                        {
                            alpha = 0.5 * p;
                        }

                        //Console.WriteLine("alpha: {0}", alpha);
                    }
                    else
                    {
                        alpha *= BETA;
                    }
                }

                //Console.WriteLine("alpha: {0}", alpha);

                if (alpha < ZERO)
                {
                    if (fx_out > fx_0)
                    {
                        for (int d = 0; d < dimension; ++d)
                        {
                            x_out[d] = x_0[d];
                        }

                        fx_out = fx_0;
                        return(true);
                    }
                    else
                    {
                        return(true);
                    }
                }
            }
        }