Exemplo n.º 1
0
        /// <summary>
        ///   Creates a new instance of the Augmented Lagrangian algorithm.
        /// </summary>
        ///
        /// <param name="innerSolver">The <see cref="IGradientOptimizationMethod">unconstrained optimization
        ///   method</see> used internally to solve the dual of this optimization problem.</param>
        /// <param name="constraints">The <see cref="NonlinearConstraint"/>s to which the solution must be subjected.</param>
        ///
        public AugmentedLagrangianSolver(IGradientOptimizationMethod innerSolver,
                                         IEnumerable <NonlinearConstraint> constraints)
        {
            int numberOfVariables = innerSolver.Parameters;

            init(numberOfVariables, constraints, innerSolver);
        }
Exemplo n.º 2
0
        private void init(NonlinearObjectiveFunction function,
                          IEnumerable <NonlinearConstraint> constraints, IGradientOptimizationMethod innerSolver)
        {
            if (function != null)
            {
                if (function.NumberOfVariables != NumberOfVariables)
                {
                    throw new ArgumentOutOfRangeException("function",
                                                          "Incorrect number of variables in the objective function. " +
                                                          "The number of variables must match the number of variables set in the solver.");
                }

                this.Function = function.Function;
                this.Gradient = function.Gradient;
            }

            if (innerSolver == null)
            {
                innerSolver = new BroydenFletcherGoldfarbShanno(NumberOfVariables)
                {
                    LineSearch  = Optimization.LineSearch.BacktrackingArmijo,
                    Corrections = 10
                };
            }

            List <NonlinearConstraint> equality    = new List <NonlinearConstraint>();
            List <NonlinearConstraint> lesserThan  = new List <NonlinearConstraint>();
            List <NonlinearConstraint> greaterThan = new List <NonlinearConstraint>();

            foreach (var c in constraints)
            {
                switch (c.ShouldBe)
                {
                case ConstraintType.EqualTo:
                    equality.Add(c); break;

                case ConstraintType.GreaterThanOrEqualTo:
                    greaterThan.Add(c); break;

                case ConstraintType.LesserThanOrEqualTo:
                    lesserThan.Add(c); break;

                default:
                    throw new ArgumentException("Unknown constraint type.", "constraints");
                }
            }

            this.lesserThanConstraints  = lesserThan.ToArray();
            this.greaterThanConstraints = greaterThan.ToArray();
            this.equalityConstraints    = equality.ToArray();

            this.lambda = new double[equalityConstraints.Length];
            this.mu     = new double[lesserThanConstraints.Length];
            this.nu     = new double[greaterThanConstraints.Length];

            this.dualSolver     = innerSolver;
            dualSolver.Function = objectiveFunction;
            dualSolver.Gradient = objectiveGradient;
        }
Exemplo n.º 3
0
        /// <summary>
        ///   Creates a new instance of the Augmented Lagrangian algorithm.
        /// </summary>
        ///
        /// <param name="innerSolver">The <see cref="IGradientOptimizationMethod">unconstrained
        ///   optimization method</see> used internally to solve the dual of this optimization
        ///   problem.</param>
        /// <param name="function">The objective function to be optimized.</param>
        /// <param name="constraints">
        ///   The <see cref="NonlinearConstraint"/>s to which the solution must be subjected.</param>
        ///
        public AugmentedLagrangian(IGradientOptimizationMethod innerSolver,
                                   NonlinearObjectiveFunction function, IEnumerable <NonlinearConstraint> constraints)
            : base(innerSolver.NumberOfVariables)
        {
            if (innerSolver.NumberOfVariables != function.NumberOfVariables)
            {
                throw new ArgumentException("The inner unconstrained optimization algorithm and the "
                                            + "objective function should have the same number of variables.", "function");
            }

            init(function, constraints, innerSolver);
        }
