/********************************************************
  BCL Example Problems
  ====================

  file xbairport.java
  ```````````````````
  QCQP problem by
      Rodrigo de Barros Nabholz & Maria Aparecida Diniz Ehrhardt
      November 1994, DMA - IMECC- UNICAMP.
  Based on AMPL model airport.mod by Hande Y. Benson
  (Source: http://www.orfe.princeton.edu/~rvdb/ampl/nlmodels/ )
   
  (c) 2008 Fair Isaac Corporation
      author: S.Heipcke, June 2008, rev. Dec. 2011
********************************************************/

import java.io.*;
import com.dashoptimization.*;

public class xbairport
{
 static final int N = 42;

 static final double CX[] = {-6.3, -7.8, -9, -7.2, -5.7, -1.9, -3.5, -0.5, 1.4,
              4, 2.1, 5.5, 5.7, 5.7, 3.8, 5.3, 4.7, 3.3, 0, -1, -0.4, 4.2, 
              3.2, 1.7, 3.3, 2, 0.7, 0.1, -0.1, -3.5, -4, -2.7, -0.5, -2.9,
              -1.2, -0.4, -0.1, -1, -1.7, -2.1, -1.8, 0};
 static final double CY[] = {8, 5.1, 2, 2.6, 5.5, 7.1, 5.9, 6.6, 6.1, 5.6, 4.9, 
              4.7, 4.3, 3.6, 4.1, 3, 2.4, 3, 4.7, 3.4, 2.3, 1.5, 0.5, -1.7, -2,
              -3.1, -3.5, -2.4, -1.3, 0, -1.7, -2.1, -0.4, -2.9, -3.4, -4.3,
              -5.2, -6.5, -7.5, -6.4, -5.1, 0};
 static final double R[] = {0.09, 0.3, 0.09, 0.45, 0.5, 0.04, 0.1, 0.02, 0.02,  
              0.07, 0.4, 0.045, 0.05, 0.056, 0.36, 0.08, 0.07, 0.36, 0.67, 0.38,
              0.37, 0.05, 0.4, 0.66, 0.05, 0.07, 0.08, 0.3, 0.31, 0.49, 0.09, 
              0.46, 0.12, 0.07, 0.07, 0.09, 0.05, 0.13, 0.16, 0.46, 0.25, 0.1};

 public static void main(String[] args) throws IOException
 {
  XPRB bcl;
  XPRBprob prob;
  int i,j;
  XPRBvar[] x,y;                        /* x-/y-coordinates to determine */
  XPRBexpr qe;
  XPRBctr cobj, c;

  bcl = new XPRB();                     /* Initialize BCL */
  prob = bcl.newProb("airport");        /* Create a new problem in BCL */

/**** VARIABLES ****/
  x = new XPRBvar[N];
  for(i=0;i<N;i++) 
   x[i] = prob.newVar("x(" + (i+1) + ")", XPRB.PL, -10, 10);
  y = new XPRBvar[N];
  for(i=0;i<N;i++) 
   y[i] = prob.newVar("y(" + (i+1) + ")", XPRB.PL, -10, 10);

/****OBJECTIVE****/
/* Minimize the total distance between all points */
/*  sum(i in 1..N-1,j in i+1..N) ((x(i)-x(j))^2+(y(i)-y(j))^2)  */
  qe = new XPRBexpr();
  for(i=0;i<N-1;i++)
   for(j=i+1;j<N;j++) qe .add((x[i].add(x[j].mul(-1))).sqr()) 
                         .add((y[i].add(y[j].mul(-1))).sqr());
  cobj = prob.newCtr("TotDist", qe);
  prob.setObj(cobj);                     /* Set objective function */ 

/**** CONSTRAINTS ****/
/* All points within given distance of their target location */
/*  (x(i)-CX(i))^2+(y(i)-CY(i))^2 <= R(i)  */
  for(i=0;i<N;i++)
   c = prob.newCtr("LimDist", (x[i].add(-CX[i])).sqr() 
                   .add( (y[i].add(-CY[i])).sqr()) .lEql(R[i]) );
 
/****SOLVING + OUTPUT****/
  prob.setSense(XPRB.MINIM);             /* Choose the sense of optimization */
 
/* Problem printing and matrix output: */
/*
  prob.print(); 
  prob.exportProb(XPRB.MPS, "airport");
  prob.exportProb(XPRB.LP, "airport");
*/

  prob.lpOptimize("");                   /* Solve the problem */

  System.out.println("Solution: " + prob.getObjVal());
  for(i=0;i<N;i++)
   System.out.println(x[i].getName() + ": " + x[i].getSol() + ", " +
                      y[i].getName() + ": " + y[i].getSol());

/* Delete the problem */
  prob.finalize();              
  prob=null;
 }
}  
