void
OsiVolSolverInterface::initFromRlbRub(const int rownum,
				      const double* rowlb,
				      const double* rowub)
{
   if (maxNumrows_ > 0) {
      rowRimAllocator_();
      if (rowub) {
	 CoinDisjointCopyN(rowub, rownum, rowupper_);
      } else {
	 CoinFillN(rowupper_, rownum, OsiVolInfinity);
      }
      if (rowlb) {
	 CoinDisjointCopyN(rowlb, rownum, rowlower_);
      } else {
	 CoinFillN(rowlower_, rownum, -OsiVolInfinity);
      }
      // Set the initial dual solution
      CoinFillN(rowprice_, rownum, 0.0);
      convertBoundsToSenses_();
   }
}
void 
OsiVolSolverInterface::addRows(const int numrows,
			       const CoinPackedVectorBase * const * rows,
			       const double* rowlb, const double* rowub)
{
  if (numrows > 0) {
    const int rownum = getNumRows();
    rowRimResize_(rownum + numrows);
    CoinDisjointCopyN(rowlb, numrows, rowlower_ + rownum);
    CoinDisjointCopyN(rowub, numrows, rowupper_ + rownum);
    for (int i = rownum + numrows - 1; i >= rownum; --i) {
      convertBoundToSense(rowlower_[i], rowupper_[i],
			  rowsense_[i], rhs_[i], rowrange_[i]);
    }
    CoinFillN(rowprice_ + rownum, numrows, 0.0);
    CoinFillN(lhs_      + rownum, numrows, 0.0);

    updateRowMatrix_();
    rowMatrix_.appendRows(numrows, rows);
    colMatrixCurrent_ = false;
  }
}
Example #3
0
void
CoinPackedVector::gutsOfSetVector(int size,
				 const int * inds, const double * elems,
				 bool testForDuplicateIndex,
				 const char * method)
{
   if ( size != 0 ) {
      reserve(size);
      nElements_ = size;
      CoinDisjointCopyN(inds, size, indices_);
      CoinDisjointCopyN(elems, size, elements_);
      CoinIotaN(origIndices_, size, 0);
   }
   if (testForDuplicateIndex) {
     try {
       CoinPackedVectorBase::setTestForDuplicateIndex(testForDuplicateIndex);
     }
     catch (CoinError e) {
       throw CoinError("duplicate index", method, "CoinPackedVector");
     }
   } else {
     setTestsOff();
   }
}
bool
OsiTestSolverInterface::setWarmStart(const CoinWarmStart* warmstart)
{
  const CoinWarmStartDual* ws =
    dynamic_cast<const CoinWarmStartDual*>(warmstart);

  if (! ws)
    return false;

  const int ws_size = ws->size();
  if (ws_size != getNumRows() && ws_size != 0) {
    throw CoinError("wrong dual warmstart size", "setWarmStart",
		   "OsiTestSolverInterface");
  }

  CoinDisjointCopyN(ws->dual(), ws_size, rowprice_);
  return true;
}
Example #5
0
void
CoinPackedVector::setFull(int size, const double * elems,
			 bool testForDuplicateIndex) 
{
  // Clear out any values presently stored
  clear();
  
  // Allocate storage
  if ( size!=0 ) {
    reserve(size);  
    nElements_ = size;

    CoinIotaN(origIndices_, size, 0);
    CoinIotaN(indices_, size, 0);
    CoinDisjointCopyN(elems, size, elements_);
  }
  // Full array can not have duplicates
  CoinPackedVectorBase::setTestForDuplicateIndexWhenTrue(testForDuplicateIndex);
}
Example #6
0
void
CoinPackedVector::gutsOfSetConstant(int size,
				   const int * inds, double value,
				   bool testForDuplicateIndex,
				   const char * method)
{
   if ( size != 0 ) {
      reserve(size);
      nElements_ = size;
      CoinDisjointCopyN(inds, size, indices_);
      CoinFillN(elements_, size, value);
      CoinIotaN(origIndices_, size, 0);
   }
   try {
      CoinPackedVectorBase::setTestForDuplicateIndex(testForDuplicateIndex);
   }
   catch (CoinError& e) {
      throw CoinError("duplicate index", method, "CoinPackedVector");
   }
}
void
OsiTestSolverInterface::setRowPrice(const double *rowprice)
{
   CoinDisjointCopyN(rowprice, getNumRows(), rowprice_);
   compute_rc_(rowprice_, rc_);
}
void 
OsiTestSolverInterface::resolve()
{
  int i;
  
  checkData_();

  // Only one of these can do any work
  updateRowMatrix_();
  updateColMatrix_();

  const int dsize = getNumRows();
  const int psize = getNumCols();

  // Negate the objective coefficients if necessary
  if (objsense_ < 0) {
    std::transform(objcoeffs_, objcoeffs_+psize, objcoeffs_,
		   std::negate<double>());
  }

  // Set the lb/ub on the duals
  volprob_.dual_lb.allocate(dsize);
  volprob_.dual_ub.allocate(dsize);
  double * dlb = volprob_.dual_lb.v;
  double * dub = volprob_.dual_ub.v;
  for (i = 0; i < dsize; ++i) {
    dlb[i] = rowupper_[i] <  getInfinity() ? -1.0e31 : 0.0;
    dub[i] = rowlower_[i] > -getInfinity() ?  1.0e31 : 0.0;
  }
  volprob_.dsize = dsize;
  volprob_.psize = psize;
  
  // Set the dual starting point
  VOL_dvector& dsol = volprob_.dsol;
  dsol.allocate(dsize);
  std::transform(rowprice_, rowprice_+dsize, dsol.v,
		 std::bind2nd(std::multiplies<double>(), objsense_));

  // adjust the dual vector (if necessary) to be sure it's feasible
  double * dv = dsol.v;
  for (i = 0; i < dsize; ++i) {
    if (dv[i] < dlb[i]) {
      dv[i] = dlb[i];
    } else if (dv[i] > dub[i]) {
      dv[i] = dub[i];
    }
  }

  // If requested, check whether the matrix contains anything but 0/1/-1
#if 0
  isZeroOneMinusOne_ = false;
#else
  isZeroOneMinusOne_ = test_zero_one_minusone_(colMatrix_);
  if (isZeroOneMinusOne_) {
    colMatrixOneMinusOne_ = new OsiVolMatrixOneMinusOne_(colMatrix_);
    rowMatrixOneMinusOne_ = new OsiVolMatrixOneMinusOne_(rowMatrix_);
  }
#endif

  volprob_.solve(*this, true);

  // extract the solution

  // the lower bound on the objective value
  lagrangeanCost_ = objsense_ * volprob_.value;
  // the primal solution
  CoinDisjointCopyN(volprob_.psol.v, psize, colsol_);

  // Reset the objective coefficients if necessary
  if (objsense_ < 0) {
    std::transform(objcoeffs_, objcoeffs_ + psize, objcoeffs_,
		   std::negate<double>());
    // also, multiply the dual solution by -1
    std::transform(volprob_.dsol.v, volprob_.dsol.v+dsize, rowprice_,
		   std::negate<double>());
  } else {
    // now we just have to copy the dual
    CoinDisjointCopyN(volprob_.dsol.v, dsize, rowprice_);
  }

  // Compute the reduced costs
  compute_rc_(rowprice_, rc_);

  // Compute the left hand side (row activity levels)
  if (isZeroOneMinusOne_) {
    colMatrixOneMinusOne_->timesMajor(colsol_, lhs_);
  } else {
    colMatrix_.times(colsol_, lhs_);
  }

  if (isZeroOneMinusOne_) {
    delete colMatrixOneMinusOne_;
    colMatrixOneMinusOne_ = NULL;
    delete rowMatrixOneMinusOne_;
    rowMatrixOneMinusOne_ = NULL;
  }
}
OsiTestSolverInterface&
OsiTestSolverInterface::operator=(const OsiTestSolverInterface& rhs)
{
   if (&rhs == this)
      return *this;

   OsiSolverInterface::operator=(rhs);
   gutsOfDestructor_();

   rowMatrixCurrent_ = rhs.rowMatrixCurrent_;
   if (rowMatrixCurrent_)
      rowMatrix_ = rhs.rowMatrix_;
   colMatrixCurrent_ = rhs.colMatrixCurrent_;
   if (colMatrixCurrent_)
      colMatrix_ = rhs.colMatrix_;

   if (rhs.maxNumrows_) {
      maxNumrows_ = rhs.maxNumrows_;
      rowRimAllocator_();
      const int rownum = getNumRows();
      CoinDisjointCopyN(rhs.rowupper_, rownum, rowupper_);
      CoinDisjointCopyN(rhs.rowlower_, rownum, rowlower_);
      CoinDisjointCopyN(rhs.rowsense_, rownum, rowsense_);
      CoinDisjointCopyN(rhs.rhs_, rownum, rhs_);
      CoinDisjointCopyN(rhs.rowrange_, rownum, rowrange_);
      CoinDisjointCopyN(rhs.rowprice_, rownum, rowprice_);
      CoinDisjointCopyN(rhs.lhs_, rownum, lhs_);
   }
   if (rhs.maxNumcols_) {
      maxNumcols_ = rhs.maxNumcols_;
      colRimAllocator_();
      const int colnum = getNumCols();
      CoinDisjointCopyN(rhs.colupper_, colnum, colupper_);
      CoinDisjointCopyN(rhs.collower_, colnum, collower_);
      CoinDisjointCopyN(rhs.continuous_, colnum, continuous_);
      CoinDisjointCopyN(rhs.objcoeffs_, colnum, objcoeffs_);
      CoinDisjointCopyN(rhs.colsol_, colnum, colsol_);
      CoinDisjointCopyN(rhs.rc_, colnum, rc_);
   }
   volprob_.parm.granularity = 0.0;
   return *this;
}
    CoinTreeSiblings(const int n, CoinTreeNode** nodes) :
	current_(0), numSiblings_(n), siblings_(new CoinTreeNode*[n])
    {
	CoinDisjointCopyN(nodes, n, siblings_);
    }
