예제 #1
0
        public void solve_vectors()
        {
            #region doc_vector
            // 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)
            //

            // Now, we can create an objective function using vectors
            var f = new NonlinearObjectiveFunction(numberOfVariables: 2,

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

                                                   // And this is the vector gradient for the same function:
                                                   gradient: (x) => new[]
            {
                2 * (200 * Math.Pow(x[0], 3) - 200 * x[0] * x[1] + x[0] - 1),     // df/dx = 2(200x³-200xy+x-1)
                200 * (x[1] - x[0] * x[0])                                        // df/dy = 200(y-x²)
            }
                                                   );

            // As before, we state the constraints. However, to illustrate the flexibility
            // of the AugmentedLagrangian, we shall use LinearConstraints to constrain the problem.
            double[,] a = Matrix.Identity(2); // Set up the constraint matrix...
            double[] b = Vector.Zeros(2);     // ...and the values they must be greater than
            int      numberOfEqualities = 0;
            var      linearConstraints  = LinearConstraintCollection.Create(a, b, numberOfEqualities);

            // Finally, we create the non-linear programming solver
            var solver = new AugmentedLagrangian(f, linearConstraints);

            // And attempt to find a minimum
            bool success = solver.Minimize();

            // The solution found was { 1, 1 }
            double[] solution = solver.Solution;

            // with the minimum value zero.
            double minValue = solver.Value;
            #endregion

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

            Assert.IsFalse(double.IsNaN(minValue));
            Assert.IsFalse(double.IsNaN(solver.Solution[0]));
            Assert.IsFalse(double.IsNaN(solver.Solution[1]));
        }
        public void ConstructorTest2()
        {
            // https://github.com/accord-net/framework/issues/171

            int n = 21;
            var Q = Matrix.Diagonal(n, 2.0);
            var d = Vector.Create(3132.0, 6264, 15660, 18792, 21924, 6264, 18792, 21924, 9396, 3132, 12528, 6264, 9396, 18792, 21924, 9396, 3132, 3132, 6264, 15660, 18792);

            int m = 44;

            double[] b =
            {
                703.999,
                -704.001,
                1267.999,
                -1268.001,
                1565.999,
                -1566.001,
                471.999,
                -472.001,
                1425.999,
                -1426.001,
                -107.001,
                -1164.001,
                -57.001,
                -311.001,
                -1433.001,
                -0.001,
                -0.001,
                -788.001,
                -472.001,
                -850.001,
                -273.001,
                -0.001,    -0.001, -0.001, -0.001,
                -0.001,    -0.001, -0.001, -0.001, -0.001,
                -0.001,    -0.001, -0.001, -0.001, -0.001,
                -0.001,    -0.001, -0.001, -0.001, -0.001,
                -0.001,    -0.001, -0.001, -0.001
            };

            var A = Matrix.Create(m, n,
                                  1.0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                  -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                  0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                  0, 0, 0, 0, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                  0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
                                  0, 0, 0, 0, 0, 0, 0, 0, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0,
                                  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0,
                                  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0,
                                  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1,
                                  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, -1, -1, -1, -1,
                                  0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                  0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0,
                                  0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0,
                                  0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0,
                                  -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0,
                                  0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0,
                                  0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0,
                                  0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0,
                                  0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0,
                                  0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1,
                                  1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                  0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                  0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                  0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                  0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                  0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                  0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                  0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                  0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                  0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
                                  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
                                  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
                                  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
                                  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
                                  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
                                  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
                                  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
                                  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1);


            var aa = A.Reshape();
            var qq = Q.Reshape();
            var r  = Quadprog.Compute(n, m, aa, b, 0, qq, d);

            double[] expected = r.Item2;

            var constraints = LinearConstraintCollection.Create(A, b, 0);

            double[] expectedViolation = constraints.Apply(x => x.GetViolation(r.Item2));
            for (int i = 0; i < expectedViolation.Length; i++)
            {
                Assert.IsTrue(expectedViolation[i] >= -1e-11);
            }


            var solver = new GoldfarbIdnani(Q, d.Multiply(-1), A, b, 0);

            Assert.IsTrue(solver.Minimize());

            double[] actual = solver.Solution;
            Assert.IsTrue(actual.IsEqual(expected, 1e-3));


            double[] actualViolation = constraints.Apply(x => x.GetViolation(solver.Solution));
            Assert.IsTrue(actualViolation.IsEqual(expectedViolation, 1e-3));
        }