Initializing help system before first use

Implementation with Java

Topics covered in this section:

The Java interface contains classes and methods for stating optimization models in a convenient way.

The following Java program implements the LP example introduced in Chapter 2:

import static com.dashoptimization.objects.Utils.scalarProduct;
import static com.dashoptimization.objects.Utils.sum;
import static java.util.stream.IntStream.range;

import com.dashoptimization.DefaultMessageListener;
import com.dashoptimization.XPRSenumerations.ObjSense;
import com.dashoptimization.objects.Variable;
import com.dashoptimization.objects.XpressProblem;

/** Modeling a small LP problem to perform portfolio optimization. */
public class FolioLP {
    /* Number of shares */
    private static final int NSHARES = 10;
    /* Number of high-risk shares */
    private static final int NRISK = 5;
    /* Number of North-American shares */
    private static final int NNA = 4;
    /* Estimated return in investment */
    private static final double[] RET = new double[] { 5, 17, 26, 12, 8, 9, 7, 6, 31, 21 };
    /* High-risk values among shares */
    private static final int[] RISK = new int[] { 1, 2, 3, 8, 9 };
    /* Shares issued in N.-America */
    private static final int[] NA = new int[] { 0, 1, 2, 3 };

    private static void printProblemStatus(XpressProblem prob) {
        System.out.println(String.format("Problem status:%n\tSolve status: %s%n\tSol status:
                %s", prob.attributes().getSolveStatus(), prob.attributes().getSolStatus()));
    }

    public static void main(String[] args) {
        try (XpressProblem prob = new XpressProblem()) {
            // Output all messages.
            prob.callbacks.addMessageCallback(DefaultMessageListener::console);

            /**** VARIABLES ****/
            Variable[] frac = prob.addVariables(NSHARES)
                    /* Fraction of capital used per share */
                    .withName(i -> String.format("frac_%d", i))
                    /* Upper bounds on the investment per share */
                    .withUB(0.3).toArray();

            /**** CONSTRAINTS ****/
            /* Limit the percentage of high-risk values */
            prob.addConstraint(sum(NRISK, i -> frac[RISK[i]]).leq(1.0 / 3.0).setName("Risk"));

            /* Minimum amount of North-American values */
            prob.addConstraint(sum(NNA, i -> frac[NA[i]]).geq(0.5).setName("NA"));

            /* Spend all the capital */
            prob.addConstraint(sum(frac).eq(1.0).setName("Cap"));

            /* Objective: maximize total return */
            prob.setObjective(scalarProduct(frac, RET), ObjSense.MAXIMIZE);

            /* Solve */
            prob.optimize();

            /* Solution printing */
            printProblemStatus(prob);
            System.out.println("Total return: " + prob.attributes().getObjVal());
            double[] sol = prob.getSolution();
            range(0, NSHARES).forEach(i -> System.out
                    .println(String.format("%s : %.2f%s", frac[i].getName(), 100.0
                           * frac[i].getValue(sol), "%")));
        }
    }
}

Let us now have a closer look at what we have just written.

Initialization

To use the Java interface you need to import the XpressProblem class, which you use to create variables and constraints. Other useful classes for the problem being formulated are also imported at this point.

If the software has not been initialized previously, the Java interface is initialized automatically when you create the first problem instance:

XpressProblem prob = new XpressProblem()

General structure

The definition of the model itself starts with the creation of the decision variables (method addVariables), followed by the definition of the objective function and the constraints. The method withUB is used to set the upper bounds on the decision variables frac.

You can create constraints by using linear expressions, as shown in the example. Equivalently, they can be constructed from expression objects, such as the constraint limiting the percentage of high-risk shares:

LinExpression CRisk = LinExpression.create();
for(int s=0;s<NRISK;s++) CRisk.addTerm(frac[RISK[s]], 1);
prob.addConstraint(CRisk.leq(1.0 / 3.0).setName("Risk"));

This assumes that the LinExpression class has been imported.

Using the withName function to give names to modeling objects (decision variables, constraints, etc.) as shown in our example program is optional. Names can be useful for debugging but otherwise have no effect on the optimizer.

Solving

Prior to launching the solver, the objective expression scalarProduct(frac, RET) is set to be maximized with a call to prob.setObjective(scalarProduct(frac, RET), ObjSense.MAXIMIZE). With the method optimize, the Xpress Optimizer is called to maximize the objective function subject to all constraints that have been defined. Since the problem contains only continuous variables, an LP algorithm will be determined automatically.

Output printing

The last few lines print out the value of the optimal solution and the solution values for all variables.


© 2001-2025 Fair Isaac Corporation. All rights reserved. This documentation is the property of Fair Isaac Corporation (“FICO”). Receipt or possession of this documentation does not convey rights to disclose, reproduce, make derivative works, use, or allow others to use it except solely for internal evaluation purposes to determine whether to purchase a license to the software described in this documentation, or as otherwise set forth in a written software license agreement between you and FICO (or a FICO affiliate). Use of this documentation and the software described in it must conform strictly to the foregoing permitted uses, and no other use is permitted.