| |||||||||||
Catenary - Solving a QCQP Description This model finds the shape of a hanging chain by
minimizing its potential energy.
Source Files By clicking on a file name, a preview is opened at the bottom of this page.
Catenary.java // (c) 2023-2024 Fair Isaac Corporation import static com.dashoptimization.objects.Utils.sum; import com.dashoptimization.XPRSconstants; import com.dashoptimization.XPRSenumerations.ObjSense; import com.dashoptimization.objects.LinExpression; import com.dashoptimization.objects.LinTermList; import com.dashoptimization.objects.Variable; import com.dashoptimization.objects.XpressProblem; /** * QCQP problem (linear objective, convex quadratic constraints) Based on AMPL * model catenary.mod (Source: * http://www.orfe.princeton.edu/~rvdb/ampl/nlmodels/) This model finds the * shape of a hanging chain by minimizing its potential energy. */ public class Catenary { static final int N = 100; // Number of chainlinks static final int L = 1; // Difference in x-coordinates of endlinks static final double H = 2.0 * L / N; // Length of each link public static void main(String[] args) { try (XpressProblem prob = new XpressProblem()) { int i; Variable[] x, y; LinExpression obj; ///// VARIABLES x = prob.addVariables(N + 1).withName("x(%s)").withLB(XPRSconstants.MINUSINFINITY).toArray(); y = prob.addVariables(N + 1).withName("y(%s)").withLB(XPRSconstants.MINUSINFINITY).toArray(); // Bounds: positions of endpoints // Left anchor x[0].fix(0); y[0].fix(0); // Right anchor x[N].fix(L); y[N].fix(0); ///// OBJECTIVE /* Minimise the potential energy: sum(j in 1..N) (y(j-1)+y(j))/2 */ obj = new LinTermList(); for (i = 1; i <= N; i++) { obj.addTerm(y[i - 1], 0.5).addTerm(y[i], 0.5); } prob.setObjective(obj, ObjSense.MINIMIZE); ///// CONSTRAINTS /* * Positions of chainlinks: forall(j in 1..N) (x(j)-x(j-1))^2+(y(j)-y(j-1))^2 <= * H^2 */ for (i = 1; i <= N; i++) { prob.addConstraint(sum(LinExpression.create().addTerm(x[i]).addTerm(x[i - 1], -1).square(), LinExpression.create().addTerm(y[i]).addTerm(y[i - 1], -1).square()).leq(H * H) .setName("Link_" + i)); } ///// SOLVING + OUTPUT prob.lpOptimize(""); // Solve the problem System.out.println("Solution: " + prob.attributes().getObjVal()); for (i = 0; i <= N; i++) { System.out.println(i + ": " + x[i].getSolution() + ", " + y[i].getSolution()); } } } } | |||||||||||
© Copyright 2024 Fair Isaac Corporation. |