Example #11
0
/** This helper function copies an array to another location. The two arrays
	must not overlap (otherwise an exception is thrown). For speed 8 entries
	are copied at a time. The source array is given by its first and "after
	last" entry; the target array is given by its first entry. */
template <class T> inline void
CoinDisjointCopy(register const T* first, register const T* last,
                 register T* to)
{
    CoinDisjointCopyN(first, static_cast<int>(last - first), to);
}
Example #12
0
//-----------------------------------------------------------------------------
// Generate Lift-and-Project cuts
//------------------------------------------------------------------- 
void CglLiftAndProject::generateCuts(const OsiSolverInterface& si, OsiCuts& cs,
				     const CglTreeInfo /*info*/)
{
  // Assumes the mixed 0-1 problem 
  //
  //   min {cx: <Atilde,x> >= btilde} 
  //
  // is in canonical form with all bounds,
  // including x_t>=0, -x_t>=-1 for x_t binary,
  // explicitly stated in the constraint matrix. 
  // See ~/COIN/Examples/Cgl2/cgl2.cpp 
  // for a general purpose "convert" function. 

  // Reference [BCC]: Balas, Ceria, and Corneujols,
  // "A lift-and-project cutting plane algorithm
  // for mixed 0-1 program", Math Prog 58, (1993) 
  // 295-324.

  // This implementation uses Normalization 1.

  // Given canonical problem and
  // the lp-relaxation solution, x,
  // the LAP cut generator attempts to construct
  // a cut for every x_j such that 0<x_j<1
  // [BCC:307]
 

  // x_j is the strictly fractional binary variable
  // the cut is generated from
  int j = 0; 

  // Get basic problem information
  // let Atilde be an m by n matrix
  const int m = si.getNumRows(); 
  const int n = si.getNumCols(); 
  const double * x = si.getColSolution();

  // Remember - Atildes may have gaps..
  const CoinPackedMatrix * Atilde = si.getMatrixByRow();
  const double * AtildeElements =  Atilde->getElements();
  const int * AtildeIndices =  Atilde->getIndices();
  const CoinBigIndex * AtildeStarts = Atilde->getVectorStarts();
  const int * AtildeLengths = Atilde->getVectorLengths();  
  const int AtildeFullSize = AtildeStarts[m];
  const double * btilde = si.getRowLower();

  // Set up memory for system (10) [BCC:307]
  // (the problem over the norm intersected 
  //  with the polar cone)
  // 
  // min <<x^T,Atilde^T>,u> + x_ju_0
  // s.t.
  //     <B,w> = (0,...,0,beta_,beta)^T
  //        w  is nonneg for all but the
  //           last two entries, which are free.
  // where 
  // w = (u,v,v_0,u_0)in BCC notation 
  //      u and v are m-vectors; u,v >=0
  //      v_0 and u_0 are free-scalars, and
  //  
  // B = Atilde^T  -Atilde^T  -e_j e_j
  //     btilde^T   e_0^T      0   0
  //     e_0^T      btilde^T   1   0

  // ^T indicates Transpose
  // e_0 is a (AtildeNCols x 1) vector of all zeros 
  // e_j is e_0 with a 1 in the jth position

  // Storing B in column order. B is a (n+2 x 2m+2) matrix 
  // But need to allow for possible gaps in Atilde.
  // At each iteration, only need to change 2 cols and objfunc
  // Sane design of OsiSolverInterface does not permit mucking
  // with matrix.
  // Because we must delete and add cols to alter matrix,
  // and we can only add columns on the end of the matrix
  // put the v_0 and u_0 columns on the end.
  // rather than as described in [BCC]
 
  // Initially allocating B with space for v_0 and u_O cols
  // but not populating, for efficiency.

  // B without u_0 and v_0 is a (n+2 x 2m) size matrix.

  int twoM = 2*m;
  int BNumRows = n+2;
  int BNumCols = twoM+2;
  int BFullSize = 2*AtildeFullSize+twoM+3;
  double * BElements = new double[BFullSize];
  int * BIndices = new int[BFullSize];
  CoinBigIndex * BStarts = new CoinBigIndex [BNumCols+1];
  int * BLengths = new int[BNumCols];


  int i, ij, k=0;
  int nPlus1=n+1;
  int offset = AtildeStarts[m]+m;
  for (i=0; i<m; i++){
    for (ij=AtildeStarts[i];ij<AtildeStarts[i]+AtildeLengths[i];ij++){
      BElements[k]=AtildeElements[ij];
      BElements[k+offset]=-AtildeElements[ij];
      BIndices[k]= AtildeIndices[ij];
      BIndices[k+offset]= AtildeIndices[ij];

      k++;
    }
    BElements[k]=btilde[i];
    BElements[k+offset]=btilde[i];
    BIndices[k]=n;
    BIndices[k+offset]=nPlus1;
    BStarts[i]= AtildeStarts[i]+i;
    BStarts[i+m]=offset+BStarts[i];// = AtildeStarts[m]+m+AtildeStarts[i]+i
    BLengths[i]= AtildeLengths[i]+1;
    BLengths[i+m]= AtildeLengths[i]+1;
    k++;
  }

  BStarts[twoM]=BStarts[twoM-1]+BLengths[twoM-1];

  // Cols that will be deleted each iteration
  int BNumColsLessOne=BNumCols-1;
  int BNumColsLessTwo=BNumCols-2;
  const int delCols[2] = {BNumColsLessOne, BNumColsLessTwo};

  // Set lower bound on u and v
  // u_0, v_0 will be reset as free
  const double solverINFINITY = si.getInfinity();
  double * BColLowers = new double[BNumCols];
  double * BColUppers = new double[BNumCols];
  CoinFillN(BColLowers,BNumCols,0.0);  
  CoinFillN(BColUppers,BNumCols,solverINFINITY); 

  // Set row lowers and uppers.
  // The rhs is zero, for but the last two rows.
  // For these the rhs is beta_
  double * BRowLowers = new double[BNumRows];
  double * BRowUppers = new double[BNumRows];
  CoinFillN(BRowLowers,BNumRows,0.0);  
  CoinFillN(BRowUppers,BNumRows,0.0);
  BRowLowers[BNumRows-2]=beta_;
  BRowUppers[BNumRows-2]=beta_;
  BRowLowers[BNumRows-1]=beta_;
  BRowUppers[BNumRows-1]=beta_;


  // Calculate base objective <<x^T,Atilde^T>,u>
  // Note: at each iteration coefficient u_0
  //       changes to <x^T,e_j>
  //       w=(u,v,beta,v_0,u_0) size 2m+3
  //       So, BOjective[2m+2]=x[j]
  double * BObjective= new double[BNumCols];
  double * Atildex = new double[m];
  CoinFillN(BObjective,BNumCols,0.0);
  Atilde->times(x,Atildex); // Atildex is size m, x is size n
  CoinDisjointCopyN(Atildex,m,BObjective); 

  // Number of cols and size of Elements vector
  // in B without the v_0 and u_0 cols
  int BFullSizeLessThree = BFullSize-3;

  // Load B matrix into a column orders CoinPackedMatrix
  CoinPackedMatrix * BMatrix = new CoinPackedMatrix(true, BNumRows,
						  BNumColsLessTwo, 
						  BFullSizeLessThree,
						  BElements,BIndices, 
						  BStarts,BLengths);
  // Assign problem into a solver interface 
  // Note: coneSi will cleanup the memory itself
  OsiSolverInterface * coneSi = si.clone(false);
  coneSi->assignProblem (BMatrix, BColLowers, BColUppers, 
		      BObjective,
		      BRowLowers, BRowUppers);

  // Problem sense should default to "min" by default, 
  // but just to be virtuous...
  coneSi->setObjSense(1.0);

  // The plot outline from here on down:
  // coneSi has been assigned B without the u_0 and v_0 columns
  // Calculate base objective <<x^T,Atilde^T>,u>
  // bool haveWarmStart = false;
  // For (j=0; j<n, j++)
  //   if (!isBinary(x_j) || x_j<=0 || x_j>=1) continue;
  //   // IMPROVEME: if(haveWarmStart) check if j attractive
  //   add {-e_j,0,-1} matrix column for v_0
  //   add {e_j,0,0} matrix column for u_0
  //   objective coefficient for u_0 is  x_j 
  //   if (haveWarmStart) 
  //      set warmstart info
  //   solve min{objw:Bw=0; w>=0,except v_0, u_0 free}
  //   if (bounded)
  //      get warmstart info
  //      haveWarmStart=true;
  //      ustar = optimal u solution
  //      ustar_0 = optimal u_0 solution
  //      alpha^T= <ustar^T,Atilde> -ustar_0e_j^T
  //      (double check <alpha^T,x> >= beta_ should be violated)
  //      add <alpha^T,x> >= beta_ to cutset 
  //   endif
  //   delete column for u_0 // this deletes all column info.
  //   delete column for v_0
  // endFor
  // clean up memory
  // return 0;

  int * nVectorIndices = new int[n];
  CoinIotaN(nVectorIndices, n, 0);

  bool haveWarmStart = false;
  bool equalObj1, equalObj2;
  CoinRelFltEq eq;

  double v_0Elements[2] = {-1,1};
  double u_0Elements[1] = {1};

  CoinWarmStart * warmStart = 0;

  double * ustar = new double[m];
  CoinFillN(ustar, m, 0.0);

  double* alpha = new double[n];
  CoinFillN(alpha, n, 0.0);

  for (j=0;j<n;j++){
    if (!si.isBinary(j)) continue; // Better to ask coneSi? No! 
                                   // coneSi has no binInfo.
    equalObj1=eq(x[j],0);
    equalObj2=eq(x[j],1);
    if (equalObj1 || equalObj2) continue;
    // IMPROVEME: if (haveWarmStart) check if j attractive;

    // AskLL:wanted to declare u_0 and v_0 packedVec outside loop
    // and setIndices, but didn't see a method to do that(?)
    // (Could "insert". Seems inefficient)
    int v_0Indices[2]={j,nPlus1};
    int u_0Indices[1]={j};
    // 
    CoinPackedVector  v_0(2,v_0Indices,v_0Elements,false);
    CoinPackedVector  u_0(1,u_0Indices,u_0Elements,false);

#if CGL_DEBUG
    const CoinPackedMatrix *see1 = coneSi->getMatrixByRow();
#endif

    coneSi->addCol(v_0,-solverINFINITY,solverINFINITY,0);
    coneSi->addCol(u_0,-solverINFINITY,solverINFINITY,x[j]);
    if(haveWarmStart) {
      coneSi->setWarmStart(warmStart);
      coneSi->resolve();
    }
    else {

#if CGL_DEBUG
      const CoinPackedMatrix *see2 = coneSi->getMatrixByRow();
#endif

      coneSi->initialSolve();
    }
    if(coneSi->isProvenOptimal()){
      warmStart = coneSi->getWarmStart();
      haveWarmStart=true;
      const double * wstar = coneSi->getColSolution();
      CoinDisjointCopyN(wstar, m, ustar);
      Atilde->transposeTimes(ustar,alpha);
      alpha[j]+=wstar[BNumCols-1]; 
      
#if debug
      int p;
      double sum;
      for(p=0;p<n;p++)sum+=alpha[p]*x[p];
      if (sum<=beta_){
	throw CoinError("Cut not violated",
			"cutGeneration",
			"CglLiftAndProject");
      }
#endif

      // add <alpha^T,x> >= beta_ to cutset
      OsiRowCut rc;
      rc.setRow(n,nVectorIndices,alpha);
      rc.setLb(beta_);
      rc.setUb(solverINFINITY);
      cs.insert(rc);
    }
    // delete col for u_o and v_0
    coneSi->deleteCols(2,delCols);

    // clean up memory
  }
  // clean up
  delete [] alpha;
  delete [] ustar;
  delete [] nVectorIndices;
  // BMatrix, BColLowers,BColUppers, BObjective, BRowLowers, BRowUppers
  // are all freed by OsiSolverInterface destructor (?)
  delete [] BLengths;
  delete [] BStarts;
  delete [] BIndices;
  delete [] BElements;
}
Example #13
0
//-------------------------------------------------------------------
// Determine row types. Find the VUBS and VLBS.
//-------------------------------------------------------------------
void
CglFlowCover::flowPreprocess(const OsiSolverInterface& si) const
{
  CoinPackedMatrix matrixByRow(*si.getMatrixByRow());

  int numRows = si.getNumRows();
  int numCols = si.getNumCols();

  const char* sense        = si.getRowSense();
  const double* RHS        = si.getRightHandSide();

  const double* coefByRow  = matrixByRow.getElements();
  const int* colInds       = matrixByRow.getIndices();
  const int* rowStarts     = matrixByRow.getVectorStarts();
  const int* rowLengths    = matrixByRow.getVectorLengths();
  int iRow      = -1;
  int iCol      = -1;

  numCols_ = numCols;     // Record col and row numbers for copy constructor
  numRows_ = numRows;

  if (rowTypes_ != 0) {
    delete [] rowTypes_; rowTypes_ = 0;
  }
  rowTypes_ = new CglFlowRowType [numRows];// Destructor will free memory
  // Get integer types
  const char * columnType = si.getColType (true);

  // Summarize the row type infomation.
  int numUNDEFINED   = 0;
  int numVARUB       = 0;
  int numVARLB       = 0;
  int numVAREQ       = 0;
  int numMIXUB       = 0;
  int numMIXEQ       = 0;
  int numNOBINUB     = 0;
  int numNOBINEQ     = 0;
  int numSUMVARUB    = 0;
  int numSUMVAREQ    = 0;
  int numUNINTERSTED = 0;

  int* ind     = new int [numCols];
  double* coef = new double [numCols];
  for (iRow = 0; iRow < numRows; ++iRow) {
    int rowLen   = rowLengths[iRow];
    char sen     = sense[iRow];
    double rhs   = RHS[iRow];

    CoinDisjointCopyN(colInds + rowStarts[iRow], rowLen, ind);
    CoinDisjointCopyN(coefByRow + rowStarts[iRow], rowLen, coef);

    CglFlowRowType rowType = determineOneRowType(si, rowLen, ind, coef,
						 sen, rhs);

    rowTypes_[iRow] = rowType;

    switch(rowType) {
    case  CGLFLOW_ROW_UNDEFINED:
      ++numUNDEFINED;
      break;
    case  CGLFLOW_ROW_VARUB:
      ++numVARUB;
      break;
    case  CGLFLOW_ROW_VARLB:
      ++numVARLB;
      break;
    case  CGLFLOW_ROW_VAREQ:
      ++numVAREQ;
      break;
    case  CGLFLOW_ROW_MIXUB:
      ++numMIXUB;
      break;
    case  CGLFLOW_ROW_MIXEQ:
      ++numMIXEQ;
      break;
    case  CGLFLOW_ROW_NOBINUB:
      ++numNOBINUB;
      break;
    case  CGLFLOW_ROW_NOBINEQ:
      ++numNOBINEQ;
      break;
    case  CGLFLOW_ROW_SUMVARUB:
      ++numSUMVARUB;
      break;
    case  CGLFLOW_ROW_SUMVAREQ:
      ++numSUMVAREQ;
      break;
    case  CGLFLOW_ROW_UNINTERSTED:
      ++numUNINTERSTED;
      break;
    default:
      throw CoinError("Unknown row type", "flowPreprocess",
		      "CglFlowCover");
    }

  }
  delete [] ind;  ind  = NULL;
  delete [] coef; coef = NULL;

  if(CGLFLOW_DEBUG) {
    std::cout << "The num of rows = "  << numRows        << std::endl;
    std::cout << "Summary of Row Type" << std::endl;
    std::cout << "numUNDEFINED     = " << numUNDEFINED   << std::endl;
    std::cout << "numVARUB         = " << numVARUB       << std::endl;
    std::cout << "numVARLB         = " << numVARLB       << std::endl;
    std::cout << "numVAREQ         = " << numVAREQ       << std::endl;
    std::cout << "numMIXUB         = " << numMIXUB       << std::endl;
    std::cout << "numMIXEQ         = " << numMIXEQ       << std::endl;
    std::cout << "numNOBINUB       = " << numNOBINUB     << std::endl;
    std::cout << "numNOBINEQ       = " << numNOBINEQ     << std::endl;
    std::cout << "numSUMVARUB      = " << numSUMVARUB    << std::endl;
    std::cout << "numSUMVAREQ      = " << numSUMVAREQ    << std::endl;
    std::cout << "numUNINTERSTED   = " << numUNINTERSTED << std::endl;
  }

  //---------------------------------------------------------------------------
  // Setup  vubs_ and vlbs_
  if (vubs_ != 0) { delete [] vubs_; vubs_ = 0; }
  vubs_ = new CglFlowVUB [numCols];      // Destructor will free memory
  if (vlbs_ != 0) { delete [] vlbs_; vlbs_ = 0; }
  vlbs_ = new CglFlowVLB [numCols];      // Destructor will free memory

  for (iCol = 0; iCol < numCols; ++iCol) {   // Initilized in constructor
    vubs_[iCol].setVar(UNDEFINED_);     // but, need redo since may call
    vlbs_[iCol].setVar(UNDEFINED_);     // preprocess(...) more than once
  }

  for (iRow = 0; iRow < numRows; ++iRow) {

    CglFlowRowType rowType2 = rowTypes_[iRow];

    if ( (rowType2 == CGLFLOW_ROW_VARUB) ||
	 (rowType2 == CGLFLOW_ROW_VARLB) ||
	 (rowType2 == CGLFLOW_ROW_VAREQ) )  {

      int startPos = rowStarts[iRow];
      int index0   = colInds[startPos];
      int index1   = colInds[startPos + 1];
      double coef0 = coefByRow[startPos];
      double coef1 = coefByRow[startPos + 1];

      int    xInd,  yInd;   // x is binary
      double xCoef, yCoef;

      if ( columnType[index0]==1 ) {
	xInd  = index0;   yInd  = index1;
	xCoef = coef0;    yCoef = coef1;
      }
      else {
	xInd  = index1;   yInd  = index0;
	xCoef = coef1;    yCoef = coef0;
      }

      switch (rowType2) {
      case CGLFLOW_ROW_VARUB:       // Inequality: y <= ? * x
	vubs_[yInd].setVar(xInd);
	vubs_[yInd].setVal(-xCoef / yCoef);
	break;
      case CGLFLOW_ROW_VARLB:       // Inequality: y >= ? * x
	vlbs_[yInd].setVar(xInd);
	vlbs_[yInd].setVal(-xCoef / yCoef);
	break;
      case CGLFLOW_ROW_VAREQ:       // Inequality: y >= AND <= ? * x
	vubs_[yInd].setVar(xInd);
	vubs_[yInd].setVal(-xCoef / yCoef);
	vlbs_[yInd].setVar(xInd);
	vlbs_[yInd].setVal(-xCoef / yCoef);
	break;
      default:
	throw CoinError("Unknown row type: impossible",
			"flowPreprocess", "CglFlowCover");
      }
    }
  }

  if(CGLFLOW_DEBUG) {
    printVubs(std::cout);
  }
}
Example #14
0
//#############################################################################
OsiSolverInterface *
MibSBilevel::setUpModel(OsiSolverInterface * oSolver, bool newOsi,
			const double *lpSol)
{

  /** Create lower-level model with fixed upper-level vars **/

  int probType =
    model_->MibSPar_->entry(MibSParams::bilevelProblemType);

  bool warmStartLL =
    model_->MibSPar_->entry(MibSParams::warmStartLL);

  bool doDualFixing =
    model_->MibSPar_->entry(MibSParams::doDualFixing);

  std::string feasCheckSolver =
    model_->MibSPar_->entry(MibSParams::feasCheckSolver);

  OsiSolverInterface * nSolver;

  double etol(model_->etol_);
  int i(0), j(0), index1(0), index2(0);
  int uCols(model_->getUpperDim());
  int lRows(model_->getLowerRowNum());
  int lCols(model_->getLowerDim());
  int * uColIndices = model_->getUpperColInd();
  int * lColIndices = model_->getLowerColInd();
  int * lRowIndices = model_->getLowerRowInd();

  double objSense(model_->getLowerObjSense());  
  double * lObjCoeffs = model_->getLowerObjCoeffs();
     
  const CoinPackedMatrix * matrix = oSolver->getMatrixByRow();
  double coeff(0.0);
  if (!lpSol){
     lpSol = oSolver->getColSolution();   
  }
  const double * origRowLb = model_->getOrigRowLb();
  const double * origRowUb = model_->getOrigRowUb();
  const double * origColLb = model_->getOrigColLb();
  const double * origColUb = model_->getOrigColUb();
  double * rowUb = new double[lRows];
  double * rowLb = new double[lRows];
  double * colUb = new double[lCols];
  double * colLb = new double[lCols];
  //CoinZeroN(rowUb, lRows);
  //CoinZeroN(rowLb, lRows);
  //CoinZeroN(colUb, lCols);
  //CoinZeroN(colLb, lCols);

  /** Set the row bounds **/
  
  for(i = 0; i < lRows; i++){
     rowLb[i] = origRowLb[lRowIndices[i]];
     rowUb[i] = origRowUb[lRowIndices[i]];
  }
     
  for(i = 0; i < lCols; i++){
     colLb[i] = origColLb[lColIndices[i]];
     colUb[i] = origColUb[lColIndices[i]];
  }
  
  if (newOsi){
     if (feasCheckSolver == "Cbc"){
	nSolver = new OsiCbcSolverInterface();
     }else if (feasCheckSolver == "SYMPHONY"){
	nSolver = new OsiSymSolverInterface();
     }else if (feasCheckSolver == "CPLEX"){
#ifdef USE_CPLEX
	nSolver = new OsiCpxSolverInterface();
#else
	throw CoinError("CPLEX chosen as solver, but it has not been enabled",
			"setUpModel", "MibsBilevel");
#endif
     }else{
	throw CoinError("Unknown solver chosen",
			"setUpModel", "MibsBilevel");
     }
	
     int * integerVars = new int[lCols];
     double * objCoeffs = new double[lCols];
     
     CoinFillN(integerVars, lCols, 0);
     //CoinZeroN(objCoeffs, lCols);
     
     int intCnt(0);
  
     /** Fill in array of lower-level integer variables **/
     
     for(i = 0; i < lCols; i++){
	index1 = lColIndices[i];
	if(oSolver->isInteger(index1)){
	   integerVars[intCnt] = i;
	   intCnt++;
	}
     }
     
     CoinDisjointCopyN(lObjCoeffs, lCols, objCoeffs);
     
     CoinPackedMatrix * newMat = new CoinPackedMatrix(false, 0, 0);
     newMat->setDimensions(0, lCols);
     double tmp(0.0);
     
     /*
       for(i = 0; i < lRows; i++){
       CoinPackedVector row;
       index1 = lRowIndices[i];
       start = matStarts[index1];
       end = start + matrix->getVectorSize(index1);
       for(j = start; j < end; j++){
       index2 = matIndices[j];
       //tmp = findIndex(index, lCols, lColIndices);
       tmp = binarySearch(0, lCols - 1, index2, lColIndices);
       if(tmp > -1)
       row.insert(tmp, matElements[j]);
       }
       newMat->appendRow(row);
       }
     */
     for(i = 0; i < lRows; i++){
	CoinPackedVector row;
	index1 = lRowIndices[i];
	for(j = 0; j < lCols; j++){
	   index2 = lColIndices[j];
	   tmp = matrix->getCoefficient(index1, index2);
	   row.insert(j, tmp);
	}
	newMat->appendRow(row);
     }

     /*
       nSolver->assignProblem(newMat, colLb, colUb,
       objCoeffs, rowLb, rowUb);
     */
     
     nSolver->loadProblem(*newMat, colLb, colUb,
			  objCoeffs, rowLb, rowUb);
     
     for(i = 0; i < intCnt; i++){
	nSolver->setInteger(integerVars[i]);
     }
     //nSolver->setInteger(integerVars, intCnt);
     
     nSolver->setObjSense(objSense); //1 min; -1 max
     
     nSolver->setHintParam(OsiDoReducePrint, true, OsiHintDo);

#if 0
     if(0){
	dynamic_cast<OsiCbcSolverInterface *> 
	   (nSolver)->getModelPtr()->messageHandler()->setLogLevel(0);
     }
     else{
	dynamic_cast<OsiSymSolverInterface *> 
	   (nSolver)->setSymParam("prep_level", -1);
	
	dynamic_cast<OsiSymSolverInterface *> 
	   (nSolver)->setSymParam("verbosity", -2);
	
	dynamic_cast<OsiSymSolverInterface *> 
	   (nSolver)->setSymParam("max_active_nodes", 1);
     }
#endif
     delete [] integerVars;

  }else{
     nSolver = solver_;
  }

#define SYM_VERSION_IS_WS strcmp(SYMPHONY_VERSION, "WS")  

#if SYMPHONY_VERSION_IS_WS
  if (feasCheckSolver == "SYMPHONY" && probType == 1 && warmStartLL &&
      !newOsi && doDualFixing){ //Interdiction

     /** Get upper bound from best known (feasible) lower level solution and try 
	 to fix additional variables by sensitivity analysis **/

     std::vector<std::pair<AlpsKnowledge*, double> > solutionPool;
     model_->getKnowledgeBroker()->
	getAllKnowledges(AlpsKnowledgeTypeSolution, solutionPool);

     const double * sol; 
     double objval, Ub(objSense*nSolver->getInfinity());
     BlisSolution* blisSol;
     std::vector<std::pair<AlpsKnowledge*, double> >::const_iterator si;
     for (si = solutionPool.begin(); si != solutionPool.end(); ++si){
	blisSol = dynamic_cast<BlisSolution*>(si->first);
	sol = blisSol->getValues();
	for (i = 0; i < uCols; i++){
	   if (lpSol[uColIndices[i]] > 1 - etol &&
	       sol[lColIndices[i]] > 1-etol){
	      break;
	   }
	}
	if (i == uCols && -objSense*blisSol->getQuality() < Ub){
	   Ub = -objSense*blisSol->getQuality();
	}
     }

     /** Figure out which variables get fixed by the upper level solution **/

     int *newUbInd = new int[uCols];
     int *newLbInd = new int[uCols];
     double *newUbVal = new double[uCols];
     double *newLbVal = new double[uCols];
     double newLb;
     for (i = 0; i < uCols; i++){
	newUbInd[i] = uColIndices[i];
	newLbInd[i] = uColIndices[i];
	newLbVal[i] = 0;
	if (lpSol[uColIndices[i]] > 1 - etol){
	   newUbVal[i] = 0;
	}else{
	   newUbVal[i] = 1;
	}
     }
	
     /** If we found an upper bound, then do the dual fixing **/

     if (Ub < objSense*nSolver->getInfinity()){
	sym_environment *env = 
	   dynamic_cast<OsiSymSolverInterface *>(nSolver)->getSymphonyEnvironment();

	for (i = 0; i < uCols; i++){
	   if (newUbVal[i] == 1){
	      // Try fixing it to zero
	      newUbVal[i] = 0; 
	      sym_get_lb_for_new_rhs(env, 0, NULL, NULL, uCols, newLbInd,
				     newLbVal, uCols, newUbInd, newUbVal,
				     &newLb);
	      if (objSense*newLb > Ub + etol){
		 //Victory! This variable can be fixed to 1 permanently
		 newLbVal[i] = 1;
	      }
	      //Set upper bound back to 1
	      newUbVal[i] = 1;
	      
	      if (newLbVal[i] == 0){
		 // Try fixing it to one
		 newLbVal[i] = 1;
		 sym_get_lb_for_new_rhs(env, 0, NULL, NULL, uCols, newLbInd,
					newLbVal, uCols, newUbInd, newUbVal,
					&newLb);
		 if (objSense*newLb > Ub + etol){
		    //Victory! This variable can be fixed to 0 permanently
		    newUbVal[i] = 0;
		 }
		 newLbVal[i] = 0;
	      }
	   }
	   
	}
     }
     
     /** Now set the row bounds to account for fixings **/
     
     /** This is probably very frgaile. Assuming interdiction 
	 rows come last. It would be better to set variable 
	 bounds directly, but this doesn't seem to work right now. **/
     int iRowStart = lRows-uCols; 

#if 1
     for(i = iRowStart; i < lRows; i++){
	nSolver->setRowLower(i, newLbVal[i-iRowStart]);
	nSolver->setRowUpper(i, newUbVal[i-iRowStart]);
     }
#else
     for(i = 0; i < uCols; i++){
	nSolver->setColLower(i, newLbVal[i]);
	nSolver->setColUpper(i, newUbVal[i]);
     }
#endif     
     delete[] newUbInd;
     delete[] newLbInd;
     delete[] newUbVal;
     delete[] newLbVal;
  }else{
#endif
     //FIXME: NEED TO GET ROW SENSE HERE
     
     /** Get contribution of upper-level columns **/
     
     double * upComp = new double[lRows];
     CoinFillN(upComp, lRows, 0.0);
     
     for(i = 0; i < lRows; i++){
	index1 = lRowIndices[i];
	for(j = 0; j < uCols; j++){
	   index2 = uColIndices[j];
	   coeff = matrix->getCoefficient(index1, index2);
	   if (coeff != 0){
	      upComp[i] += coeff * lpSol[index2];
	   }
	}
     }
     
     /** Correct the row bounds to account for fixed upper-level vars **/
     
     for(i = 0; i < lRows; i++){
	nSolver->setRowLower(i, rowLb[i] - upComp[i]);
	nSolver->setRowUpper(i, rowUb[i] - upComp[i]);
     }
     
     delete [] upComp;

#if SYMPHONY_VERSION_IS_WS
  }
#endif

  //I don't think this is needed
  //if(!getWarmStart())
  //  setWarmStart(nSolver->getWarmStart());

  return nSolver;

}
Example #15
0
void
BM_tm::initialize_core(BCP_vec<BCP_var_core*>& vars,
                       BCP_vec<BCP_cut_core*>& cuts,
                       BCP_lp_relax*& matrix)
{
    char* argv_[3];
    char** argv = argv_;
    argv[0] = NULL;
    argv[1] = strdup(par.entry(BM_par::NL_filename).c_str());
    argv[2] = NULL;
    
    /* Get the basic options. */
    Bonmin::BonminAmplSetup bonmin;
    bonmin.readOptionsFile(par.entry(BM_par::IpoptParamfile).c_str());
    bonmin.initialize(argv);    
    
    free(argv[1]);

    Bonmin::OsiTMINLPInterface& nlp = *bonmin.nonlinearSolver();
#if defined(BM_DISREGARD_SOS)
    const Bonmin::TMINLP::SosInfo * sos = nlp.model()->sosConstraints();
    if (sos->num > 0) {
      printf("There are SOS constraints... disregarding them...\n");
    }
#endif
    
    OsiSolverInterface& clp  = *bonmin.continuousSolver();
    
    const int numCols = clp.getNumCols();
    const int numRows = clp.getNumRows();

    const double* clb = clp.getColLower();
    const double* cub = clp.getColUpper();

    double* obj = new double[numCols];
    if (bonmin.getAlgorithm() == Bonmin::B_BB /* pure B&B */) {
      std::cout<<"Doing branch and bound"<<std::endl;
      CoinFillN(obj, numCols, 0.0);
      matrix = NULL;
    } else {
      std::cout<<"Doing hybrid"<<std::endl;
      CoinDisjointCopyN(clp.getObjCoefficients(), numCols, obj);
      cuts.reserve(numRows);
      const double* rlb = clp.getRowLower();
      const double* rub = clp.getRowUpper();
      for (int i = 0; i < numRows; ++i)	{
	cuts.push_back(new BCP_cut_core(rlb[i], rub[i]));
      }
      matrix = new BCP_lp_relax(true /*column major ordered*/);
      matrix->copyOf(*clp.getMatrixByCol(), obj, clb, cub, rlb, rub);
    }

    vars.reserve(numCols);
    for (int i = 0; i < numCols; ++i)	{
      BCP_var_t type = BCP_ContinuousVar;
      if (clp.isBinary(i)) type = BCP_BinaryVar;
      if (clp.isInteger(i)) type = BCP_IntegerVar;
      vars.push_back(new BCP_var_core(type, obj[i], clb[i], cub[i]));
    }
    delete[] obj;

    /* Initialize pseudocosts */
    int nObj = 0;
    for (int i = 0; i < numCols; ++i) {
	if (nlp.isInteger(i)) {
	    ++nObj;
	}
    }
#if ! defined(BM_DISREGARD_SOS)
    const Bonmin::TMINLP::SosInfo * sos = nlp.model()->sosConstraints();
    nObj += sos->num;
#endif
    pseudoCosts_.initialize(nObj);
}