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 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); }
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 GoldfarbIdnaniConstructorTest2() { // 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) // // Lets first group the quadratic and linear terms. The // quadratic terms are +2x², +3y² and -4xy. The linear // terms are -2x and +1y. So our matrix of quadratic // terms can be expressed as: double[,] Q = // 2x² -1xy +4y² { /* x y */ /*x*/ { +2 /*xx*/ * 2, -1 /*xy*/ }, /*y*/ { -1 /*xy*/, +4 /*yy*/ * 2 }, }; // Accordingly, our vector of linear terms is given by: double[] d = { -5 /*x*/, -6 /*y*/ }; // -5x -6y // We have now to express our constraints. We can do it // either by directly specifying a matrix A in which each // line refers to one of the constraints, expressing the // relationship between the different variables in the // constraint, like this: double[,] A = { { 1, -1 }, // This line says that x + (-y) ... (a) { 1, 0 }, // This line says that x alone ... (b) }; double[] b = { 5, // (a) ... should be equal to 5. 10, // (b) ... should be greater than or equal to 10. }; // Equalities must always come first, and in this case // we have to specify how many of the constraints are // actually equalities: int numberOfEqualities = 1; // Alternatively, we may use a more explicitly form: List <LinearConstraint> list = new List <LinearConstraint>(); // Define the first constraint, which involves only x list.Add(new LinearConstraint(numberOfVariables: 1) { // x is the first variable, thus located at // index 0. We are specifying that x >= 10: VariablesAtIndices = new[] { 0 }, // index 0 (x) ShouldBe = ConstraintType.GreaterThanOrEqualTo, Value = 10 }); // Define the second constraint, which involves x and y list.Add(new LinearConstraint(numberOfVariables: 2) { // x is the first variable, located at index 0, and y is // the second, thus located at 1. We are specifying that // x - y = 5 by saying that the variable at position 0 // times 1 plus the variable at position 1 times -1 // should be equal to 5. VariablesAtIndices = new int[] { 0, 1 }, // index 0 (x) and index 1 (y) CombinedAs = new double[] { 1, -1 }, // when combined as x - y ShouldBe = ConstraintType.EqualTo, Value = 5 }); // Now we can finally create our optimization problem var target = new GoldfarbIdnaniQuadraticSolver(numberOfVariables: 2, constraints: list); Assert.IsTrue(A.IsEqual(target.ConstraintMatrix)); Assert.IsTrue(b.IsEqual(target.ConstraintValues)); Assert.AreEqual(numberOfEqualities, target.NumberOfEqualities); // And attempt to solve it. double minimumValue = target.Minimize(Q, d); Assert.AreEqual(170, minimumValue, 1e-10); Assert.AreEqual(10, target.Solution[0]); Assert.AreEqual(05, target.Solution[1]); foreach (double v in target.Solution) { Assert.IsFalse(double.IsNaN(v)); } foreach (double v in target.Lagrangian) { Assert.IsFalse(double.IsNaN(v)); } }
private void button1_Click(object sender, EventArgs e) { String objectiveString = tbObjective.Text; String[] constraintStrings = tbConstraints.Lines; bool minimize = (string)comboBox1.SelectedItem == "min"; QuadraticObjectiveFunction function; LinearConstraint[] constraints = new LinearConstraint[constraintStrings.Length]; try { // Create objective function function = new QuadraticObjectiveFunction(objectiveString); } catch (FormatException) { tbSolution.Text = "Invalid objective function."; return; } // Create list of constraints for (int i = 0; i < constraints.Length; i++) { try { constraints[i] = new LinearConstraint(function, constraintStrings[i]); } catch (FormatException) { tbSolution.Text = "Invalid constraint at line " + i + "."; return; } } // Create solver var solver = new GoldfarbIdnaniQuadraticSolver(function.NumberOfVariables, constraints); try { // Solve the minimization or maximization problem double value = (minimize) ? solver.Minimize(function) : solver.Maximize(function); // Grab the solution found double[] solution = solver.Solution; // Format and display solution StringBuilder sb = new StringBuilder(); sb.AppendLine("Solution:"); sb.AppendLine(); sb.AppendLine(" " + objectiveString + " = " + value); sb.AppendLine(); for (int i = 0; i < solution.Length; i++) { string variableName = function.Indices[i]; sb.AppendLine(" " + variableName + " = " + solution[i]); } tbSolution.Text = sb.ToString(); } catch (NonPositiveDefiniteMatrixException) { tbSolution.Text = "Function is not positive definite."; } catch (ConvergenceException) { tbSolution.Text = "No possible solution could be attained."; } }