コード例 #1
0
        public void AugmentedLagrangianSolverConstructorTest3()
        {
            // min x*y+ y*z
            //
            // s.t.  x^2 - y^2 + z^2 - 2  >= 0
            //       x^2 + y^2 + z^2 - 10 <= 0
            //

            double x = 0, y = 0, z = 0;

            var f = new NonlinearObjectiveFunction(

                function: () => x * y + y * z,

                gradient: () => new[]
            {
                y,         // df/dx
                x + z,     // df/dy
                y,         // df/dz
            }

                );


            var constraints = new List <NonlinearConstraint>();

            constraints.Add(new NonlinearConstraint(f,

                                                    function: () => x * x - y * y + z * z,
                                                    gradient: () => new[] { 2 * x, -2 * y, 2 * z },

                                                    shouldBe: ConstraintType.GreaterThanOrEqualTo, value: 2
                                                    ));

            constraints.Add(new NonlinearConstraint(f,

                                                    function: () => x * x + y * y + z * z,
                                                    gradient: () => new[] { 2 * x, 2 * y, 2 * z },

                                                    shouldBe: ConstraintType.LesserThanOrEqualTo, value: 10
                                                    ));

            var solver = new AugmentedLagrangianSolver(3, constraints);

            solver.Solution[0] = 1;
            solver.Solution[1] = 1;
            solver.Solution[2] = 1;

            double minValue = solver.Minimize(f);

            Assert.AreEqual(-6.9, minValue, 1e-1);
            Assert.AreEqual(+1.73, solver.Solution[0], 1e-2);
            Assert.AreEqual(-2.00, solver.Solution[1], 1e-2);
            Assert.AreEqual(+1.73, solver.Solution[2], 1e-2);

            Assert.IsFalse(Double.IsNaN(minValue));
            Assert.IsFalse(Double.IsNaN(solver.Solution[0]));
            Assert.IsFalse(Double.IsNaN(solver.Solution[1]));
            Assert.IsFalse(Double.IsNaN(solver.Solution[2]));
        }
コード例 #2
0
        public static double solve(bool isFine, IEnumerable <Constraint> cons)
        {
            var constraints = cons.ToArray();

            // Get the parameters that need solving by selecting "free" ones
            Parameter[] x = constraints.SelectMany(p => p)
                            .Distinct()
                            .Where(p => p.free == true)
                            .ToArray();

            Console.WriteLine("Number of free vars is " + x.Length);

            // Wrap our constraint error function for Accord.NET
            Func <double[], double> objective = args => {
                int i = 0;
                foreach (var arg in args)
                {
                    x [i].Value = arg;
                    i++;
                }
                return(Constraint.calc(constraints));
            };


            var nlConstraints = new List <NonlinearConstraint> ();

            // Finally, we create the non-linear programming solver
            var solver = new AugmentedLagrangianSolver(x.Length, nlConstraints);

            // Copy in the initial conditions
            x.Select(v => v.Value).ToArray().CopyTo(solver.Solution, 0);

            // And attempt to solve the problem
            return(solver.Minimize(LogWrap(objective), LogWrap(Grad(x.Length, objective))));
        }
コード例 #3
0
        public void AugmentedLagrangianSolverConstructorTest2()
        {
            // min 100(y-x*x)²+(1-x)²
            //
            // s.t.  x >= 0
            //       y >= 0
            //

            var f = new NonlinearObjectiveFunction(2,

                                                   function: (x) => 100 * Math.Pow(x[1] - x[0] * x[0], 2) + Math.Pow(1 - x[0], 2),

                                                   gradient: (x) => new[]
            {
                2.0 * (200.0 * Math.Pow(x[0], 3) - 200.0 * x[0] * x[1] + x[0] - 1),     // df/dx
                200 * (x[1] - x[0] * x[0])                                              // df/dy
            }

                                                   );


            var constraints = new List <NonlinearConstraint>();

            constraints.Add(new NonlinearConstraint(f,

                                                    function: (x) => x[0],
                                                    gradient: (x) => new[] { 1.0, 0.0 },

                                                    shouldBe: ConstraintType.GreaterThanOrEqualTo, value: 0
                                                    ));

            constraints.Add(new NonlinearConstraint(f,

                                                    function: (x) => x[1],
                                                    gradient: (x) => new[] { 0.0, 1.0 },

                                                    shouldBe: ConstraintType.GreaterThanOrEqualTo, value: 0
                                                    ));

            var solver = new AugmentedLagrangianSolver(2, constraints);

            double minValue = solver.Minimize(f);

            Assert.AreEqual(0, minValue, 1e-10);
            Assert.AreEqual(1, solver.Solution[0], 1e-10);
            Assert.AreEqual(1, solver.Solution[1], 1e-10);

            Assert.IsFalse(Double.IsNaN(minValue));
            Assert.IsFalse(Double.IsNaN(solver.Solution[0]));
            Assert.IsFalse(Double.IsNaN(solver.Solution[1]));
        }
