FICO
FICO Xpress Optimization Examples Repository
FICO Optimization Community FICO Xpress Optimization Home
Back to examples browserPrevious exampleNext example

Catenary - Solving a QCQP

Description
This model finds the shape of a hanging chain by minimizing its potential energy.

catenary_java.zip[download all files]

Source Files
By clicking on a file name, a preview is opened at the bottom of this page.
Catenary.java[download]





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

Back to examples browserPrevious exampleNext example