/// <summary> /// Minimizes the function. /// </summary> /// /// <param name="function">The function to be minimized.</param> /// <returns>The minimum value at the solution found.</returns> /// public double Minimize(QuadraticObjectiveFunction function) { if (function == null) { throw new ArgumentNullException("function"); } return(Minimize(function.GetQuadraticTermsMatrix(), function.GetLinearTermsVector())); }
/// <summary> /// Minimizes the function. /// </summary> /// /// <param name="function">The function to be minimized.</param> /// <returns>The minimum value at the solution found.</returns> /// public double Minimize(QuadraticObjectiveFunction function) { if (function == null) throw new ArgumentNullException("function"); double[,] Q = function.GetQuadraticTermsMatrix(); double[] d = function.GetLinearTermsVector(); return Minimize(Q, d); }
public void GoldfarbIdnaniConstructorTest9() { // Solve the following optimization problem: // // min f(x) = 2x² + xy + y² - 5y // // s.t. -x - 3y >= -2 // -x - y >= 0 // x >= 0 // y >= 0 // double x = 0, y = 0; var f = new QuadraticObjectiveFunction(() => 2 * (x * x) + (x * y) + (y * y) - 5 * y); List<LinearConstraint> constraints = new List<LinearConstraint>(); constraints.Add(new LinearConstraint(f, () => -x - 3 * y >= -2)); constraints.Add(new LinearConstraint(f, () => -x - y >= 0)); constraints.Add(new LinearConstraint(f, () => x >= 0)); constraints.Add(new LinearConstraint(f, () => y >= 0)); GoldfarbIdnaniQuadraticSolver target = new GoldfarbIdnaniQuadraticSolver(2, constraints); double[,] expectedA = { { -1, -3 }, { -1, -1 }, { 1, 0 }, { 0, 1 }, }; double[] expectedb = { -2, 0, 0, 0 }; double[,] expectedQ = { { 4, 1 }, { 1, 2 }, }; double[] expectedd = { 0, -5 }; // Tested against R's QuadProg package /* Qmat = matrix(c(4,1,1,2),2,2) dvec = -c(0, -5) Amat = matrix(c(-1, -3, -1, -1, 1, 0, 0, 1), 2,4) bvec = c(-2, 0, 0, 0) solve.QP(Qmat, dvec, Amat, bvec) */ var actualA = target.ConstraintMatrix; var actualb = target.ConstraintValues; var actualQ = f.GetQuadraticTermsMatrix(); var actuald = f.GetLinearTermsVector(); Assert.IsTrue(expectedA.IsEqual(actualA)); Assert.IsTrue(expectedb.IsEqual(actualb)); Assert.IsTrue(expectedQ.IsEqual(actualQ)); Assert.IsTrue(expectedd.IsEqual(actuald)); double min = target.Minimize(f); double[] solution = target.Solution; Assert.AreEqual(0, solution[0], 1e-10); Assert.AreEqual(0, solution[1], 1e-10); Assert.AreEqual(0.0, min, 1e-10); Assert.AreEqual(0, target.Lagrangian[0], 1e-10); Assert.AreEqual(5, target.Lagrangian[1], 1e-10); Assert.AreEqual(5, target.Lagrangian[2], 1e-10); Assert.AreEqual(0, target.Lagrangian[3], 1e-10); Assert.IsFalse(Double.IsNaN(min)); foreach (double v in target.Solution) Assert.IsFalse(double.IsNaN(v)); foreach (double v in target.Lagrangian) Assert.IsFalse(double.IsNaN(v)); }
public void GoldfarbIdnaniConstructorTest8() { // Solve the following optimization problem: // // min f(x) = x² + 2xy + y² - y // // s.t. x >= 1 // y >= 1 // double x = 0, y = 0; // http://www.wolframalpha.com/input/?i=min+x%C2%B2+%2B+2xy+%2B+y%C2%B2+-+y%2C+x+%3E%3D+1%2C+y+%3E%3D+1 var f = new QuadraticObjectiveFunction(() => (x * x) + 2 * (x * y) + (y * y) - y); List<LinearConstraint> constraints = new List<LinearConstraint>(); constraints.Add(new LinearConstraint(f, () => x >= 1)); constraints.Add(new LinearConstraint(f, () => y >= 1)); GoldfarbIdnaniQuadraticSolver target = new GoldfarbIdnaniQuadraticSolver(2, constraints); double[,] A = { { 1, 0 }, { 0, 1 }, }; double[] b = { 1, 1, }; Assert.IsTrue(A.IsEqual(target.ConstraintMatrix)); Assert.IsTrue(b.IsEqual(target.ConstraintValues)); double[,] Q = { { 2, 2 }, { 2, 2 }, }; double[] d = { 0, -1 }; var actualQ = f.GetQuadraticTermsMatrix(); var actuald = f.GetLinearTermsVector(); Assert.IsTrue(Q.IsEqual(actualQ)); Assert.IsTrue(d.IsEqual(actuald)); bool thrown = false; try { target.Minimize(f); } catch (NonPositiveDefiniteMatrixException) { thrown = true; } Assert.IsTrue(thrown); }
public void GoldfarbIdnaniConstructorTest7() { // Solve the following optimization problem: // // min f(x) = 3x² + 2xy + 3y² - y // // s.t. x >= 1 // y >= 1 // double x = 0, y = 0; // http://www.wolframalpha.com/input/?i=min+x%C2%B2+%2B+2xy+%2B+y%C2%B2+-+y%2C+x+%3E%3D+1%2C+y+%3E%3D+1 var f = new QuadraticObjectiveFunction(() => 3 * (x * x) + 2 * (x * y) + 3 * (y * y) - y); List<LinearConstraint> constraints = new List<LinearConstraint>(); constraints.Add(new LinearConstraint(f, () => x >= 1)); constraints.Add(new LinearConstraint(f, () => y >= 1)); GoldfarbIdnaniQuadraticSolver target = new GoldfarbIdnaniQuadraticSolver(2, constraints); double[,] A = { { 1, 0 }, { 0, 1 }, }; double[] b = { 1, 1, }; Assert.IsTrue(A.IsEqual(target.ConstraintMatrix)); Assert.IsTrue(b.IsEqual(target.ConstraintValues)); double[,] Q = { { 6, 2 }, { 2, 6 }, }; double[] d = { 0, -1 }; var actualQ = f.GetQuadraticTermsMatrix(); var actuald = f.GetLinearTermsVector(); Assert.IsTrue(Q.IsEqual(actualQ)); Assert.IsTrue(d.IsEqual(actuald)); double minValue = target.Minimize(f); double[] solution = target.Solution; Assert.AreEqual(7, minValue); Assert.AreEqual(1, solution[0]); Assert.AreEqual(1, solution[1]); Assert.AreEqual(8, target.Lagrangian[0], 1e-5); Assert.AreEqual(7, target.Lagrangian[1], 1e-5); foreach (double v in target.Solution) Assert.IsFalse(double.IsNaN(v)); foreach (double v in target.Lagrangian) Assert.IsFalse(double.IsNaN(v)); }
public void GoldfarbIdnaniConstructorTest4() { // Solve the following optimization problem: // // min f(x) = 2x² - xy + 4y² - 5x - 6y // // s.t. x - y == 5 (x minus y should be equal to 5) // x >= 10 (x should be greater than or equal to 10) // var f = new QuadraticObjectiveFunction("2x² - xy + 4y² - 5x - 6y"); List<LinearConstraint> constraints = new List<LinearConstraint>(); constraints.Add(new LinearConstraint(f, "x-y = 5")); constraints.Add(new LinearConstraint(f, "x >= 10")); GoldfarbIdnaniQuadraticSolver target = new GoldfarbIdnaniQuadraticSolver(2, constraints); double[,] A = { { 1, -1 }, { 1, 0 }, }; double[] b = { 5, 10, }; Assert.IsTrue(A.IsEqual(target.ConstraintMatrix)); Assert.IsTrue(b.IsEqual(target.ConstraintValues)); double[,] Q = { { +2*2, -1 }, { -1, +4*2 }, }; double[] d = { -5, -6 }; var actualQ = f.GetQuadraticTermsMatrix(); var actuald = f.GetLinearTermsVector(); Assert.IsTrue(Q.IsEqual(actualQ)); Assert.IsTrue(d.IsEqual(actuald)); }
public void GoldfarbIdnaniConstructorTest3() { // Solve the following optimization problem: // // min f(x) = 2x² - xy + 4y² - 5x - 6y // // s.t. x - y == 5 (x minus y should be equal to 5) // x >= 10 (x should be greater than or equal to 10) // // In this example we will be using some symbolic processing. // The following variables could be initialized to any value. double x = 0, y = 0; // Create our objective function using a lambda expression var f = new QuadraticObjectiveFunction(() => 2 * (x * x) - (x * y) + 4 * (y * y) - 5 * x - 6 * y); // Now, create the constraints List<LinearConstraint> constraints = new List<LinearConstraint>(); constraints.Add(new LinearConstraint(f, () => x - y == 5)); constraints.Add(new LinearConstraint(f, () => x >= 10)); // Now we create the quadratic programming solver for 2 variables, using the constraints. GoldfarbIdnaniQuadraticSolver solver = new GoldfarbIdnaniQuadraticSolver(2, constraints); double[,] A = { { 1, -1 }, { 1, 0 }, }; double[] b = { 5, 10, }; Assert.IsTrue(A.IsEqual(solver.ConstraintMatrix)); Assert.IsTrue(b.IsEqual(solver.ConstraintValues)); double[,] Q = { { +2*2, -1 }, { -1, +4*2 }, }; double[] d = { -5, -6 }; var actualQ = f.GetQuadraticTermsMatrix(); var actuald = f.GetLinearTermsVector(); Assert.IsTrue(Q.IsEqual(actualQ)); Assert.IsTrue(d.IsEqual(actuald)); // And attempt to solve it. double minimumValue = solver.Minimize(f); }
/// <summary> /// Maximizes the function. /// </summary> /// /// <param name="function">The function to be maximized.</param> /// <returns>The maximum value at the solution found.</returns> /// public double Maximize(QuadraticObjectiveFunction function) { if (function == null) throw new ArgumentNullException("function"); return Maximize(function.GetQuadraticTermsMatrix(), function.GetLinearTermsVector()); }