Exemplo n.º 4
0
        private void init(int numberOfVariables, IEnumerable <NonlinearConstraint> constraints, IGradientOptimizationMethod innerSolver)
        {
            this.numberOfVariables = numberOfVariables;

            List <NonlinearConstraint> equality    = new List <NonlinearConstraint>();
            List <NonlinearConstraint> lesserThan  = new List <NonlinearConstraint>();
            List <NonlinearConstraint> greaterThan = new List <NonlinearConstraint>();

            foreach (var c in constraints)
            {
                switch (c.ShouldBe)
                {
                case ConstraintType.EqualTo:
                    equality.Add(c); break;

                case ConstraintType.GreaterThanOrEqualTo:
                    greaterThan.Add(c); break;

                case ConstraintType.LesserThanOrEqualTo:
                    lesserThan.Add(c); break;

                default:
                    throw new ArgumentException("Unknown constraint type.", "constraints");
                }
            }

            this.lesserThanConstraints  = lesserThan.ToArray();
            this.greaterThanConstraints = greaterThan.ToArray();
            this.equalityConstraints    = equality.ToArray();

            this.Solution = new double[numberOfVariables];

            this.dualSolver     = innerSolver;
            dualSolver.Function = objectiveFunction;
            dualSolver.Gradient = objectiveGradient;

            for (int i = 0; i < Solution.Length; i++)
            {
                Solution[i] = Accord.Math.Tools.Random.NextDouble() * 2 - 1;
            }
        }
        private static void test2(IGradientOptimizationMethod inner)
        {
            // maximize 2x + 3y, s.t. 2x² + 2y² <= 50
            //
            // http://www.wolframalpha.com/input/?i=max+2x+%2B+3y%2C+s.t.+2x%C2%B2+%2B+2y%C2%B2+%3C%3D+50

            // Max x' * c
            //  x

            // s.t. x' * A * x <= k
            //      x' * i     = 1
            // lower_bound < x < upper_bound

            double[] c = { 2, 3 };
            double[,] A = { { 2, 0 }, { 0, 2 } };
            double k = 50;

            // Create the objective function
            var objective = new NonlinearObjectiveFunction(2,
                                                           function: (x) => x.InnerProduct(c),
                                                           gradient: (x) => c
                                                           );

            // Test objective
            for (int i = 0; i < 10; i++)
            {
                for (int j = 0; j < 10; j++)
                {
                    double expected = i * 2 + j * 3;
                    double actual   = objective.Function(new double[] { i, j });
                    Assert.AreEqual(expected, actual);
                }
            }


            // Create the optimization constraints
            var constraints = new List <NonlinearConstraint>();

            constraints.Add(new QuadraticConstraint(objective,
                                                    quadraticTerms: A,
                                                    shouldBe: ConstraintType.LesserThanOrEqualTo, value: k
                                                    ));


            // Test first constraint
            for (int i = 0; i < 10; i++)
            {
                for (int j = 0; j < 10; j++)
                {
                    var input = new double[] { i, j };

                    double expected = i * (2 * i + 0 * j) + j * (0 * i + 2 * j);
                    double actual   = constraints[0].Function(input);
                    Assert.AreEqual(expected, actual);
                }
            }


            // Create the solver algorithm
            AugmentedLagrangian solver =
                new AugmentedLagrangian(inner, objective, constraints);

            Assert.AreEqual(inner, solver.Optimizer);

            Assert.IsTrue(solver.Maximize());
            double maxValue = solver.Value;

            Assert.AreEqual(18.02, maxValue, 1e-2);
            Assert.AreEqual(2.77, solver.Solution[0], 1e-2);
            Assert.AreEqual(4.16, solver.Solution[1], 1e-2);
        }
        private static void test1(IGradientOptimizationMethod inner, double tol)
        {
            // maximize 2x + 3y, s.t. 2x² + 2y² <= 50 and x+y = 1

            // Max x' * c
            //  x

            // s.t. x' * A * x <= k
            //      x' * i     = 1
            // lower_bound < x < upper_bound

            double[] c = { 2, 3 };
            double[,] A = { { 2, 0 }, { 0, 2 } };
            double k = 50;

            // Create the objective function
            var objective = new NonlinearObjectiveFunction(2,
                                                           function: (x) => x.InnerProduct(c),
                                                           gradient: (x) => c
                                                           );

            // Test objective
            for (int i = 0; i < 10; i++)
            {
                for (int j = 0; j < 10; j++)
                {
                    double expected = i * 2 + j * 3;
                    double actual   = objective.Function(new double[] { i, j });
                    Assert.AreEqual(expected, actual);
                }
            }


            // Create the optimization constraints
            var constraints = new List <NonlinearConstraint>();

            constraints.Add(new QuadraticConstraint(objective,
                                                    quadraticTerms: A,
                                                    shouldBe: ConstraintType.LesserThanOrEqualTo, value: k
                                                    ));

            constraints.Add(new NonlinearConstraint(objective,
                                                    function: (x) => x.Sum(),
                                                    gradient: (x) => new[] { 1.0, 1.0 },
                                                    shouldBe: ConstraintType.EqualTo, value: 1,
                                                    withinTolerance: 1e-10
                                                    ));


            // Test first constraint
            for (int i = 0; i < 10; i++)
            {
                for (int j = 0; j < 10; j++)
                {
                    double expected = i * (2 * i + 0 * j) + j * (0 * i + 2 * j);
                    double actual   = constraints[0].Function(new double[] { i, j });
                    Assert.AreEqual(expected, actual);
                }
            }


            // Test second constraint
            for (int i = 0; i < 10; i++)
            {
                for (int j = 0; j < 10; j++)
                {
                    double expected = i + j;
                    double actual   = constraints[1].Function(new double[] { i, j });
                    Assert.AreEqual(expected, actual);
                }
            }



            AugmentedLagrangian solver =
                new AugmentedLagrangian(inner, objective, constraints);

            Assert.AreEqual(inner, solver.Optimizer);

            Assert.IsTrue(solver.Maximize());
            double maxValue = solver.Value;

            Assert.AreEqual(6, maxValue, tol);
            Assert.AreEqual(-3, solver.Solution[0], tol);
            Assert.AreEqual(4, solver.Solution[1], tol);
        }
