private static double[,] createConstraintMatrix(int numberOfVariables, LinearConstraint[] constraintArray, out double[] b, out int equalities) { // First of all, separate the equality constraints from the inequalities. constraintArray.StableSort((c1, c2) => c1.ShouldBe.CompareTo(c2.ShouldBe)); int numberOfConstraints = constraintArray.Length; double[,] A = new double[numberOfConstraints, numberOfVariables]; b = new double[numberOfConstraints]; equalities = 0; for (int i = 0; i < constraintArray.Length; i++) { LinearConstraint constraint = constraintArray[i]; if (constraint.NumberOfVariables > numberOfVariables) { throw new ArgumentException("The number of variables in the constraint exceeds the number of variables for the problem."); } for (int j = 0; j < constraint.VariablesAtIndices.Length; j++) { int k = constraint.VariablesAtIndices[j]; if (k >= numberOfVariables) { throw new ArgumentException("The constraint refers to a variable index which is not present on the objective function."); } if (constraint.ShouldBe == ConstraintType.GreaterThanOrEqualTo || constraint.ShouldBe == ConstraintType.EqualTo) { A[i, k] = constraint.CombinedAs[j]; b[i] = constraint.Value; } else if (constraint.ShouldBe == ConstraintType.LesserThanOrEqualTo) { A[i, k] = -constraint.CombinedAs[j]; b[i] = -constraint.Value; } else { throw new ArgumentException("The provided constraint type is not supported."); } } if (constraint.ShouldBe == ConstraintType.EqualTo) { equalities++; } } return(A); }
/// <summary> /// Attempts to create a <see cref="LinearConstraint"/> /// from a <see cref="System.String"/> representation. /// </summary> /// /// <param name="str">The string containing the constraint in textual form.</param> /// <param name="function">The objective function to which this constraint refers to.</param> /// <param name="constraint">The resulting constraint, if it could be parsed.</param> /// <param name="culture">The culture information specifying how /// numbers written in the <paramref name="constraint"/> should /// be parsed. Default is CultureInfo.InvariantCulture.</param> /// /// <returns><c>true</c> if the function could be parsed /// from the string, <c>false</c> otherwise.</returns> /// public static bool TryParse(string str, CultureInfo culture, IObjectiveFunction function, out LinearConstraint constraint) { // TODO: implement this method without the try-catch block. try { constraint = new LinearConstraint(function, str, culture); } catch (FormatException) { constraint = null; return(false); } return(true); }
/// <summary> /// Attempts to create a <see cref="LinearConstraint"/> /// from a <see cref="System.String"/> representation. /// </summary> /// /// <param name="str">The string containing the constraint in textual form.</param> /// <param name="function">The objective function to which this constraint refers to.</param> /// <param name="constraint">The resulting constraint, if it could be parsed.</param> /// /// <returns><c>true</c> if the function could be parsed /// from the string, <c>false</c> otherwise.</returns> /// public static bool TryParse(string str, IObjectiveFunction function, out LinearConstraint constraint) { return(TryParse(str, CultureInfo.InvariantCulture, function, out constraint)); }
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."; } }
/// <summary> /// Attempts to create a <see cref="LinearConstraint"/> /// from a <see cref="System.String"/> representation. /// </summary> /// /// <param name="str">The string containing the constraint in textual form.</param> /// <param name="function">The objective function to which this constraint refers to.</param> /// <param name="constraint">The resulting constraint, if it could be parsed.</param> /// <param name="culture">The culture information specifying how /// numbers written in the <paramref name="constraint"/> should /// be parsed. Default is CultureInfo.InvariantCulture.</param> /// /// <returns><c>true</c> if the function could be parsed /// from the string, <c>false</c> otherwise.</returns> /// public static bool TryParse(string str, CultureInfo culture, IObjectiveFunction function, out LinearConstraint constraint) { // TODO: implement this method without the try-catch block. try { constraint = new LinearConstraint(function, str, culture); } catch (FormatException) { constraint = null; return false; } return true; }
/// <summary> /// Attempts to create a <see cref="LinearConstraint"/> /// from a <see cref="System.String"/> representation. /// </summary> /// /// <param name="str">The string containing the constraint in textual form.</param> /// <param name="function">The objective function to which this constraint refers to.</param> /// <param name="constraint">The resulting constraint, if it could be parsed.</param> /// /// <returns><c>true</c> if the function could be parsed /// from the string, <c>false</c> otherwise.</returns> /// public static bool TryParse(string str, IObjectiveFunction function, out LinearConstraint constraint) { return TryParse(str, CultureInfo.InvariantCulture, function, out constraint); }
/// <summary> /// Computes the optimization algorithm when the user /// presses the "Compute" button in the main interface. /// </summary> /// private void btnCompute_Click(object sender, EventArgs e) { // First, get what the user entered on screen: String strObjective = tbObjective.Text; String[] strConstraints = tbConstraints.Lines; // Check if this is a minimization or maximization task bool minimize = (string)comboBox1.SelectedItem == "min"; // Now we can start creating our function: QuadraticObjectiveFunction function; LinearConstraint[] constraints = new LinearConstraint[strConstraints.Length]; // Attempt to parse the string and create the objective function if (!QuadraticObjectiveFunction.TryParse(strObjective, out function)) { tbSolution.Text = "Invalid objective function."; return; } // Create list of constraints for (int i = 0; i < constraints.Length; i++) { if (!LinearConstraint.TryParse(strConstraints[i], function, out constraints[i])) { tbSolution.Text = "Invalid constraint at line " + i + "."; return; } } // After the text has been parsed, create the solver var solver = new GoldfarbIdnani(function, constraints); // Solve the optimization problem: if (minimize) solver.Minimize(); // the user wants to minimize it else solver.Maximize(); // the user wants to maximize it if (solver.Status == GoldfarbIdnaniStatus.NonPositiveDefinite) { tbSolution.Text = "Function is not positive definite."; return; } else if (solver.Status == GoldfarbIdnaniStatus.NoPossibleSolution) { tbSolution.Text = "No possible solution could be attained."; return; } // Retrieve the computed solution double[] solution = solver.Solution; // And let's format and display it: StringBuilder sb = new StringBuilder(); sb.AppendLine("Solution:"); sb.AppendLine(); sb.AppendLine(" " + strObjective + " = " + solver.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(); }
private static double[,] createConstraintMatrix(int numberOfVariables, LinearConstraint[] constraintArray, out double[] b, out int equalities) { // First of all, separate the equality constraints from the inequalities. constraintArray.StableSort((c1, c2) => c1.ShouldBe.CompareTo(c2.ShouldBe)); int numberOfConstraints = constraintArray.Length; double[,] A = new double[numberOfConstraints, numberOfVariables]; b = new double[numberOfConstraints]; equalities = 0; for (int i = 0; i < constraintArray.Length; i++) { LinearConstraint constraint = constraintArray[i]; if (constraint.NumberOfVariables > numberOfVariables) throw new ArgumentException("The number of variables in the constraint exceeds the number of variables for the problem."); for (int j = 0; j < constraint.VariablesAtIndices.Length; j++) { int k = constraint.VariablesAtIndices[j]; if (k >= numberOfVariables) throw new ArgumentException("The constraint refers to a variable index which is not present on the objective function."); if (constraint.ShouldBe == ConstraintType.GreaterThanOrEqualTo || constraint.ShouldBe == ConstraintType.EqualTo) { A[i, k] = constraint.CombinedAs[j]; b[i] = constraint.Value; } else if (constraint.ShouldBe == ConstraintType.LesserThanOrEqualTo) { A[i, k] = -constraint.CombinedAs[j]; b[i] = -constraint.Value; } else throw new ArgumentException("The provided constraint type is not supported."); } if (constraint.ShouldBe == ConstraintType.EqualTo) equalities++; } return A; }