/********************************************************
  Xpress-BCL Java Example Problems
  ================================

  file folioinit2.java
  ````````````````````
  Modeling a small LP problem
  to perform portfolio optimization.
  Initialization with error handling.

  (c) 2008-2023 Fair Isaac Corporation
      author: S.Heipcke, 2003, rev. Dec. 2011
********************************************************/

import com.dashoptimization.*;

public class folioinit2 {
    static final int NSHARES = 10;     /* Number of shares */
    static final int NRISK = 5;        /* Number of high-risk shares */
    static final int NNA = 4;          /* Number of North-American shares */

    static final double[] RET = {5,17,26,12,8,9,7,6,31,21};
    /* Estimated return in investment  */
    static final int[] RISK = {1,2,3,8,9};  /* High-risk values among shares */
    static final int[] NA = {0,1,2,3};      /* Shares issued in N.-America */

    static final String[] LPSTATUS = {"not loaded", "optimal", "infeasible",
                                      "worse than cutoff", "unfinished", "unbounded", "cutoff in dual",
                                      "unsolved", "nonconvex"};

    public static void main(String[] args) {
        int s;
        XPRBexpr Risk,Na,Return,Cap;
        XPRBvar[] frac;                    /* Fraction of capital used per share */

        try (XPRB bcl = new XPRB()) {      /* Initialize BCL */

            try (XPRBprob p = bcl.newProb("FolioLP")) {        /* Create a new problem in BCL */

                /* Create the decision variables */
                frac = new XPRBvar[NSHARES];
                for(s=0;s<NSHARES;s++) frac[s] = p.newVar("frac");  /*, XPRB.PL, 0, 0.3); */

                /* Objective: total return */
                Return = new XPRBexpr();
                for(s=0;s<NSHARES;s++) Return.add(frac[s].mul(RET[s]));
                p.setObj(Return);                  /* Set the objective function */

                /* Limit the percentage of high-risk values */
                Risk = new XPRBexpr();
                for(s=0;s<NRISK;s++) Risk.add(frac[RISK[s]]);
                p.newCtr("Risk", Risk.lEql(1.0/3) );

                /* Minimum amount of North-American values */
                Na = new XPRBexpr();
                for(s=0;s<NNA;s++) Na.add(frac[NA[s]]);
                p.newCtr("NA", Na.gEql(0.5) );

                /* Spend all the capital */
                Cap = new XPRBexpr();
                for(s=0;s<NSHARES;s++) Cap.add(frac[s]);
                p.newCtr(Cap.eql(1));

                /* Upper bounds on the investment per share */
                for(s=0;s<NSHARES;s++) frac[s].setUB(0.3);

                /* Solve the problem */
                p.setSense(XPRB.MAXIM);
                p.lpOptimize("");

                System.out.println("Problem status: " + LPSTATUS[p.getLPStat()]);

                /* Solution printing */
                System.out.println("Total return: " + p.getObjVal());
                for(s=0;s<NSHARES;s++)
                    System.out.println(s + ": " + frac[s].getSol()*100 + "%");
            }
        }
        catch(XPRBlicenseError e) {
            System.out.println("Initialization failed (licensing problem).");
            System.exit(1);
        }
        catch(XPRBerror e) {
            System.out.println("Initialization failed.");
            System.exit(1);
        }
    }
}
