public void constructorTest5() { // AugmentedLagrangian with NonlinearConstraints // have a Gradient NullReferenceException issue // https://github.com/accord-net/framework/issues/177 // Easy three dimensional minimization in ellipsoid. var function = new NonlinearObjectiveFunction(3, function: x => x[0] * x[1] * x[2], gradient: x => new[] { x[1] * x[2], x[0] * x[2], x[0] * x[1] }); NonlinearConstraint[] constraints = { new NonlinearConstraint(function, constraint: x => (1.0 - x[0] * x[0] - 2.0 * x[1] * x[1] - 3.0 * x[2] * x[2]) >= 0, gradient: x => new[] { -2.0 * x[0], -4.0 * x[1], -6.0 * x[2] }), new NonlinearConstraint(function, constraint: x => x[0] >= 0, gradient: x => new[] { 1.0, 0, 0 }), new NonlinearConstraint(function, constraint: x => x[1] >= 0, gradient: x => new[] { 0, 1.0, 0 }), new NonlinearConstraint(function, constraint: x => - x[2] >= 0, gradient: x => new[] { 0, 0, -1.0 }), }; for (int i = 0; i < constraints.Length; i++) { Assert.AreEqual(ConstraintType.GreaterThanOrEqualTo, constraints[i].ShouldBe); Assert.AreEqual(0, constraints[i].Value); } var inner = new BroydenFletcherGoldfarbShanno(3); inner.LineSearch = LineSearch.BacktrackingArmijo; inner.Corrections = 10; var solver = new AugmentedLagrangian(inner, function, constraints); Assert.AreEqual(inner, solver.Optimizer); Assert.IsTrue(solver.Minimize()); double minimum = solver.Value; double[] solution = solver.Solution; double[] expected = { 1.0 / Math.Sqrt(3.0), 1.0 / Math.Sqrt(6.0), -1.0 / 3.0 }; for (int i = 0; i < expected.Length; i++) { Assert.AreEqual(expected[i], solver.Solution[i], 1e-3); } Assert.AreEqual(-0.078567420132031968, minimum, 1e-4); double expectedMinimum = function.Function(solver.Solution); Assert.AreEqual(expectedMinimum, minimum); }
public void ConstructorTest3() { // minimize f(x) = x*y*z, // s.t. // // 1 - x² - 2y² - 3z² > 0 // x > 0, // y > 0 // // Easy three dimensional minimization in ellipsoid. var function = new NonlinearObjectiveFunction(3, function: x => x[0] * x[1] * x[2], gradient: x => new[] { x[1] * x[2], x[0] * x[2], x[0] * x[1] }); NonlinearConstraint[] constraints = { new NonlinearConstraint(3, function: x => 1.0 - x[0] * x[0] - 2.0 * x[1] * x[1] - 3.0 * x[2] * x[2], gradient: x => new[] { -2.0 * x[0], -4.0 * x[1], -6.0 * x[2] }), new NonlinearConstraint(3, function: x => x[0], gradient: x => new[] { 1.0, 0, 0 }), new NonlinearConstraint(3, function: x => x[1], gradient: x => new[] { 0, 1.0, 0 }), new NonlinearConstraint(3, function: x => - x[2], gradient: x => new[] { 0, 0, -1.0 }), }; for (int i = 0; i < constraints.Length; i++) { Assert.AreEqual(ConstraintType.GreaterThanOrEqualTo, constraints[i].ShouldBe); Assert.AreEqual(0, constraints[i].Value); } var inner = new BroydenFletcherGoldfarbShanno(3); inner.LineSearch = LineSearch.BacktrackingArmijo; inner.Corrections = 10; var solver = new AugmentedLagrangian(inner, function, constraints); Assert.AreEqual(inner, solver.Optimizer); Assert.IsTrue(solver.Minimize()); double minimum = solver.Value; double[] solution = solver.Solution; double[] expected = { 1.0 / Math.Sqrt(3.0), 1.0 / Math.Sqrt(6.0), -1.0 / 3.0 }; for (int i = 0; i < expected.Length; i++) { Assert.AreEqual(expected[i], solver.Solution[i], 1e-3); } Assert.AreEqual(-0.078567420132031968, minimum, 1e-4); double expectedMinimum = function.Function(solver.Solution); Assert.AreEqual(expectedMinimum, minimum); }
public void AugmentedLagrangianSolverConstructorTest4() { // min x*y+ y*z // // s.t. x^2 - y^2 + z^2 - 2 >= 0 // x^2 + y^2 + z^2 - 10 <= 0 // x + y = 1 // 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 )); constraints.Add(new NonlinearConstraint(f, function: () => x + y, gradient: () => new[] { 1.0, 1.0, 0.0 }, shouldBe: ConstraintType.EqualTo, value: 1 ) { Tolerance = 1e-5 }); var solver = new AugmentedLagrangian(f, constraints); solver.Solution[0] = 1; solver.Solution[1] = 1; solver.Solution[2] = 1; Assert.IsTrue(solver.Minimize()); double minValue = solver.Value; Assert.AreEqual(1, solver.Solution[0] + solver.Solution[1], 1e-4); 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])); }
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²) } ); // Now we can start stating the constraints var constraints = new List <NonlinearConstraint>() { // Add the non-negativity constraint for x new NonlinearConstraint(f, // 1st constraint: x should be greater than or equal to 0 function: (x) => x[0], // x shouldBe: ConstraintType.GreaterThanOrEqualTo, value: 0, gradient: (x) => new[] { 1.0, 0.0 } ), // Add the non-negativity constraint for y new NonlinearConstraint(f, // 2nd constraint: y should be greater than or equal to 0 function: (x) => x[1], // y shouldBe: ConstraintType.GreaterThanOrEqualTo, value: 0, gradient: (x) => new[] { 0.0, 1.0 } ) }; // Finally, we create the non-linear programming solver var solver = new AugmentedLagrangian(f, constraints); // 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 static void AugmentedLagrangianSolverConstructorTest4() { double x = 0, y = 0; var f = new NonlinearObjectiveFunction( function: () => 0.3 * x + 0.6 * y, gradient: () => new[] { 0.3, // df/dx 0.6, // df/dy } ); var constraints = new List <NonlinearConstraint>(); constraints.Add(new NonlinearConstraint(f, function: () => 7 * x + 3 * y, gradient: () => new[] { 7.0, 3.0 }, shouldBe: ConstraintType.GreaterThanOrEqualTo, value: 2100 )); constraints.Add(new NonlinearConstraint(f, function: () => y, gradient: () => new[] { 0, 1.0 }, shouldBe: ConstraintType.GreaterThanOrEqualTo, value: 1200 )); constraints.Add(new NonlinearConstraint(f, function: () => x, gradient: () => new[] { 1.0, 0 }, shouldBe: ConstraintType.GreaterThanOrEqualTo, value: 0 )); var solver = new AugmentedLagrangian(f, constraints); solver.Solution[0] = 1; solver.Solution[1] = 1; bool success = solver.Minimize(); double[] solution = solver.Solution; double minValue = solver.Value; Console.WriteLine("Solver Value = " + solver.Value); Console.WriteLine("Solver Minize = " + solver.Minimize()); Console.WriteLine("Solver Solution x = " + solver.Solution[0]); Console.WriteLine("Solver Solution y = " + solver.Solution[1]); Console.ReadKey(); }