/********************************************************
 * Xpress-BCL Java Example Problems
 * ================================
 *
 * file xbqpr12.java
 * `````````````````
 * Small Quadratic Programming example.
 * minimize x1 + x1^2 +2x1x2 +2x2^2 +x4^2
 * s.t. C1:  x1 +2x2 -4x4 >= 0
 * C2: 3x1 -2x3 - x4 <= 100
 * C3: 10 <= x1 +3x2 +3x3 -2x4 <= 30
 * 0<=x1<=20
 * 0<=x2,x3
 * x4 free
 *
 * (c) 2008-2024 Fair Isaac Corporation
 * author: S.Heipcke, Jan. 2000, rev. Dec. 2011
 ********************************************************/

import com.dashoptimization.*;
import java.io.*;

public class xbqpr12 {
  static final int NXPRBvar = 4;

  /***********************************************************************/

  public static void main(String[] args) throws IOException {
    try (XPRBprob p = new XPRBprob("QPr12"); /* Initialize BCL and create a new problem */
        XPRBexprContext context =
            new XPRBexprContext() /* Release XPRBexpr instances at end of block. */) {
      XPRBctr c;
      XPRBexpr le, qobj;
      XPRBvar[] x;
      int i;

      /**** VARIABLES ****/
      x = new XPRBvar[NXPRBvar];
      x[0] = p.newVar("x1", XPRB.PL, 0, 20);
      x[1] = p.newVar("x2");
      x[2] = p.newVar("x3");
      x[3] = p.newVar("x4", XPRB.PL, -XPRB.INFINITY, XPRB.INFINITY);

      /****OBJECTIVE****/
      qobj = new XPRBexpr(); /* Define the objective function */
      qobj.add(x[0]);
      qobj.add((x[0].sqr()).add(x[0].mul(2).mul(x[1])).add(x[1].sqr().mul(2)).add(x[3].sqr()));
      p.setObj(qobj);

      /**** CONSTRAINTS ****/
      p.newCtr("C1", x[0].add(x[1].mul(2)).add(x[3].mul(-4)).gEql(0));
      p.newCtr("C2", x[0].mul(3).add(x[2].mul(-2)).add(x[3].mul(-1)).lEql(100));
      c = p.newCtr("C3", x[0].add(x[1].mul(3)).add(x[2].mul(3)).add(x[3].mul(-2)));
      c.setRange(10, 30);

      /****SOLVING + OUTPUT****/
      p.print(); /* Print out the problem definition */
      p.exportProb(XPRB.MPS, "QPr12"); /* Output the matrix in MPS format */
      p.exportProb(XPRB.LP, "QPr12"); /* Output the matrix in LP format */

      p.setSense(XPRB.MINIM); /* Choose the sense of the  optimization */
      p.lpOptimize(""); /* Solve the QP-problem */

      System.out.println("Objective function value: " + p.getObjVal());
      for (i = 0; i < NXPRBvar; i++) System.out.print(x[i].getName() + ": " + x[i].getSol() + ", ");
      System.out.println();
    }
  }
}