コード例 #4
0
        public void AugmentedLagrangianSolverConstructorTest1()
        {
            Accord.Math.Tools.SetupGenerator(0);

            // min 100(y-x*x)²+(1-x)²
            //
            // s.t.  x <= 0
            //       y <= 0
            //

            var f = new NonlinearObjectiveFunction(2,

                                                   function: (x) => 100 * Math.Pow(x[1] - x[0] * x[0], 2) + Math.Pow(1 - x[0], 2),

                                                   gradient: (x) => new[]
            {
                2.0 * (200.0 * x[0] * x[0] * x[0] - 200.0 * x[0] * x[1] + x[0] - 1), // df/dx
                200 * (x[1] - x[0] * x[0])                                           // df/dy
            }

                                                   );


            var constraints = new List <NonlinearConstraint>();

            constraints.Add(new NonlinearConstraint(f,

                                                    function: (x) => x[0],
                                                    gradient: (x) => new[] { 1.0, 0.0 },

                                                    shouldBe: ConstraintType.LesserThanOrEqualTo, value: 0
                                                    ));

            constraints.Add(new NonlinearConstraint(f,

                                                    function: (x) => x[1],
                                                    gradient: (x) => new[] { 0.0, 1.0 },

                                                    shouldBe: ConstraintType.LesserThanOrEqualTo, value: 0
                                                    ));

            var solver = new AugmentedLagrangianSolver(2, constraints);

            double minValue = solver.Minimize(f);

            Assert.AreEqual(1, minValue, 1e-5);
            Assert.AreEqual(0, solver.Solution[0], 1e-5);
            Assert.AreEqual(0, solver.Solution[1], 1e-5);
        }
コード例 #5
0
        public IConstrainedSolver Create()
        {
            var lagrangianCompiler     = new LagrangianCompiler();
            var unconstrainedOptimizer = new LBFGSOptimizer(30);
            //var unconstrainedOptimizer = new ConjugateGradientOptimizer();
            var iterations = new AugmentedLagrangianIterations(
                unconstrainedOptimizer,
                lagrangianCompiler,
                startConstraintsPenalty: 10,
                constraintsPenaltyMax: 1E3,
                maxConstraintsNormLowerBound: 1E-8,
                lagrangianGradientNormLowerBound: 4E-7);

            var convergenceTest = new ConstraintsNormWithGradientNormConvergenceTest(
                constraintsNormMax: 1E-8,
                lagrangianGradientNormMax: 2E-6,
                maxIterations: 1000);
            var solver = new AugmentedLagrangianSolver(convergenceTest, iterations);

            return(solver);
        }
コード例 #6
0
        public void AugmentedLagrangianSolverConstructorTest7()
        {
            // maximize 2x + 3y, s.t. 2x² + 2y² <= 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++)
                {
                    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);
                }
            }


            // Create the solver algorithm
            AugmentedLagrangianSolver solver =
                new AugmentedLagrangianSolver(2, constraints);

            double maxValue = solver.Maximize(objective);

            Assert.AreEqual(18.02, maxValue, 0.01);
            Assert.AreEqual(2.77, solver.Solution[0], 1e-2);
            Assert.AreEqual(4.16, solver.Solution[1], 1e-2);
        }
コード例 #7
0
        public void AugmentedLagrangianSolverConstructorTest5()
        {
            // Suppose we would like to minimize the following function:
            //
            //    f(x,y) = min 100(y-x²)²+(1-x)²
            //
            // Subject to the constraints
            //
            //    x >= 0  (x must be positive)
            //    y >= 0  (y must be positive)
            //

            double x = 0, y = 0;


            // First, we create our objective function
            var f = new NonlinearObjectiveFunction(

                // This is the objective function:  f(x,y) = min 100(y-x²)²+(1-x)²
                function: () => 100 * Math.Pow(y - x * x, 2) + Math.Pow(1 - x, 2),

                // The gradient vector:
                gradient: () => new[]
            {
                2 * (200 * Math.Pow(x, 3) - 200 * x * y + x - 1),     // df/dx = 2(200x³-200xy+x-1)
                200 * (y - x * x)                                     // df/dy = 200(y-x²)
            }

                );


            // Now we can start stating the constraints
            var constraints = new List <NonlinearConstraint>();

            // Add the non-negativity constraint for x
            constraints.Add(new NonlinearConstraint(f,

                                                    // 1st constraint: x should be greater than or equal to 0
                                                    function: () => x, shouldBe: ConstraintType.GreaterThanOrEqualTo, value: 0,

                                                    gradient: () => new[] { 1.0, 0.0 }
                                                    ));

            // Add the non-negativity constraint for y
            constraints.Add(new NonlinearConstraint(f,

                                                    // 2nd constraint: y should be greater than or equal to 0
                                                    function: () => y, shouldBe: ConstraintType.GreaterThanOrEqualTo, value: 0,

                                                    gradient: () => new[] { 0.0, 1.0 }
                                                    ));


            // Finally, we create the non-linear programming solver
            var solver = new AugmentedLagrangianSolver(2, constraints);

            // And attempt to solve the problem
            double minValue = solver.Minimize(f);

            Assert.AreEqual(0, minValue, 1e-10);
            Assert.AreEqual(1, solver.Solution[0], 1e-10);
            Assert.AreEqual(1, solver.Solution[1], 1e-10);

            Assert.IsFalse(Double.IsNaN(minValue));
            Assert.IsFalse(Double.IsNaN(solver.Solution[0]));
            Assert.IsFalse(Double.IsNaN(solver.Solution[1]));
        }