Example #1
0
int main(int argc, const char *argv[])
{
     ClpInterior  model;
     int status;
     if (argc < 2) {
#if defined(SAMPLEDIR)
          status = model.readMps(SAMPLEDIR "/p0033.mps", true);
#else
          fprintf(stderr, "Do not know where to find sample MPS files.\n");
          exit(1);
#endif
     } else
          status = model.readMps(argv[1]);
     if (status) {
          printf("errors on input\n");
          exit(77);
     }
     // ** note this does not have presolve
#ifdef WSSMP_BARRIER
     ClpCholeskyWssmp * cholesky = new ClpCholeskyWssmp();
#else
     ClpCholeskyDense * cholesky = new ClpCholeskyDense();
#endif
     model.setCholesky(cholesky);
     model.primalDual();
     // Do crossover
     ClpSimplex model2(model);
     // make sure no status left
     model2.createStatus();
     model2.primal(1);
     return 0;
}
Example #2
0
File: pdco.cpp Project: coin-or/Clp
int main(int argc, const char *argv[])
{

     // Get model in some way
     ClpInterior model;
     // Open graph and parameter files
     //FILE *fpin = fopen("./g.graph","r");
     //FILE *fpp = fopen("./gparm","r");
     FILE *fpin = fopen("./g.tiny", "r");
     FILE *fpp = fopen("./gparm.tiny", "r");
     assert(fpin);
     assert(fpp);
     myPdco stuff(model, fpin, fpp);
     Info info;
     Outfo outfo;
     Options options;


     /*
      *     Set the input parameters for LSQR.
      */
     options.gamma = stuff.getD1();
     options.delta = stuff.getD2();
     options.MaxIter = 40;
     options.FeaTol = 5.0e-4;
     options.OptTol = 5.0e-4;
     options.StepTol = 0.99;
     //  options.x0min = 10.0/num_cols;
     options.x0min = 0.01;
     options.z0min = 0.01;
     options.mu0 = 1.0e-6;
     options.LSmethod = 3;   // 1=Cholesky    2=QR    3=LSQR
     options.LSproblem = 1;  // See below
     options.LSQRMaxIter = 999;
     options.LSQRatol1 = 1.0e-3; // Initial  atol
     options.LSQRatol2 = 1.0e-6; // Smallest atol (unless atol1 is smaller)
     options.LSQRconlim = 1.0e12;
     info.atolmin = options.LSQRatol2;
     info.LSdamp = 0.0;
     // These are already set?
     model.xsize_ = 50.0 / (model.numberColumns());
     model.xsize_ = CoinMin(1.0, model.xsize_);

     /*
      *     Solve the test problem
      */
     model.pdco(&stuff, options, info, outfo);

     /*
      *     Examine the results.
      *     Print the residual norms RNORM and ARNORM given by LSQR, and then compute
      */
     return 0;
}
Example #3
0
// To define the function sciclp as a C function and allow this function to be loaded easily in scilab
extern "C" int sciclp(char * fname)
{
  ClpSimplex      * modelSimplex  = NULL;
  ClpInterior     * modelInterior = NULL;
  ClpModel        * modelBase     = NULL;
  ClpCholeskyBase * cholesky      = NULL; 
  DerivedHandler  * printer       = NULL;
  ClpSolve          modelSolve; // YC: we can set some parameters via CbcSolve
  CoinPackedMatrix  A_matrix, Q_matrix;
#ifdef HANDLE_CTRLC
  MyClpEventHandler SciClpEventHandler;
  SciClpEventHandler.setInCbc(false);
#endif
  int Log = 0;
  int ncols = 0, nrows = 0, i, j, nz = 0, writemps = 0;
  int count = 0, status = 0, type;
  char  * writemps_filename = NULL;
  SciSparse S_A, S_Q;
  
  if (Rhs<LASTPARAM) 
    {
      Scierror(999,"%s: 12 inputs required in call to %s. Bug in clp.sci ?...\n", fname, fname);
      return 0;
    }
		
  /* Get pointers to input */

  int n_a,     m_a,     * a_addr     = NULL;
  int n_c,     m_c,     * c_addr     = NULL;
  int n_lhs,   m_lhs,   * lhs_addr   = NULL;
  int n_rhs,   m_rhs,   * rhs_addr   = NULL;
  int n_upper, m_upper, * upper_addr = NULL;
  int n_lower, m_lower, * lower_addr = NULL;
  int * vtype_addr = NULL;
  int * ctype_addr = NULL;
  int n_q,     m_q,     * q_addr     = NULL;
  double * c = NULL, * lhs = NULL, * rhs = NULL, * lower = NULL, * upper = NULL, * a = NULL;
  double * q = NULL;
  char * ctype = NULL, * vtype = NULL;
  SciErr _SciErr;
  
  _SciErr = getVarAddressFromPosition(pvApiCtx, C_IN, &c_addr); SCICOINOR_ERROR;
  _SciErr = getMatrixOfDouble(pvApiCtx, c_addr, &n_c, &m_c, &c); SCICOINOR_ERROR;
  _SciErr = getVarAddressFromPosition(pvApiCtx, LHS_IN, &lhs_addr); SCICOINOR_ERROR;
  _SciErr = getMatrixOfDouble(pvApiCtx, lhs_addr, &n_lhs, &m_lhs, &lhs); SCICOINOR_ERROR;
  _SciErr = getVarAddressFromPosition(pvApiCtx, RHS_IN, &rhs_addr); SCICOINOR_ERROR;
  _SciErr = getMatrixOfDouble(pvApiCtx, rhs_addr, &n_rhs, &m_rhs, &rhs); SCICOINOR_ERROR;
  _SciErr = getVarAddressFromPosition(pvApiCtx, LOWER_IN, &lower_addr); SCICOINOR_ERROR;
  _SciErr = getMatrixOfDouble(pvApiCtx, lower_addr, &n_lower, &m_lower, &lower); SCICOINOR_ERROR;
  _SciErr = getVarAddressFromPosition(pvApiCtx, UPPER_IN, &upper_addr); SCICOINOR_ERROR;
  _SciErr = getMatrixOfDouble(pvApiCtx, upper_addr, &n_upper, &m_upper, &upper); SCICOINOR_ERROR;
  _SciErr = getVarAddressFromPosition(pvApiCtx, CTYPE_IN, &ctype_addr); SCICOINOR_ERROR;
  getAllocatedSingleString(pvApiCtx, ctype_addr, &ctype);
  _SciErr = getVarAddressFromPosition(pvApiCtx, VTYPE_IN, &vtype_addr); SCICOINOR_ERROR;
  getAllocatedSingleString(pvApiCtx, vtype_addr, &vtype);

  ncols = n_c   * m_c;   /* Length of c == number of columns */
  nrows = n_rhs * m_rhs; /* length of b == number of rows    */
  if (nrows==0) nrows = n_lhs * m_lhs;

#ifdef DEBUG
  sciprint("DEBUG: c           size: m = %d n = %d\n", m_c,     n_c);
  sciprint("DEBUG: lhs         size: m = %d n = %d\n", m_lhs,   n_lhs);
  sciprint("DEBUG: rhs         size: m = %d n = %d\n", m_rhs,   n_rhs);
  sciprint("DEBUG: lower       size: m = %d n = %d\n", m_lower, n_lower);
  sciprint("DEBUG: upper       size: m = %d n = %d\n", m_upper, n_upper);
  sciprint("DEBUG: ctype       size: m = %d n = %d\n", m_ctype, n_ctype);
  sciprint("DEBUG: vtype       size: m = %d n = %d\n", m_vtype, n_vtype);
  sciprint("DEBUG: nrows = %d\n", nrows);
  sciprint("DEBUG: ncols = %d\n", ncols);

  sciprint("c :");
  for(i=0;i<ncols; i++) sciprint("%f ",*(c+i));
  sciprint("\n");
  sciprint("lhs :");
  for(i=0;i<nrows; i++) sciprint("%f ",*(lhs+i));
  sciprint("\n");
  sciprint("rhs :");
  for(i=0;i<nrows; i++) sciprint("%f ",*(rhs+i));
  sciprint("\n");
  sciprint("lb :");
  for(i=0;i<ncols; i++) sciprint("%f ",*(lower+i));
  sciprint("\n");
  sciprint("ub :");
  for(i=0;i<ncols; i++) sciprint("%f ",*(upper+i));
  sciprint("\n");
  sciprint("ctype = %s\n", ctype);
  sciprint("vtype = %s\n", vtype);
#endif

  //////////////////
  // The A matrix //
  //////////////////

  _SciErr = getVarAddressFromPosition(pvApiCtx, A_IN, &a_addr); SCICOINOR_ERROR;
  _SciErr = getVarType(pvApiCtx, a_addr, &type); SCICOINOR_ERROR;
  if(type!=sci_sparse)
    {
#ifdef DEBUG
      sciprint("DEBUG: A_IN is not sparse\n");
#endif
      
      _SciErr = getMatrixOfDouble(pvApiCtx, a_addr, &m_a, &n_a, &a); SCICOINOR_ERROR;
      A_matrix.setDimensions(nrows,ncols);
      
      if (a==NULL) 
	{
	  Scierror(999,"%s: invalid value of matrix a\n",fname);
	  
	  freeAllocatedSingleString(ctype);
	  freeAllocatedSingleString(vtype);
	  
	  return 0;
	}
      
      for(i=0; i<m_a; i++)
	{
	  for(j=0; j<n_a; j++)
	    {
	      if (*(a+i+j*m_a) != 0) A_matrix.modifyCoefficient(i,j,*(a+i+j*m_a));
#ifdef DEBUG
	      sciprint("%f ",*(a+i+j*m_a));
#endif
	    }
#ifdef DEBUG
	  sciprint("\n");
#endif
	}
    }
  else
    {
#ifdef DEBUG
      sciprint("DEBUG: A_IN is sparse\n");
#endif
      
      getAllocatedSparseMatrix(pvApiCtx, a_addr, &S_A.m, &S_A.n, &S_A.nel, &S_A.mnel, &S_A.icol, &S_A.R);
      A_matrix.setDimensions(nrows,ncols);
      
#ifdef DEBUG
      sciprint("A = [%d,%d]\n", m_a, n_a);
#endif
      
      nz = S_A.nel;
      
      count = 0;
      for(i=0;i<S_A.m;i++)
	{
	  if (S_A.mnel[i]!=0) 
	    {
#ifdef DEBUG
	      sciprint("mnel[%d] = %d - ",i, S_A.mnel[i]);
#endif
	      for(j=0;j<S_A.mnel[i];j++)
		{
		  count++;
		  A_matrix.modifyCoefficient(i,S_A.icol[count-1]-1,S_A.R[count-1]);
#ifdef DEBUG
		  sciprint("[%d] = %f ", S_A.icol[count-1]-1, S_A.R[count-1]);
#endif
		}
#ifdef DEBUG
	      sciprint("\n");
#endif
	    }
	}
      
      freeAllocatedSparseMatrix(S_A.mnel, S_A.icol, S_A.R);
    }
  
  /////////////////
  // Get options //
  /////////////////

#ifdef DEBUG
  sciprint("DEBUG: get options\n");
#endif

  // Default settings
  int * param_in_addr = NULL;
  int     solverchoice = 1, loglevel = 0, fact_freq = 200, perturb = 0;
  int     presolve = 0, red_grad = 1, maximumbarrieriterations = 200;
  int     tmp_int, tmp_res;
  double  tmp_double;
  char *  tmp_char;

  initPList(pvApiCtx, PARAM_IN, &param_in_addr);
  if (!checkPList(pvApiCtx, param_in_addr))
    {
      Scierror(999, "%s: argument n° %d is not a plist\n", fname, PARAM_IN);

      return 0;
    }

  // solver option
  getIntInPList(pvApiCtx, param_in_addr, "solver", &tmp_int, &tmp_res, 1, Log, CHECK_NONE);
  if (tmp_res!=-1) solverchoice = tmp_int;

  // Load the matrix in the solver
  switch(solverchoice)
    {
    case 6:
      modelInterior = new ClpInterior;
      modelBase = (ClpModel *)modelInterior;
      break;
    default:
      modelSimplex = new ClpSimplex;
      modelBase = (ClpModel *)modelSimplex;
      break;
    }

  // maxnumiterations option
  getIntInPList(pvApiCtx, param_in_addr, "maxnumiterations", &tmp_int, &tmp_res, 1000, Log, CHECK_NONE);
  if (tmp_res!=-1) modelBase->setMaximumIterations(tmp_int);
      
  // maxnumseconds option
  getDoubleInPList(pvApiCtx, param_in_addr, "maxnumseconds", &tmp_double, &tmp_res, 3600, Log, CHECK_NONE);
  if (tmp_res!=-1) modelBase->setMaximumSeconds(tmp_double);
      
  // primaltolerance option
  getDoubleInPList(pvApiCtx, param_in_addr, "primaltolerance", &tmp_double, &tmp_res, 1e-7, Log, CHECK_NONE);
  if (tmp_res!=-1) modelBase->setPrimalTolerance(tmp_double);

  // dualtolerance option
  getDoubleInPList(pvApiCtx, param_in_addr, "dualtolerance", &tmp_double, &tmp_res, 1e-7, Log, CHECK_NONE);
  if (tmp_res!=-1)   modelBase->setDualTolerance(tmp_double);				

  // verbose option
  getIntInPList(pvApiCtx, param_in_addr, "verbose", &tmp_int, &tmp_res, 0, Log, CHECK_NONE);
  if (tmp_res!=-1) 
    {
      ///////////////////////////////
      // Enable printing in Scilab //
      // and set parameters of clp //
      ///////////////////////////////
	  
      loglevel = tmp_int;

      printer = new DerivedHandler(); // assumed open	
      printer->setLogLevel(loglevel);
    }

  // optim_dir option
  getIntInPList(pvApiCtx, param_in_addr, "optim_dir", &tmp_int, &tmp_res, 1, Log, CHECK_NONE);
  if (tmp_res!=-1) modelBase->setOptimizationDirection(tmp_int);

  // writemps option
  getStringInPList(pvApiCtx, param_in_addr, "writemps", &tmp_char, &tmp_res, "test.mps", Log, CHECK_NONE);
  if (tmp_res!=-1) 
    {
      writemps_filename = tmp_char;
      writemps = 1;
#ifdef DEBUG
      sciprint("DEBUG: writemps_filename = %s\n", writemps_filename);
#endif
    }

  // perturb option
  getIntInPList(pvApiCtx, param_in_addr, "perturb", &tmp_int, &tmp_res, 0, Log, CHECK_NONE);
  if (tmp_res!=-1) perturb = tmp_int;

  // scaling option
  // Sets or unsets scaling:
  // - 0 -off
  // - 1 equilibrium (default)
  // - 2 geometric
  // - 3 auto
  // - 4 auto-but-as-initialSolve-in-bab. 
  getIntInPList(pvApiCtx, param_in_addr, "scaling", &tmp_int, &tmp_res, 1, Log, CHECK_NONE);
  if (tmp_res!=-1) modelBase->scaling(tmp_int);

  // factorization frequency option
  getIntInPList(pvApiCtx, param_in_addr, "fact_freq", &tmp_int, &tmp_res, 200, Log, CHECK_NONE);
  if (tmp_res!=-1) fact_freq = tmp_int;

  // presolve option
  getIntInPList(pvApiCtx, param_in_addr, "presolve", &tmp_int, &tmp_res, 0, Log, CHECK_NONE);
  if (tmp_res!=-1) presolve = tmp_int;

  // reduced gradient phase option
  getIntInPList(pvApiCtx, param_in_addr, "red_grad", &tmp_int, &tmp_res, 1, Log, CHECK_NONE);
  if (tmp_res!=-1) red_grad = tmp_int;

  // maxnumiterationshotstart
  getIntInPList(pvApiCtx, param_in_addr, "maxnumiterationshotstart", &tmp_int, &tmp_res, 1000, Log, CHECK_NONE);
  if (tmp_res!=-1) modelBase->setIntParam(ClpMaxNumIterationHotStart, tmp_int);

  // dualobjectivelimit
  getDoubleInPList(pvApiCtx, param_in_addr, "dualobjectivelimit", &tmp_double, &tmp_res, 1e-7, Log, CHECK_NONE);
  if (tmp_res!=-1) modelBase->setDblParam(ClpDualObjectiveLimit, tmp_double);

  // primalobjectivelimit
  getDoubleInPList(pvApiCtx, param_in_addr, "primalobjectivelimit", &tmp_double, &tmp_res, 1e-7, Log, CHECK_NONE);
  if (tmp_res!=-1) modelBase->setDblParam(ClpPrimalObjectiveLimit, tmp_double);

  // obj offset
  getDoubleInPList(pvApiCtx, param_in_addr, "objoffset", &tmp_double, &tmp_res, 0.0, Log, CHECK_NONE);
  if (tmp_res!=-1) modelBase->setDblParam(ClpObjOffset, tmp_double);

  // presolvetolerance
  getDoubleInPList(pvApiCtx, param_in_addr, "presolvetolerance", &tmp_double, &tmp_res, 1e-7, Log, CHECK_NONE);
  if (tmp_res!=-1) modelBase->setDblParam(ClpPresolveTolerance, tmp_double);
      
  // maximumBarrierIterations
  getIntInPList(pvApiCtx, param_in_addr, "maxnumbarrieriterations", &tmp_int, &tmp_res, 200, Log, CHECK_NONE);
  if (tmp_res!=-1) maximumbarrieriterations = tmp_int;

  /////////////////////////////////////
  // Set the bounds on the variables //
  /////////////////////////////////////

  modelBase->loadProblem(A_matrix,lhs,rhs,c,lower,upper);

  for(i=0;i<ncols; i++)
    {
      modelBase->setColUpper(i, *(upper+i));
      modelBase->setColLower(i, *(lower+i));
      modelBase->setObjectiveCoefficient(i,*(c+i));
      if ((*(vtype+i)=='I')||(*(vtype+i)=='i'))
	{
	  modelBase->setInteger(i);
	}
      else
	{
	  modelBase->setContinuous(i);
	}
    }
  
  /////////////////////////////////////////
  // Set the boundary of the constraints //
  /////////////////////////////////////////

  // 'L' - smaller than - <=
  // 'E' - equality     - =
  // 'G' - greater than - >=
  // 'R' - Range        - <= + >=
  // 'N' - Free         - no constraints

#ifdef DEBUG
  sciprint("DEBUG: dealing with btype\n");
#endif
  for(i=0;i<nrows; i++)
    {
      switch(*(ctype+i))
	{
	case 'l':
	case 'L':
	  modelBase->setRowUpper(i, *(rhs+i));
	  modelBase->setRowLower(i, -COIN_DBL_MAX);
	  break;
	case 'e':
	case 'E':
	  modelBase->setRowUpper(i, *(rhs+i));
	  modelBase->setRowLower(i, *(rhs+i));
	  break;
	case 'n':
	case 'N':
	  modelBase->setRowUpper(i,  COIN_DBL_MAX);
	  modelBase->setRowLower(i, -COIN_DBL_MAX);
	  break;
	case 'r':
	case 'R':
	  modelBase->setRowUpper(i, *(rhs+i));
	  modelBase->setRowLower(i, *(lhs+i));
	  break;
	case 'g':
	case 'G':
	default:
	  modelBase->setRowUpper(i, COIN_DBL_MAX);
	  modelBase->setRowLower(i, *(lhs+i));
	  break;
	}
#ifdef DEBUG
      sciprint("row lower[%d] = %f row upper[%d] = %f\n", i, modelBase->getRowLower()[i], i, modelBase->getRowUpper()[i]);
#endif
    }
  
  ///////////////////////////////////
  // Affect names to rows and cols //
  ///////////////////////////////////

  modelBase->setIntParam(ClpNameDiscipline,0);

  ////////////////////////
  // Any quadratic part //
  ////////////////////////
  
#ifdef DEBUG
  sciprint("DEBUG: dealing with Q\n");
#endif
  _SciErr = getVarAddressFromPosition(pvApiCtx, Q_IN, &q_addr); SCICOINOR_ERROR;
  _SciErr = getVarType(pvApiCtx, q_addr, &type); SCICOINOR_ERROR;

  if(type!=sci_sparse)
    {
      _SciErr = getMatrixOfDouble(pvApiCtx, q_addr, &m_q, &n_q, &q); SCICOINOR_ERROR;
      
      if (n_q * m_q !=0)
	{
#ifdef DEBUG
	  sciprint("DEBUG: Q_IN is not sparse\n");
	  sciprint("DEBUG: Q size: n = %d m= %d\n", n_q, m_q);
#endif
	  
	  Q_matrix.setDimensions(nrows,ncols);
	  
	  nz = n_q * m_q;
	  
	  if (q==NULL) 
	    {
	      Scierror(999,"%s: invalid value of matrix q\n",fname);
	  
	      freeAllocatedSingleString(ctype);
	      freeAllocatedSingleString(vtype);

	      if (writemps_filename) FREE(writemps_filename);

	      return 0;
	    }
	  
	  for(i=0; i<m_q; i++)
	    {
	      for(j=0; j<n_q; j++)
		{
		  if (*(q+i+j*m_q)!=0) Q_matrix.modifyCoefficient(i,j,*(q+i+j*m_q));
		}
	    }
	  modelBase->loadQuadraticObjective(Q_matrix);
	}
    }
  else
    {
      getAllocatedSparseMatrix(pvApiCtx, q_addr, &S_Q.m, &S_Q.n, &S_Q.nel, &S_Q.mnel, &S_Q.icol, &S_Q.R);
      
      if (S_Q.n * S_Q.m!=0)
	{
#ifdef DEBUG
	  sciprint("DEBUG: Q_IN is sparse\n");
	  sciprint("DEBUG: Q size: n = %d m= %d\n", S_Q.n, S_Q.m);
#endif
	  Q_matrix.setDimensions(nrows,ncols);
	  
	  nz = S_Q.nel;
	  
	  count = 0;
	  for(i=0;i<S_Q.m;i++)
	    {
	      if (S_Q.mnel[i]!=0) 
		{
		  for(j=0;j<S_Q.mnel[i];j++)
		    {
		      count++;
		      Q_matrix.modifyCoefficient(i,S_Q.icol[count-1]-1,S_Q.R[count-1]);
		    }
		}
	    }
	  modelBase->loadQuadraticObjective(Q_matrix);
	}

      freeAllocatedSparseMatrix(S_Q.mnel, S_Q.icol, S_Q.R);
    }
 
  // Solver specific part
  switch(solverchoice)
    {
    case 6:
      modelInterior->setMaximumBarrierIterations(maximumbarrieriterations);
      break;
    default:
      modelSimplex->setFactorizationFrequency(fact_freq);
      modelSimplex->setPerturbation(perturb);
      break;
    }

  ///////////////////////////
  // Pre / Post resolution //
  ///////////////////////////

#ifdef HANDLE_CTRLC
  ///////////////////////////////////////////////////////////
  // Pass in the event handler, to handle ctrl+c in scilab //
  ///////////////////////////////////////////////////////////

  if (modelSimplex) 
    {
      modelSimplex->passInEventHandler(&SciClpEventHandler);
      modelSimplex->passInMessageHandler(printer);
    }
#endif

#ifdef DEBUG
  sciprint("DEBUG: presolve\n");
#endif
  // If the solver is not ClpInterior we can set the presolve option
  if (presolve && solverchoice!=6) 
    {
      TRYCATCH(modelSimplex->initialSolve(modelSolve));
      switch(presolve)
	{
	case 2:
	  TRYCATCH(modelSimplex->initialDualSolve());
	  break;
	case 3:
	  TRYCATCH(modelSimplex->initialPrimalSolve());
	  break;
	case 4:
	  TRYCATCH(modelSimplex->initialBarrierSolve());
	  break;
	case 5:
	  TRYCATCH(modelSimplex->initialBarrierNoCrossSolve());
	  break;
	default:
	  TRYCATCH(modelSimplex->initialSolve());
	  break;
	}
    }

  ////////////////////////////////////////////
  // If needed, write the problem in a file //
  ////////////////////////////////////////////

#ifdef DEBUG
  sciprint("DEBUG: dealing with writemps\n");
#endif
  if (writemps)
    {
      modelBase->writeMps(writemps_filename);
      if (loglevel) sciprint("sciclp: writing %s mps file\n",writemps_filename);
    }

  ////////////////
  // Resolution //
  ////////////////

#ifdef DEBUG
  sciprint("DEBUG: resolution\n");
  sciprint("model number columns = %d\n", modelBase->numberColumns());
  sciprint("model number rows    = %d\n", modelBase->numberRows());
#endif

  if ((solverchoice>=1)&&(solverchoice<=5))
    {
      TRYCATCH(modelSimplex->initialSolve())
    }

#ifdef HANDLE_CTRLC
  ///////////////////////////////////////////////////////////
  // Pass in the event handler, to handle ctrl+c in scilab //
  ///////////////////////////////////////////////////////////

  if (modelSimplex)  
    {
      modelSimplex->passInEventHandler(&SciClpEventHandler);
      modelSimplex->passInMessageHandler(printer);
    }
  if (modelInterior) 
    {
      modelInterior->passInEventHandler(&SciClpEventHandler);
      modelInterior->passInMessageHandler(printer);
    }
#endif

  switch (solverchoice)
    {
    case 2:
      TRYCATCH(status = modelSimplex->dual());
      break;
    case 3:
      TRYCATCH(status = modelSimplex->barrier(false));
      break;
    case 4:
      TRYCATCH(status = modelSimplex->barrier(true));
      break;
    case 5:
      TRYCATCH(status = modelSimplex->reducedGradient(red_grad));
      break;
    case 6:
      cholesky = new ClpCholeskyBase();
      cholesky->setKKT(true);
      modelInterior->setCholesky(cholesky);
      TRYCATCH(status = modelInterior->primalDual());
      break;
    case 7:
      TRYCATCH(status = modelInterior->pdco());
      break;
    default:
      TRYCATCH(status = modelSimplex->primal());
      break;
    }

#ifdef DEBUG
  if (status && loglevel) sciprint("Optimization failed\n");
#endif

  int clp_status = 0;

  clp_status  = (int)(pow(2.0,0.0)*modelBase->isAbandoned());
  clp_status += (int)(pow(2.0,1.0)*modelBase->isProvenOptimal());
  clp_status += (int)(pow(2.0,2.0)*modelBase->isProvenPrimalInfeasible());
  clp_status += (int)(pow(2.0,3.0)*modelBase->isProvenDualInfeasible());
  clp_status += (int)(pow(2.0,4.0)*modelBase->isPrimalObjectiveLimitReached());
  clp_status += (int)(pow(2.0,5.0)*modelBase->isDualObjectiveLimitReached());  
  clp_status += (int)(pow(2.0,6.0)*modelBase->isIterationLimitReached());      

  //////////////////////////////
  // Allocate for return data //
  //////////////////////////////

#ifdef DEBUG
  sciprint("DEBUG: allocating data\n");
#endif

  int m_xmin   = ncols, n_xmin   = 1;
  int m_lambda   = 1, n_lambda   = nrows;
  int * extra_addr = NULL;

  char * ListLabels [] = {"lambda","secondary_status","clp_status"};

  _SciErr = createMatrixOfDouble(pvApiCtx, XMIN_OUT, m_xmin, n_xmin, (double *)modelBase->primalColumnSolution()); SCICOINOR_ERROR;
  createScalarDouble(pvApiCtx, FMIN_OUT, modelBase->getObjValue());
  createScalarDouble(pvApiCtx, STATUS_OUT, (double)modelBase->status());

  _SciErr = createPList(pvApiCtx, EXTRA_OUT, &extra_addr, (char **)ListLabels, 3); SCICOINOR_ERROR;

  _SciErr = createColVectorOfDoubleInPList(pvApiCtx, EXTRA_OUT, extra_addr, "lambda", m_lambda*n_lambda, (double *)modelBase->dualRowSolution()); SCICOINOR_ERROR;
  _SciErr = createIntInPList(pvApiCtx, EXTRA_OUT, extra_addr, "secondary_status", modelBase->secondaryStatus()); SCICOINOR_ERROR;
  _SciErr = createIntInPList(pvApiCtx, EXTRA_OUT, extra_addr, "clp_status",       clp_status); SCICOINOR_ERROR;

#ifdef DEBUG
  sciprint("DEBUG: getting solution\n");
#endif

  //
  // status of problem:
  //  -1 - unknown e.g. before solve or if postSolve says not optimal
  //   0 - optimal
  //   1 - primal infeasible
  //   2 - dual infeasible
  //   3 - stopped on iterations or time
  //   4 - stopped due to errors
  //   5 - stopped by event handler (virtual int ClpEventHandler::event())
  //

  // Secondary status of problem - may get extended 
  // - 0 - none 
  // - 1 - primal infeasible because dual limit reached OR probably primal infeasible but can't prove it (main status 4)
  // - 2 - scaled problem optimal - unscaled problem has primal infeasibilities
  // - 3 - scaled problem optimal - unscaled problem has dual infeasibilities
  // - 4 - scaled problem optimal - unscaled problem has primal and dual infeasibilities
  // - 5 - giving up in primal with flagged variables
  // - 6 - failed due to empty problem check
  // - 7 - postSolve says not optimal
  // - 8 - failed due to bad element check
  // - 9 - status was 3 and stopped on time 
  // - 100 up - translation of enum from ClpEventHandler.

  /////////////////////////////////
  // Copy solutions if available //
  /////////////////////////////////

#ifdef DEBUG
  sciprint("DEBUG: returning data\n");
#endif

  LhsVar(1) = XMIN_OUT;
  LhsVar(2) = FMIN_OUT;
  LhsVar(3) = STATUS_OUT;
  LhsVar(4) = EXTRA_OUT;

  //////////////////////////////
  // Delete allocated objects //
  //////////////////////////////

  if (modelSimplex)  delete modelSimplex;
  if (modelInterior) delete modelInterior;
  if (printer)       delete printer;

  freeAllocatedSingleString(ctype);
  freeAllocatedSingleString(vtype);

  if (writemps_filename) FREE(writemps_filename);

  return 0;
}
Example #4
0
int main(int argc, const char *argv[])
{
     /* Read quadratic model in two stages to test loadQuadraticObjective.

        And is also possible to just read into ClpSimplex/Interior which sets it all up in one go.
        But this is only if it is in QUADOBJ format.

        If no arguments does share2qp using ClpInterior (also creates quad.mps which is in QUADOBJ format)
        If one argument uses simplex e.g. testit quad.mps
        If > one uses barrier via ClpSimplex input and then ClpInterior borrow
     */
     if (argc < 2) {
          CoinMpsIO  m;
#if defined(SAMPLEDIR)
          int status = m.readMps(SAMPLEDIR "/share2qp", "mps");
#else
          fprintf(stderr, "Do not know where to find sample MPS files.\n");
          exit(1);
#endif
          if (status) {
               printf("errors on input\n");
               exit(77);
          }
          ClpInterior model;
          model.loadProblem(*m.getMatrixByCol(), m.getColLower(), m.getColUpper(),
                            m.getObjCoefficients(),
                            m.getRowLower(), m.getRowUpper());
          // get quadratic part
          int * start = NULL;
          int * column = NULL;
          double * element = NULL;
          m.readQuadraticMps(NULL, start, column, element, 2);
          int j;
          for (j = 0; j < 79; j++) {
               if (start[j] < start[j+1]) {
                    int i;
                    printf("Column %d ", j);
                    for (i = start[j]; i < start[j+1]; i++) {
                         printf("( %d, %g) ", column[i], element[i]);
                    }
                    printf("\n");
               }
          }
          model.loadQuadraticObjective(model.numberColumns(), start, column, element);
          // share2qp is in old style qp format - convert to new so other options can use
          model.writeMps("quad.mps");
          ClpCholeskyBase * cholesky = new ClpCholeskyBase();
          cholesky->setKKT(true);
          model.setCholesky(cholesky);
          model.primalDual();
          double *primal;
          double *dual;
          primal = model.primalColumnSolution();
          dual = model.dualRowSolution();
          int i;
          int numberColumns = model.numberColumns();
          int numberRows = model.numberRows();
          for (i = 0; i < numberColumns; i++) {
               if (fabs(primal[i]) > 1.0e-8)
                    printf("%d primal %g\n", i, primal[i]);
          }
          for (i = 0; i < numberRows; i++) {
               if (fabs(dual[i]) > 1.0e-8)
                    printf("%d dual %g\n", i, dual[i]);
          }
     } else {
          // Could read into ClpInterior
          ClpSimplex model;
          if (model.readMps(argv[1])) {
               printf("errors on input\n");
               exit(77);
          }
          model.writeMps("quad");
          if (argc < 3) {
               // simplex - just primal as dual does not work
               // also I need to fix scaling of duals on output
               // (Was okay in first place - can't mix and match scaling techniques)
               // model.scaling(0);
               model.primal();
          } else {
               // barrier
               ClpInterior barrier;
               barrier.borrowModel(model);
               ClpCholeskyBase * cholesky = new ClpCholeskyBase();
               cholesky->setKKT(true);
               barrier.setCholesky(cholesky);
               barrier.primalDual();
               barrier.returnModel(model);
          }
          // Just check if share2qp (quad.mps here)
          // this is because I am not checking if variables at ub
          if (model.numberColumns() == 79) {
               double *primal;
               double *dual;
               primal = model.primalColumnSolution();
               dual = model.dualRowSolution();
               // Check duals by hand
               const ClpQuadraticObjective * quadraticObj =
                    (dynamic_cast<const ClpQuadraticObjective*>(model.objectiveAsObject()));
               assert(quadraticObj);
               CoinPackedMatrix * quad = quadraticObj->quadraticObjective();
               const int * columnQuadratic = quad->getIndices();
               const CoinBigIndex * columnQuadraticStart = quad->getVectorStarts();
               const int * columnQuadraticLength = quad->getVectorLengths();
               const double * quadraticElement = quad->getElements();
               int numberColumns = model.numberColumns();
               int numberRows = model.numberRows();
               double * gradient = new double [numberColumns];
               // move linear objective
               memcpy(gradient, quadraticObj->linearObjective(), numberColumns * sizeof(double));
               int iColumn;
               for (iColumn = 0; iColumn < numberColumns; iColumn++) {
                    double valueI = primal[iColumn];
                    CoinBigIndex j;
                    for (j = columnQuadraticStart[iColumn];
                              j < columnQuadraticStart[iColumn] + columnQuadraticLength[iColumn]; j++) {
                         int jColumn = columnQuadratic[j];
                         double valueJ = primal[jColumn];
                         double elementValue = quadraticElement[j];
                         if (iColumn != jColumn) {
                              double gradientI = valueJ * elementValue;
                              double gradientJ = valueI * elementValue;
                              gradient[iColumn] += gradientI;
                              gradient[jColumn] += gradientJ;
                         } else {
                              double gradientI = valueI * elementValue;
                              gradient[iColumn] += gradientI;
                         }
                    }
                    if (fabs(primal[iColumn]) > 1.0e-8)
                         printf("%d primal %g\n", iColumn, primal[iColumn]);
               }
               for (int i = 0; i < numberRows; i++) {
                    if (fabs(dual[i]) > 1.0e-8)
                         printf("%d dual %g\n", i, dual[i]);
               }
               // Now use duals to get reduced costs
               // Can't use this as will try and use scaling
               // model.transposeTimes(-1.0,dual,gradient);
               // So ...
               CoinPackedMatrix * matrix = model.matrix();
               const int * row = matrix->getIndices();
               const CoinBigIndex * columnStart = matrix->getVectorStarts();
               const int * columnLength = matrix->getVectorLengths();
               const double * element = matrix->getElements();
               for (iColumn = 0; iColumn < numberColumns; iColumn++) {
                    double dj = gradient[iColumn];
                    CoinBigIndex j;
                    for (j = columnStart[iColumn];
                              j < columnStart[iColumn] + columnLength[iColumn]; j++) {
                         int jRow = row[j];
                         dj -= element[j] * dual[jRow];
                    }
                    if (model.getColumnStatus(iColumn) == ClpSimplex::basic) {
                         assert(fabs(dj) < 1.0e-5);
                    } else {
                         assert(dj > -1.0e-5);
                    }
               }
               delete [] gradient;
          }
     }
     return 0;
}