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); }