Exemplo n.º 7
0
        private void init(NonlinearObjectiveFunction function,
            IEnumerable<NonlinearConstraint> constraints, IGradientOptimizationMethod innerSolver)
        {
            if (function != null)
            {
                if (function.NumberOfVariables != NumberOfVariables)
                {
                    throw new ArgumentOutOfRangeException("function",
                        "Incorrect number of variables in the objective function. " +
                        "The number of variables must match the number of variables set in the solver.");
                }

                this.Function = function.Function;
                this.Gradient = function.Gradient;
            }

            if (innerSolver == null)
            {
                innerSolver = new BroydenFletcherGoldfarbShanno(NumberOfVariables)
                {
                    LineSearch = Optimization.LineSearch.BacktrackingArmijo,
                    Corrections = 10
                };
            }

            List<NonlinearConstraint> equality = new List<NonlinearConstraint>();
            List<NonlinearConstraint> lesserThan = new List<NonlinearConstraint>();
            List<NonlinearConstraint> greaterThan = new List<NonlinearConstraint>();

            foreach (var c in constraints)
            {
                switch (c.ShouldBe)
                {
                    case ConstraintType.EqualTo:
                        equality.Add(c); break;

                    case ConstraintType.GreaterThanOrEqualTo:
                        greaterThan.Add(c); break;

                    case ConstraintType.LesserThanOrEqualTo:
                        lesserThan.Add(c); break;

                    default:
                        throw new ArgumentException("Unknown constraint type.", "constraints");
                }
            }

            this.lesserThanConstraints = lesserThan.ToArray();
            this.greaterThanConstraints = greaterThan.ToArray();
            this.equalityConstraints = equality.ToArray();

            this.lambda = new double[equalityConstraints.Length];
            this.mu = new double[lesserThanConstraints.Length];
            this.nu = new double[greaterThanConstraints.Length];

            this.dualSolver = innerSolver;
            dualSolver.Function = objectiveFunction;
            dualSolver.Gradient = objectiveGradient;
        }
Exemplo n.º 8
0
 /// <summary>
 ///   Creates a new instance of the Augmented Lagrangian algorithm.
 /// </summary>
 /// 
 /// <param name="innerSolver">The <see cref="IGradientOptimizationMethod">unconstrained 
 ///   optimization method</see> used internally to solve the dual of this optimization 
 ///   problem.</param>
 /// <param name="constraints">
 ///   The <see cref="NonlinearConstraint"/>s to which the solution must be subjected.</param>
 /// 
 public AugmentedLagrangian(IGradientOptimizationMethod innerSolver, IEnumerable<NonlinearConstraint> constraints)
     : base(innerSolver.NumberOfVariables)
 {
     init(null, constraints, innerSolver);
 }
Exemplo n.º 9
0
        /// <summary>
        ///   Creates a new instance of the Augmented Lagrangian algorithm.
        /// </summary>
        /// 
        /// <param name="innerSolver">The <see cref="IGradientOptimizationMethod">unconstrained 
        ///   optimization method</see> used internally to solve the dual of this optimization 
        ///   problem.</param>
        /// <param name="function">The objective function to be optimized.</param>
        /// <param name="constraints">
        ///   The <see cref="NonlinearConstraint"/>s to which the solution must be subjected.</param>
        /// 
        public AugmentedLagrangian(IGradientOptimizationMethod innerSolver,
            NonlinearObjectiveFunction function, IEnumerable<NonlinearConstraint> constraints)
            : base(innerSolver.NumberOfVariables)
        {
            if (innerSolver.NumberOfVariables != function.NumberOfVariables)
                throw new ArgumentException("The inner unconstrained optimization algorithm and the "
                    + "objective function should have the same number of variables.", "function");

            init(function, constraints, innerSolver);
        }
Exemplo n.º 10
0
 /// <summary>
 ///   Creates a new instance of the Augmented Lagrangian algorithm.
 /// </summary>
 ///
 /// <param name="innerSolver">The <see cref="IGradientOptimizationMethod">unconstrained
 ///   optimization method</see> used internally to solve the dual of this optimization
 ///   problem.</param>
 /// <param name="constraints">
 ///   The <see cref="NonlinearConstraint"/>s to which the solution must be subjected.</param>
 ///
 public AugmentedLagrangian(IGradientOptimizationMethod innerSolver, IEnumerable <NonlinearConstraint> constraints)
     : base(innerSolver.NumberOfVariables)
 {
     init(null, constraints, innerSolver);
 }
        private void init(int numberOfVariables, IEnumerable<NonlinearConstraint> constraints, IGradientOptimizationMethod innerSolver)
        {
            this.numberOfVariables = numberOfVariables;

            List<NonlinearConstraint> equality = new List<NonlinearConstraint>();
            List<NonlinearConstraint> lesserThan = new List<NonlinearConstraint>();
            List<NonlinearConstraint> greaterThan = new List<NonlinearConstraint>();

            foreach (var c in constraints)
            {
                switch (c.ShouldBe)
                {
                    case ConstraintType.EqualTo:
                        equality.Add(c); break;

                    case ConstraintType.GreaterThanOrEqualTo:
                        greaterThan.Add(c); break;

                    case ConstraintType.LesserThanOrEqualTo:
                        lesserThan.Add(c); break;

                    default:
                        throw new ArgumentException("Unknown constraint type.", "constraints");
                }
            }

            this.lesserThanConstraints = lesserThan.ToArray();
            this.greaterThanConstraints = greaterThan.ToArray();
            this.equalityConstraints = equality.ToArray();

            this.Solution = new double[numberOfVariables];

            this.dualSolver = innerSolver;
            dualSolver.Function = objectiveFunction;
            dualSolver.Gradient = objectiveGradient;

            for (int i = 0; i < Solution.Length; i++)
                Solution[i] = Accord.Math.Tools.Random.NextDouble() * 2 - 1;
        }
 /// <summary>
 ///   Creates a new instance of the Augmented Lagrangian algorithm.
 /// </summary>
 /// 
 /// <param name="innerSolver">The <see cref="IGradientOptimizationMethod">unconstrained optimization
 ///   method</see> used internally to solve the dual of this optimization problem.</param>
 /// <param name="constraints">The <see cref="NonlinearConstraint"/>s to which the solution must be subjected.</param>
 /// 
 public AugmentedLagrangianSolver(IGradientOptimizationMethod innerSolver,
     IEnumerable<NonlinearConstraint> constraints)
 {
     int numberOfVariables = innerSolver.Parameters;
     init(numberOfVariables, constraints, innerSolver);
 }
        private static void test2(IGradientOptimizationMethod inner)
        {
            // maximize 2x + 3y, s.t. 2x² + 2y² <= 50
            //
            // http://www.wolframalpha.com/input/?i=max+2x+%2B+3y%2C+s.t.+2x%C2%B2+%2B+2y%C2%B2+%3C%3D+50

            // Max x' * c
            //  x

            // s.t. x' * A * x <= k
            //      x' * i     = 1
            // lower_bound < x < upper_bound

            double[] c = { 2, 3 };
            double[,] A = { { 2, 0 }, { 0, 2 } };
            double k = 50;

            // Create the objective function
            var objective = new NonlinearObjectiveFunction(2,
                function: (x) => x.InnerProduct(c),
                gradient: (x) => c
            );

            // Test objective
            for (int i = 0; i < 10; i++)
            {
                for (int j = 0; j < 10; j++)
                {
                    double expected = i * 2 + j * 3;
                    double actual = objective.Function(new double[] { i, j });
                    Assert.AreEqual(expected, actual);
                }
            }


            // Create the optimization constraints
            var constraints = new List<NonlinearConstraint>();

            constraints.Add(new QuadraticConstraint(objective,
                quadraticTerms: A,
                shouldBe: ConstraintType.LesserThanOrEqualTo, value: k
            ));


            // Test first constraint
            for (int i = 0; i < 10; i++)
            {
                for (int j = 0; j < 10; j++)
                {
                    var input = new double[] { i, j };

                    double expected = i * (2 * i + 0 * j) + j * (0 * i + 2 * j);
                    double actual = constraints[0].Function(input);
                    Assert.AreEqual(expected, actual);
                }
            }


            // Create the solver algorithm
            AugmentedLagrangian solver =
                new AugmentedLagrangian(inner, objective, constraints);

            Assert.AreEqual(inner, solver.Optimizer);

            Assert.IsTrue(solver.Maximize());
            double maxValue = solver.Value;

            Assert.AreEqual(18.02, maxValue, 1e-2);
            Assert.AreEqual(2.77, solver.Solution[0], 1e-2);
            Assert.AreEqual(4.16, solver.Solution[1], 1e-2);
        }
        private static void test1(IGradientOptimizationMethod inner, double tol)
        {

            // maximize 2x + 3y, s.t. 2x² + 2y² <= 50 and x+y = 1

            // Max x' * c
            //  x

            // s.t. x' * A * x <= k
            //      x' * i     = 1
            // lower_bound < x < upper_bound

            double[] c = { 2, 3 };
            double[,] A = { { 2, 0 }, { 0, 2 } };
            double k = 50;

            // Create the objective function
            var objective = new NonlinearObjectiveFunction(2,
                function: (x) => x.InnerProduct(c),
                gradient: (x) => c
            );

            // Test objective
            for (int i = 0; i < 10; i++)
            {
                for (int j = 0; j < 10; j++)
                {
                    double expected = i * 2 + j * 3;
                    double actual = objective.Function(new double[] { i, j });
                    Assert.AreEqual(expected, actual);
                }
            }


            // Create the optimization constraints
            var constraints = new List<NonlinearConstraint>();

            constraints.Add(new QuadraticConstraint(objective,
                quadraticTerms: A,
                shouldBe: ConstraintType.LesserThanOrEqualTo, value: k
            ));

            constraints.Add(new NonlinearConstraint(objective,
                function: (x) => x.Sum(),
                gradient: (x) => new[] { 1.0, 1.0 },
                shouldBe: ConstraintType.EqualTo, value: 1,
                withinTolerance: 1e-10
            ));


            // Test first constraint
            for (int i = 0; i < 10; i++)
            {
                for (int j = 0; j < 10; j++)
                {
                    double expected = i * (2 * i + 0 * j) + j * (0 * i + 2 * j);
                    double actual = constraints[0].Function(new double[] { i, j });
                    Assert.AreEqual(expected, actual);
                }
            }


            // Test second constraint
            for (int i = 0; i < 10; i++)
            {
                for (int j = 0; j < 10; j++)
                {
                    double expected = i + j;
                    double actual = constraints[1].Function(new double[] { i, j });
                    Assert.AreEqual(expected, actual);
                }
            }



            AugmentedLagrangian solver =
                new AugmentedLagrangian(inner, objective, constraints);

            Assert.AreEqual(inner, solver.Optimizer);

            Assert.IsTrue(solver.Maximize());
            double maxValue = solver.Value;

            Assert.AreEqual(6, maxValue, tol);
            Assert.AreEqual(-3, solver.Solution[0], tol);
            Assert.AreEqual(4, solver.Solution[1], tol);
        }