Пример #1
0
void OsiIF::loadDummyRow(OsiSolverInterface* s2, const double* lbounds, const double* ubounds, const double* objectives)
{
	CoinPackedVector *coinrow = new CoinPackedVector();
	CoinPackedMatrix *matrix =  new CoinPackedMatrix(false,0,0);
	matrix->setDimensions(0, numCols_);
	ArrayBuffer<int> dummy(1,false);
	dummy.push(0);
	char *senses = new char[1];
	double *rhs = new double[1];
	double *ranges = new double[1];
	coinrow->insert(0, 1.);
	matrix->appendRow(*coinrow);
	senses[0] = 'E';
	rhs[0] = 1.;
	ranges[0] = 0.;

	lpSolverTime_.start();
	s2->loadProblem(*matrix, lbounds, ubounds, objectives, senses, rhs, ranges);
	lpSolverTime_.stop();
	_remRows(dummy);

	delete coinrow;
	delete matrix;
	freeChar(senses);
	freeDouble(rhs);
	freeDouble(ranges);

	return;
}
Пример #2
0
//===========================================================================//
int ATM_DecompApp::createConCount(DecompConstraintSet * model,
				  const int             atmIndex){
  
   //---
   //---       sum{d in D} v[a,d]  <= K[a] (for count)      
   //---
   CoinPackedVector row;
   string rowName = "count(a_" + m_instance.getAtmName(atmIndex) + ")";
   
   pair<int,int>       adP;
   int                 pairIndex = 0;
   const vector<int> & pairsAD   = m_instance.getPairsAD();
   const double      * K_a       = m_instance.get_K_a();
   vector<int>::const_iterator vi;
   //TODO: this can be faster by storing the incident d's for each a
   for(vi = pairsAD.begin(); vi != pairsAD.end(); vi++){
      adP = m_instance.getIndexADInv(*vi);
      if(atmIndex != adP.first){
	 pairIndex++;
	 continue;      
      }      
      row.insert(colIndex_v(pairIndex), 1.0);
      pairIndex++;
   }
   model->appendRow(row, -DecompInf, K_a[atmIndex], rowName);
   return 1;
}
Пример #3
0
template <class BinaryFunction> void
binaryOp(CoinPackedVector& retVal,
	 const CoinPackedVectorBase& op1, const CoinPackedVectorBase& op2,
	 BinaryFunction bf)
{
   retVal.clear();
   const int s1 = op1.getNumElements();
   const int s2 = op2.getNumElements();
/*
  Replaced || with &&, in response to complaint from Sven deVries, who
  rightly points out || is not appropriate for additive operations. &&
  should be ok as long as binaryOp is understood not to create something
  from nothing.		-- lh, 04.06.11
*/
   if (s1 == 0 && s2 == 0)
      return;

   retVal.reserve(s1+s2);

   const int * inds1 = op1.getIndices();
   const double * elems1 = op1.getElements();
   const int * inds2 = op2.getIndices();
   const double * elems2 = op2.getElements();

   int i;
   // loop once for each element in op1
   for ( i=0; i<s1; ++i ) {
      const int index = inds1[i];
      const int pos2 = op2.findIndex(index);
      const double val = bf(elems1[i], pos2 == -1 ? 0.0 : elems2[pos2]);
      // if (val != 0.0) // *THINK* : should we put in only nonzeros?
      retVal.insert(index, val);
   }
   // loop once for each element in operand2  
   for ( i=0; i<s2; ++i ) {
      const int index = inds2[i];
      // if index exists in op1, then element was processed in prior loop
      if ( op1.isExistingIndex(index) )
	 continue;
      // Index does not exist in op1, so the element value must be zero
      const double val = bf(0.0, elems2[i]);
      // if (val != 0.0) // *THINK* : should we put in only nonzeros?
      retVal.insert(index, val);
   }
}
Пример #4
0
//===========================================================================//
int ATM_DecompApp::createConPickOne(DecompConstraintSet * model,
				    const int             atmIndex){
   //---
   //---       sum{t in T} x1[a,t] <= 1
   //---      
   int              t;
   CoinPackedVector row;
   string rowName = "pickone_x1(a_" + m_instance.getAtmName(atmIndex) + ")";
   if(m_appParam.UseTightModel){
      for(t = 0; t <= m_appParam.NumSteps; t++)
	 row.insert(colIndex_x1(atmIndex,t), 1.0);
      model->appendRow(row, 1.0, 1.0, rowName);
   }
   else{
      for(t = 0; t < m_appParam.NumSteps; t++)
	 row.insert(colIndex_x1(atmIndex,t), 1.0);
      model->appendRow(row, -DecompInf, 1.0, rowName);
   }
   return 1;
}
Пример #5
0
/** scale the cut passed as argument*/
void scale(OsiRowCut &cut)
{
    double rhs = fabs(cut.lb());
    CoinPackedVector row;
    row.reserve(cut.row().getNumElements());
    for (int i = 0 ; i < cut.row().getNumElements() ; i++)
    {
        row.insert(cut.row().getIndices()[i], cut.row().getElements()[i]/rhs);
    }
    cut.setLb(cut.lb()/rhs);
    cut.setRow(row);
}
Пример #6
0
/** scale the cut passed as argument using provided normalization factor*/
void scale(OsiRowCut &cut, double norma)
{
    assert(norma >0.);
    CoinPackedVector row;
    row.reserve(cut.row().getNumElements());
    for (int i = 0 ; i < cut.row().getNumElements() ; i++)
    {
        row.insert(cut.row().getIndices()[i], cut.row().getElements()[i]/norma);
    }
    cut.setLb(cut.lb()/norma);
    cut.setRow(row);
}
Пример #7
0
// ------------------------------------------------------------------------- //
void UtilPackedVectorFromDense(const int          len,
                               const double*      dense,
                               const double       etol,
                               CoinPackedVector& v)
{
   //TODO: test for dup? - efficiency vs debug
   //TODO: insert is slow - better to use setVector?
   int i;

   for (i = 0; i < len; i++) {
      if (fabs(dense[i]) > etol) {
         v.insert(i, dense[i]);
      }
   }
}
Пример #8
0
/*------------------------------------------------------------------------*/
CoinPackedVector *
DecompCutPool::createRowReform(const int                  n_corecols,
                               const CoinPackedVector* row,
                               const DecompVarList&       vars)
{
   double coeff;
   //---
   //--- Create a dense row from the original sparse row (in terms of x).
   //---
   double* rowDense  = row->denseVector(n_corecols);
   //---
   //--- In order to expand to the reformulated row (in terms of lambda),
   //--- we need to substitute x = sum{s in F'} s lambda[s]
   //---
   //--- Example - Given a cut:
   //---   a[1]x[1] + a[2]x[2] >= b
   //---   a[1]x[1]             = a[1] (s1[1] lam[1] + s2[1] lam[2])
   //---              a[2]x[2]  = a[2] (s1[2] lam[1] + s2[2] lam[2])
   //--- So,   lam[1]'s coeff   = a[1] s1[1] + a[2] s1[2]
   //---       lam[2]'s coeff   = a[1] s2[1] + a[2] s2[2]
   //---
   int col_index                  = 0;
   CoinPackedVector* rowReform = new CoinPackedVector();
   DecompVarList::const_iterator vli;

   for (vli = vars.begin(); vli != vars.end(); vli++) {
      coeff = (*vli)->m_s.dotProduct(rowDense);

      if (fabs(coeff) > 1.0e-12) { //m_app->m_param.tolerance)
         rowReform->insert(col_index, coeff);
      }

      col_index++;
   }

   if (rowReform->getNumElements() == 0) {
      cerr << "row size 0, don't add it" << endl;
      UTIL_DELPTR(rowReform);
      rowReform = 0;
   }

   UTIL_DELARR(rowDense);
   //---
   //--- delete the temporary memory
   //---
   UTIL_DELARR(rowDense);
   return rowReform;
}
Пример #9
0
//@{
template <class BinaryFunction> void
binaryOp(CoinPackedVector& retVal,
	 const CoinPackedVectorBase& op1, double value,
	 BinaryFunction bf)
{
   retVal.clear();
   const int s = op1.getNumElements();
   if (s > 0) {
      retVal.reserve(s);
      const int * inds = op1.getIndices();
      const double * elems = op1.getElements();
      for (int i=0; i<s; ++i ) {
	 retVal.insert(inds[i], bf(value, elems[i]));
      }
   }
}
Пример #10
0
// =========================================================================
// COIN Macros
// =========================================================================
// ------------------------------------------------------------------------- //
CoinPackedVector* UtilPackedVectorFromDense(const int      len,
      const double* dense,
      const double   etol)
{
   //TODO: test for dup? - efficiency vs debug
   //TODO: insert is slow - better to use setVector?
   int i;
   CoinPackedVector* v = new CoinPackedVector();

   for (i = 0; i < len; i++) {
      if (fabs(dense[i]) > etol) {
         v->insert(i, dense[i]);
      }
   }

   return v;
}
/*
  Extract a column from a CoinPostsolveMatrix. At least here we only need to
  walk one threaded column.
*/
CoinPackedVector *CoinPresolveMonitor::extractCol (int j,
					const CoinPostsolveMatrix *mtx) const
{
  const CoinBigIndex *colStarts = mtx->getColStarts() ;
  const int *colLens = mtx->getColLengths() ;
  const double *coeffs = mtx->getElementsByCol() ;
  const int *rowIndices = mtx->getRowIndicesByCol() ;
  const CoinBigIndex *colLinks = mtx->link_ ;

  CoinPackedVector *pkvec = new CoinPackedVector() ;

  CoinBigIndex jj = colStarts[j] ;
  const int &lenj = colLens[j] ;
  for (int k = 0 ; k < lenj ; k++) {
    pkvec->insert(rowIndices[jj],coeffs[jj]) ;
    jj = colLinks[jj] ;
  }
  
  return (pkvec) ;
}
/*
  Extract a row from a CoinPostsolveMatrix. This is very painful, because
  the matrix is threaded column-ordered only. We have to scan every entry
  in the matrix, looking for entries that match the requested row index.
*/
CoinPackedVector *CoinPresolveMonitor::extractRow (int i,
					const CoinPostsolveMatrix *mtx) const
{
  const CoinBigIndex *colStarts = mtx->getColStarts() ;
  const int *colLens = mtx->getColLengths() ;
  const double *coeffs = mtx->getElementsByCol() ;
  const int *rowIndices = mtx->getRowIndicesByCol() ;
  const CoinBigIndex *colLinks = mtx->link_ ;

  int n = mtx->getNumCols() ;

  CoinPackedVector *pkvec = new CoinPackedVector() ;

  for (int j = 0 ; j < n ; j++) {
    const CoinBigIndex ii =
	presolve_find_row3(i,colStarts[j],colLens[j],rowIndices,colLinks) ;
    if (ii >= 0) pkvec->insert(j,coeffs[ii]) ;
  }

  return (pkvec) ;
}
Пример #13
0
void OsiSolver::add_in_constraint(LinearConstraint *con, double coef) {
    CoinPackedVector row;
    for (unsigned int i = 0; i < con->_variables.size(); ++i) {
        int *index = new int;
        MipWrapper_Expression *var = con->_variables[i];
        if (var->_var == NULL) {
            *index = n_cols++;
            var->_var = index;
            if (!var->_continuous) {
                hasIntegers = true;
                integer_vars.push_back(*index);
            }
        } else {
            index = (int*) var->_var;
        }
        col_lb[*index] = manageInfinity(var->_lower);
        col_ub[*index] = manageInfinity(var->_upper);
        row.insert(*index, con->_coefficients[i]);
    }
    row_lb[n_rows] = manageInfinity(con->_lhs);
    row_ub[n_rows] = manageInfinity(con->_rhs);
    n_rows++;
    matrix->appendRow(row);
}
Пример #14
0
void OsiIF::_addRows(ArrayBuffer<Row*> &rows)
{
	CoinPackedVector *coinrow = new CoinPackedVector();

	for (int i = 0; i < rows.size(); i++) {
		coinrow->clear();
		for (int j = 0; j < rows[i]->nnz(); j++){
			coinrow->insert(rows[i]->support(j), rows[i]->coeff(j));
		}
		lpSolverTime_.start();
		osiLP_->addRow(*coinrow, csense2osi(rows[i]->sense()), rows[i]->rhs(), 0.0);
		lpSolverTime_.stop();
	}

	delete coinrow;
	lpSolverTime_.start();
	numRows_ = osiLP_->getNumRows();
	rhs_ = osiLP_->getRightHandSide();
	numCols_ = osiLP_->getNumCols();
	collower_ = osiLP_->getColLower();
	colupper_ = osiLP_->getColUpper();
	lpSolverTime_.stop();

}
Пример #15
0
//#############################################################################
mcSol 
MibSHeuristic::solveSubproblem(double beta)
{

  /* 
     optimize wrt to weighted upper-level objective 
     over current feasible lp feasible region 
  */

  MibSModel * model = MibSModel_;
  OsiSolverInterface * oSolver = model->getSolver();
  //OsiSolverInterface * sSolver = new OsiCbcSolverInterface();  
  OsiSolverInterface* sSolver = new OsiSymSolverInterface();
  //sSolver = oSolver->clone();
  //OsiSolverInterface * sSolver = tmpSolver;
  //OsiSolverInterface * tmpSolver = new OsiSolverInterface(oSolver);
  
  double uObjSense(oSolver->getObjSense());
  double lObjSense(model->getLowerObjSense());  
  int lCols(model->getLowerDim());
  int uCols(model->getUpperDim());
  int * lColIndices = model->getLowerColInd();
  int * uColIndices = model->getUpperColInd();
  double * lObjCoeffs = model->getLowerObjCoeffs();
  const double * uObjCoeffs = oSolver->getObjCoefficients();

  double etol(etol_);
  int tCols(uCols + lCols); 

  assert(tCols == oSolver->getNumCols());


  sSolver->loadProblem(*oSolver->getMatrixByCol(),
		       oSolver->getColLower(), oSolver->getColUpper(),
		       oSolver->getObjCoefficients(),
		       oSolver->getRowLower(), oSolver->getRowUpper());

  int j(0);
  for(j = 0; j < tCols; j++){
    if(oSolver->isInteger(j))
      sSolver->setInteger(j);
  }


  double * nObjCoeffs = new double[tCols];
  int i(0), index(0);
  
  CoinZeroN(nObjCoeffs, tCols);
  
  /* Multiply the UL columns of the UL objective by beta */
  for(i = 0; i < uCols; i++){
    index = uColIndices[i];
    if(fabs(uObjCoeffs[index]) > etol)
      nObjCoeffs[index] = beta * uObjCoeffs[index] * uObjSense;
    else 
      nObjCoeffs[index] = 0.0;
  }
    
  /* Multiply the LL columns of the UL objective by beta */
  for(i = 0; i < lCols; i++){
    index = lColIndices[i];
    if(fabs(uObjCoeffs[index]) > etol)
      nObjCoeffs[index] = beta* uObjCoeffs[index] * uObjSense;
    else
      nObjCoeffs[index] = 0.0;
  }
  
  /* Add the LL columns of the LL objective multiplied by (1 - beta) */
  for(i = 0; i < lCols; i++){
    index = lColIndices[i];
    if(fabs(lObjCoeffs[i]) > etol)
      nObjCoeffs[index] += (1 - beta) * lObjCoeffs[i] * lObjSense;
  }
  
  sSolver->setObjective(nObjCoeffs);

  //int i(0);
  if(0){
    for(i = 0; i < sSolver->getNumCols(); i++){
      std::cout << "betaobj " << sSolver->getObjCoefficients()[i] << std::endl;
    }
  }

  if(0){
     sSolver->writeLp("afterbeta");
     //sSolver->writeMps("afterbeta");
  }
  
  if(0){  
    for(i = 0; i < sSolver->getNumCols(); i++){
      std::cout << "obj " << sSolver->getObjCoefficients()[i] << std::endl;
      std::cout << "upper " << sSolver->getColUpper()[i] << std::endl;
      std::cout << "lower " << sSolver->getColLower()[i] << std::endl;
    }
  }

  if(0){
    dynamic_cast<OsiCbcSolverInterface *> 
      (sSolver)->getModelPtr()->messageHandler()->setLogLevel(0);
  }
  else{
    dynamic_cast<OsiSymSolverInterface *> 
      (sSolver)->setSymParam("prep_level", -1);
    
    dynamic_cast<OsiSymSolverInterface *> 
      (sSolver)->setSymParam("verbosity", -2);

    dynamic_cast<OsiSymSolverInterface *> 
      (sSolver)->setSymParam("max_active_nodes", 1);
  }

  //dynamic_cast<OsiSymSolverInterface *> (sSolver)->branchAndBound();

  sSolver->branchAndBound();

  if(sSolver->isProvenOptimal()){

    if(0){
      std::cout << "writing lp file." << std::endl;
      sSolver->writeLp("afterbeta");
      //sSolver->writeMps("afterbeta");
    }
    
    double upperObjVal(0.0);
    double lowerObjVal(0.0);
    

    for(i = 0; i < tCols; i++){
      upperObjVal += 
	sSolver->getColSolution()[i] * oSolver->getObjCoefficients()[i];
      if(0){
	std::cout << "sSolver->getColSolution()[" << i << "] :"
		  << sSolver->getColSolution()[i] << std::endl;
      }
    }
    lowerObjVal = getLowerObj(sSolver->getColSolution(), lObjSense);
    
    if(beta == 1.0){
      
      /*
	fix upper-level objective to current value and 
	reoptimize wrt to lower-level objective
      */
      
      //OsiSolverInterface * nSolver = new OsiCbcSolverInterface();
      OsiSolverInterface * nSolver = new OsiSymSolverInterface();
      nSolver->loadProblem(*oSolver->getMatrixByCol(),
			   oSolver->getColLower(), oSolver->getColUpper(),
			   oSolver->getObjCoefficients(),
			   oSolver->getRowLower(), oSolver->getRowUpper());
      for(j = 0; j < tCols; j++){
	if(oSolver->isInteger(j))
	  nSolver->setInteger(j);
      }
      

      CoinZeroN(nObjCoeffs, tCols);
      
      for(i = 0; i < lCols; i++){
	index = lColIndices[i];
	nObjCoeffs[index] = lObjCoeffs[i] * lObjSense;
      }
      
      nSolver->setObjective(nObjCoeffs);
      
      CoinPackedVector objCon;
      
      for(i = 0; i < tCols; i++){
	objCon.insert(i, uObjCoeffs[i] * uObjSense);
      }
      
      nSolver->addRow(objCon, upperObjVal, upperObjVal);
      nSolver->writeLp("beta1");
      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);
      }

      nSolver->branchAndBound();
     

      double * colsol = new double[tCols];

      if(nSolver->isProvenOptimal()){
	lowerObjVal = nSolver->getObjValue();
	CoinCopyN(nSolver->getColSolution(), tCols, colsol);
      }
      else{
	//just take the current solution
	lowerObjVal = sSolver->getObjValue();
	CoinCopyN(sSolver->getColSolution(), tCols, colsol);
      }

      delete[] nObjCoeffs;
      nObjCoeffs = 0;
      delete sSolver;
      delete nSolver;
      return mcSol(std::make_pair(upperObjVal, lowerObjVal), colsol);
    }
    else if(beta == 0.0){
      
      /*
	fix lower-level objective to current value and 
	reoptimize wrt to upper-level objective
      */
      
      //OsiSolverInterface * nSolver = new OsiCbcSolverInterface();
      OsiSolverInterface * nSolver = new OsiSymSolverInterface();
      nSolver->loadProblem(*oSolver->getMatrixByCol(),
			   oSolver->getColLower(), oSolver->getColUpper(),
			   oSolver->getObjCoefficients(),
			   oSolver->getRowLower(), oSolver->getRowUpper());
      for(j = 0; j < tCols; j++){
	if(oSolver->isInteger(j))
	  nSolver->setInteger(j);
      }
      
      CoinZeroN(nObjCoeffs, tCols);
	
      for(i = 0; i < tCols; i++)
	nObjCoeffs[i] = uObjCoeffs[i] * uObjSense;
      
      nSolver->setObjective(nObjCoeffs);
	
      CoinPackedVector objCon;
	
      for(i = 0; i < lCols; i++){
	index = lColIndices[i];
	objCon.insert(index, lObjCoeffs[i] * lObjSense);  
      }
      
      nSolver->addRow(objCon, lowerObjVal, lowerObjVal);
      
      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);
      }

      if(0)      
	nSolver->writeLp("nSolver");
      

      nSolver->branchAndBound();
	
      double * colsol = new double[tCols];
	
      if(nSolver->isProvenOptimal()){
	upperObjVal = nSolver->getObjValue();
	CoinCopyN(nSolver->getColSolution(), tCols, colsol);
      }
      else{
	upperObjVal = nSolver->getObjValue();
	CoinCopyN(nSolver->getColSolution(), tCols, colsol);
      }

      delete[] nObjCoeffs;
      nObjCoeffs = 0;
      delete sSolver;
      delete nSolver;
      return mcSol(std::make_pair(upperObjVal, lowerObjVal), colsol);
	
    }
    else{
      
      //no optimality cut needed here.  all solutions are supported.
      
      double * colsol = new double[tCols];
      CoinCopyN(sSolver->getColSolution(), tCols, colsol);	
      
      delete[] nObjCoeffs;
      nObjCoeffs = 0;
      delete sSolver;
      return mcSol(std::make_pair(upperObjVal, lowerObjVal), colsol);
      
    }
    
  }
  else{
    //FIXME:SHOULD JUST TAKE THIS OUT.  DELETE sSolver and remove it from above
    
    nObjCoeffs = 0;
    delete[] nObjCoeffs;
    delete sSolver;
    std::cout << "Subproblem is not proven optimal." << std::endl;
    //return NULL;
    //abort();
  }
}
Пример #16
0
bool OSI_X_SolverWrapper<SOLVERINTERFACE>::setup(const LP_Constraints & cstraints) //cstraints <-> constraints
{
  bool bOk = true;
  if ( si == NULL )
  {
    return false;
  }
  assert(nbParams_ == cstraints.nbParams_);

  const unsigned int NUMVAR = cstraints.constraint_mat_.cols();
  std::vector<double> col_lb(NUMVAR);//the column lower bounds
  std::vector<double> col_ub(NUMVAR);//the column upper bounds

  this->nbParams_ = NUMVAR;

  si->setObjSense( ((cstraints.bminimize_) ? 1 : -1) );

  const Mat & A = cstraints.constraint_mat_;

  //Equality constraint will be done by two constraints due to the API limitation ( >= & <=).
  const size_t nbLine = A.rows() +
    std::count(cstraints.vec_sign_.begin(), cstraints.vec_sign_.end(), LP_Constraints::LP_EQUAL);

  std::vector<double> row_lb(nbLine);//the row lower bounds
  std::vector<double> row_ub(nbLine);//the row upper bounds

  CoinPackedMatrix * matrix = new CoinPackedMatrix(false,0,0);
  matrix->setDimensions(0, NUMVAR);

  //-- Add row-wise constraint
  size_t indexRow = 0;
  for (int i=0; i < A.rows(); ++i)
  {
    Vec temp = A.row(i);

    CoinPackedVector row;
    if ( cstraints.vec_sign_[i] == LP_Constraints::LP_EQUAL || cstraints.vec_sign_[i] == LP_Constraints::LP_LESS_OR_EQUAL )
    {
      int coef = 1;
      for ( int j = 0; j < A.cols() ; j++ )
      {
        row.insert(j, coef * temp.data()[j]);
      }
      row_lb[indexRow] = -1.0 * si->getInfinity();
      row_ub[indexRow] = coef * cstraints.constraint_objective_(i);
      matrix->appendRow(row);
      indexRow++;
    }
    if ( cstraints.vec_sign_[i] == LP_Constraints::LP_EQUAL || cstraints.vec_sign_[i] == LP_Constraints::LP_GREATER_OR_EQUAL )
    {
      int coef = -1;
      for ( int j = 0; j < A.cols() ; j++ )
      {
	      row.insert(j, coef * temp.data()[j]);
      }
      row_lb[indexRow] = -1.0 * si->getInfinity();
      row_ub[indexRow] = coef * cstraints.constraint_objective_(i);
      matrix->appendRow(row);
      indexRow++;
    }
  }

  //-- Setup bounds for all the parameters
  if (cstraints.vec_bounds_.size() == 1)
  {
    // Setup the same bound for all the parameters
    for (int i=0; i < this->nbParams_; ++i)
    {
      col_lb[i] = cstraints.vec_bounds_[0].first;
      col_ub[i] = cstraints.vec_bounds_[0].second;
    }
  }
  else // each parameter have it's own bounds
  {
    for (int i=0; i < this->nbParams_; ++i)
    {
      col_lb[i] = cstraints.vec_bounds_[i].first;
      col_ub[i] = cstraints.vec_bounds_[i].second;
    }
  }

  si->loadProblem(*matrix, &col_lb[0], &col_ub[0], cstraints.vec_cost_.empty() ? NULL : &cstraints.vec_cost_[0], &row_lb[0], &row_ub[0] );

  delete matrix;

  return bOk;
}
Пример #17
0
//===========================================================================//
DecompConstraintSet * ATM_DecompApp::createModelRelaxCount(){
   
   UtilPrintFuncBegin(m_osLog, m_classTag,
		      "createModelRelaxCount()", m_appParam.LogLevel, 2);
   
   int                a, d, t, nRows, pairIndex, nRowsMax;
   double             rhs, coefA, coefC;
   pair<int,int>      adP;
   vector<int>::const_iterator vi;
   
   const int           nSteps     = m_appParam.NumSteps;
   const int           nAtms      = m_instance.getNAtms();
   const int           nDates     = m_instance.getNDates();
   const int           nPairs     = m_instance.getNPairs();
   const int           nAtmsSteps = getNAtmsSteps();
   const vector<int> & pairsAD    = m_instance.getPairsAD();   

   const double      * a_ad      = m_instance.get_a_ad(); //dense storage
   const double      * b_ad      = m_instance.get_b_ad(); //dense storage
   const double      * c_ad      = m_instance.get_c_ad(); //dense storage
   const double      * d_ad      = m_instance.get_d_ad(); //dense storage
   const double      * e_ad      = m_instance.get_e_ad(); //dense storage
   const double      * w_ad      = m_instance.get_w_ad(); //dense storage
   const double      * B_d       = m_instance.get_B_d();

   const int           nCols     = numCoreCols();
   if(m_appParam.UseTightModel)
      nRowsMax  = nDates + 2*nAtms +   nAtmsSteps + 2*nPairs;
   else
      nRowsMax  = nDates +   nAtms + 3*nAtmsSteps + 2*nPairs;

   //TODO:
   // try the nested idea - so master has ConZtoX and we price without that
   //   but we solve with gap the harder oracle with those constraints

   //---
   //--- A' (relax):
   //---    for d in D:
   //---       sum{a in A} (f+[a,d] - f-[a,d]) <= B[d]  <---- makes it hard
   //OPT
   //---    for a in A:
   //---       sum{t in T}  x1[a,t] <= 1
   //OPT
   //---    for a in A, t in T:
   //---       z[a,t] <= x1[a,t],            
   //---       z[a,t] <= x2[a],              
   //---       z[a,t] >= x1[a,t] + x2[a] - 1.      

   //---    for a in A, d in D:
   //---       f+[a,d] - f-[a,d] =  
   //---         a[a,d] sum{t in T} (t/n) x1[a,t] +
   //---         b[a,d] x2[a]                     +     
   //---         c[a,d] sum{t in T} (t/n) z[a,t]  + 
   //---         d[a,d] x3[a]                     +
   //---         e[a,d]
   //---       f-[a,d] <= w[a,d] * v[a,d]
   //---
   
   DecompConstraintSet * model = new DecompConstraintSet();
   CoinAssertHint(model, "Error: Out of Memory");

   model->M = new CoinPackedMatrix(false, 0.0, 0.0);
   CoinAssertHint(model->M, "Error: Out of Memory");
   model->M->setDimensions(0, nCols);
   model->reserve(nRowsMax, nCols);

   //---
   //--- create nDates empty rowBudget packed vectors
   //---
   vector<CoinPackedVector> rowBudget;
   for(d = 0; d < nDates; d++){
      CoinPackedVector row;
      rowBudget.push_back(row);
   }

   nRows     = 0;
   pairIndex = 0;
   for(vi = pairsAD.begin(); vi != pairsAD.end(); vi++){
      adP = m_instance.getIndexADInv(*vi);
      a = adP.first;
      d = adP.second;

      //---
      //--- sum{a in A} (f+[a,d] - f-[a,d]) <= B[d]
      //---
      rowBudget[d].insert(getColOffset_fp() + pairIndex,  1.0);
      rowBudget[d].insert(getColOffset_fm() + pairIndex, -1.0);


      //---
      //---       f+[a,d] - f-[a,d] =  
      //---         a[a,d] sum{t in T} (t/n) x1[a,t] +
      //---         b[a,d] x2[a]                     +     
      //---         c[a,d] sum{t in T} (t/n) z[a,t]  + 
      //---         d[a,d] x3[a]                     +
      //---         e[a,d]
      //---
      CoinPackedVector row;
      string rowName = "demand_def(a_" 
	 + m_instance.getAtmName(a) + ",d_" 
	 + m_instance.getDateName(d) + ")";
      row.insert(colIndex_fp(pairIndex),  1.0);
      row.insert(colIndex_fm(pairIndex), -1.0);
      coefA = -a_ad[*vi] / nSteps;
      coefC = -c_ad[*vi] / nSteps;
      if(m_appParam.UseTightModel){
	 for(t = 0; t <= nSteps; t++){ 
	    row.insert(colIndex_x1(a,t), t * coefA);
	    row.insert(colIndex_z (a,t), t * coefC);
	 }
      }
      else{
	 for(t = 0; t < nSteps; t++){ 
	    row.insert(colIndex_x1(a,t), (t+1) * coefA);
	    row.insert(colIndex_z (a,t), (t+1) * coefC);
	 }
      }
      row.insert(colIndex_x2(a), -b_ad[*vi]);
      row.insert(colIndex_x3(a), -d_ad[*vi]);
      
      rhs = e_ad[*vi];
      model->appendRow(row, rhs, rhs, rowName);
      nRows++;

      //---
      //---       f-[a,d] <= w[a,d] * v[a,d]      
      //---
      CoinPackedVector rowLink;
      string rowNameLink = "linkv(a_" 
         + m_instance.getAtmName(a) + ",d_" 
         + m_instance.getDateName(d) + ")";	 
      rowLink.insert(colIndex_fm(pairIndex), 1.0);
      rowLink.insert(colIndex_v (pairIndex), -w_ad[*vi]);
      model->appendRow(rowLink, -DecompInf, 0.0, rowNameLink);
      nRows++;	 

      pairIndex++;
   }

   for(d = 0; d < nDates; d++){   
      string rowNameBudget = "budget(d_" + m_instance.getDateName(d) + ")";
      model->appendRow(rowBudget[d], -DecompInf, B_d[d], rowNameBudget);
      nRows++;
   }

   //---
   //---    for a in A:
   //---       sum{t in T}  x1[a,t] <= 1
   //---    for a in A, t in T:
   //---       z[a,t] <= x1[a,t],            
   //---       z[a,t] <= x2[a],              
   //---       z[a,t] >= x1[a,t] + x2[a] - 1.      
   //---   
   //THINK: if you use this, shouldn't we postprocess z=x1*x2?
   //  putting those constaints in master are unneccessary... 
   //  in fact, why not just do that in block version too... 
   //for(a = 0; a < nAtms; a++){
      //nRows += createConZtoX(model, a);
      //nRows += createConPickOne(model, a);
   //}
   assert(nRows <= nRowsMax);
   
   //---
   //--- create model columns
   //---
   createModelColumns(model);
   
   UtilPrintFuncEnd(m_osLog, m_classTag,
		    "createModelRelaxCount()", m_appParam.LogLevel, 2);

   return model;
}
Пример #18
0
//===========================================================================//
DecompConstraintSet * ATM_DecompApp::createModelRelax2(const int d){
   
   UtilPrintFuncBegin(m_osLog, m_classTag,
		      "createModelRelax2()", m_appParam.LogLevel, 2);
   
   int                a, t, nRows, pairIndex, nRowsMax;
   double             rhs, coefA, coefC;
   pair<int,int>      adP;
   vector<int>::const_iterator vi;
   
   const int           nSteps    = m_appParam.NumSteps;
   const int           nAtms     = m_instance.getNAtms();
   const vector<int> & pairsAD   = m_instance.getPairsAD();   

   const double      * a_ad      = m_instance.get_a_ad(); //dense storage
   const double      * b_ad      = m_instance.get_b_ad(); //dense storage
   const double      * c_ad      = m_instance.get_c_ad(); //dense storage
   const double      * d_ad      = m_instance.get_d_ad(); //dense storage
   const double      * e_ad      = m_instance.get_e_ad(); //dense storage
   const double      * w_ad      = m_instance.get_w_ad(); //dense storage
   const double      * B_d       = m_instance.get_B_d();

   const int           nCols     = numCoreCols();
   if(m_appParam.UseTightModel)
      nRowsMax  = 3*nAtms + 1 + getNAtmsSteps();
   else
      nRowsMax  = 2*nAtms + 1 + (3*getNAtmsSteps());

   //---
   //--- A'[d] for d in D (independent blocks)
   //---    for a in A
   //---       f+[a,d] - f-[a,d] =  
   //---         a[a,d] sum{t in T} (t/n) x1[a,t] +
   //---         b[a,d] x2[a]                     +     
   //---         c[a,d] sum{t in T} (t/n) z[a,t]  + 
   //---         d[a,d] x3[a]                     +
   //---         e[a,d]
   //---       f-[a,d] <= w[a,d] * v[a,d]
   //---    sum{a in A} (f+[a,d] - f-[a,d]) <= B[d]
   //---    for a in A, t in T:
   //---       z[a,t] <= x1[a,t],            
   //---       z[a,t] <= x2[a],              
   //---       z[a,t] >= x1[a,t] + x2[a] - 1.
   //---
   
   DecompConstraintSet * model = new DecompConstraintSet();
   CoinAssertHint(model, "Error: Out of Memory");

   model->M = new CoinPackedMatrix(false, 0.0, 0.0);
   CoinAssertHint(model->M, "Error: Out of Memory");
   model->M->setDimensions(0, nCols);
   model->reserve(nRowsMax, nCols);

   CoinPackedVector rowBudget;
   nRows     = 0;
   pairIndex = 0;
   for(vi = pairsAD.begin(); vi != pairsAD.end(); vi++){
      adP = m_instance.getIndexADInv(*vi);
      if(d != adP.second){
	 pairIndex++;
	 continue;      
      }
      a = adP.first;

      //---
      //--- sum{a in A} (f+[a,d] - f-[a,d]) <= B[d]
      //---
      rowBudget.insert(getColOffset_fp() + pairIndex,  1.0);
      rowBudget.insert(getColOffset_fm() + pairIndex, -1.0);


      //---
      //---       f+[a,d] - f-[a,d] =  
      //---         a[a,d] sum{t in T} (t/n) x1[a,t] +
      //---         b[a,d] x2[a]                     +     
      //---         c[a,d] sum{t in T} (t/n) z[a,t]  + 
      //---         d[a,d] x3[a]                     +
      //---         e[a,d]
      //---
      CoinPackedVector row;
      string rowName = "demand_def(a_" 
	 + m_instance.getAtmName(a) + ",d_" 
	 + m_instance.getDateName(d) + ")";
      row.insert(colIndex_fp(pairIndex),  1.0);
      row.insert(colIndex_fm(pairIndex), -1.0);
      coefA = -a_ad[*vi] / nSteps;
      coefC = -c_ad[*vi] / nSteps;
      if(m_appParam.UseTightModel){
	 for(t = 0; t <= nSteps; t++){ 
	    row.insert(colIndex_x1(a,t), t * coefA);
	    row.insert(colIndex_z (a,t), t * coefC);
	 }
      }
      else{
	 for(t = 0; t < nSteps; t++){ 
	    row.insert(colIndex_x1(a,t), (t+1) * coefA);
	    row.insert(colIndex_z (a,t), (t+1) * coefC);
	 }
      }
      row.insert(colIndex_x2(a), -b_ad[*vi]);
      row.insert(colIndex_x3(a), -d_ad[*vi]);

      rhs = e_ad[*vi];
      model->appendRow(row, rhs, rhs, rowName);
      nRows++;

      //---
      //---       f-[a,d] <= w[a,d] * v[a,d]      
      //---      
      CoinPackedVector rowLink;
      string rowNameLink = "linkv(a_" 
         + m_instance.getAtmName(a) + ",d_" 
         + m_instance.getDateName(d) + ")";	 
      rowLink.insert(colIndex_fm(pairIndex), 1.0);
      rowLink.insert(colIndex_v (pairIndex), -w_ad[*vi]);
      model->appendRow(rowLink, -DecompInf, 0.0, rowNameLink);
      nRows++;	 
   
      pairIndex++;
   }
   
   string rowNameBudget = "budget(d_" + m_instance.getDateName(d) + ")";
   model->appendRow(rowBudget, -DecompInf, B_d[d], rowNameBudget);
   nRows++;

  for(a = 0; a < nAtms; a++)
     nRows += createConZtoX(model, a);
   assert(nRows <= nRowsMax);
   
   //---
   //--- create model columns
   //---
   createModelColumns(model, -1, d);
   
   UtilPrintFuncEnd(m_osLog, m_classTag,
		    "createModelRelax2()", m_appParam.LogLevel, 2);

   return model;
}
Пример #19
0
//===========================================================================//
DecompConstraintSet * 
ATM_DecompApp::createModelRelax1(const int a,
				 bool      includeCount){
   
   UtilPrintFuncBegin(m_osLog, m_classTag,
		      "createModelRelax1()", m_appParam.LogLevel, 2);

   int                t, d, nRows, pairIndex;
   double             rhs, coefA, coefC;
   pair<int,int>      adP;
   vector<int>::const_iterator vi;
   
   const int           nSteps    = m_appParam.NumSteps;
   const int           nDates    = m_instance.getNDates();
   const vector<int> & pairsAD   = m_instance.getPairsAD();   

   const double      * a_ad      = m_instance.get_a_ad(); //dense storage
   const double      * b_ad      = m_instance.get_b_ad(); //dense storage
   const double      * c_ad      = m_instance.get_c_ad(); //dense storage
   const double      * d_ad      = m_instance.get_d_ad(); //dense storage
   const double      * e_ad      = m_instance.get_e_ad(); //dense storage
   const double      * w_ad      = m_instance.get_w_ad(); //dense storage

   const int           nCols     = numCoreCols();
   int                 nRowsMax  = nDates + 1 + (3*nSteps);
   if(includeCount)
      nRowsMax += nDates + 1;

   //---
   //---    for a in A, d in D:
   //---       f+[a,d] - f-[a,d] =  
   //---         a[a,d] sum{t in T} (t/n) x1[a,t] +
   //---         b[a,d] x2[a]                     +     
   //---         c[a,d] sum{t in T} (t/n) z[a,t]  + 
   //---         d[a,d] x3[a]                     +
   //---         e[a,d]
   //---       f-[a,d] <= w[a,d] * v[a,d]  (for count)
   //---    for a in A:
   //---       sum{t in T} x1[a,t] <= 1
   //---       sum{d in D} v[a,d]  <= K[a] (for count) [OPT]

   //Probably not... 
   //THINK: can't we just post-process this? z=x1*x2
   //---    for a in A, t in T:
   //---       z[a,t] <= x1[a,t],            
   //---       z[a,t] <= x2[a],              
   //---       z[a,t] >= x1[a,t] + x2[a] - 1.
   //---
   
   DecompConstraintSet * model = new DecompConstraintSet();
   CoinAssertHint(model, "Error: Out of Memory");

   model->M = new CoinPackedMatrix(false, 0.0, 0.0);
   CoinAssertHint(model->M, "Error: Out of Memory");
   model->M->setDimensions(0, nCols);
   model->M->reserve(nRowsMax, nCols);
   model->rowLB.reserve(nRowsMax);
   model->rowUB.reserve(nRowsMax);

   //---
   //---    for a in A, d in D:
   //---       f+[a,d] - f-[a,d] =  
   //---         a[a,d] sum{t in T} (t/n) x1[a,t] +
   //---         b[a,d] x2[a]                     +     
   //---         c[a,d] sum{t in T} (t/n) z[a,t]  + 
   //---         d[a,d] x3[a]                     +
   //---         e[a,d]
   //---       f-[a,d] <= w[a,d] * v[a,d]  (for count)
   //---
   nRows     = 0;
   pairIndex = 0;
   for(vi = pairsAD.begin(); vi != pairsAD.end(); vi++){
      adP = m_instance.getIndexADInv(*vi);
      if(a != adP.first){
	 pairIndex++;
	 continue;      
      }
      d = adP.second;

      CoinPackedVector row;
      string rowName = "demand_def(a_" 
	 + m_instance.getAtmName(a) + ",d_" 
	 + m_instance.getDateName(d) + ")";

      row.insert(colIndex_fp(pairIndex),  1.0);
      row.insert(colIndex_fm(pairIndex), -1.0);
      coefA = -a_ad[*vi] / nSteps;
      coefC = -c_ad[*vi] / nSteps;
      if(m_appParam.UseTightModel){
	 for(t = 0; t <= nSteps; t++){ 
	    row.insert(colIndex_x1(a,t), t * coefA);
	    row.insert(colIndex_z (a,t), t * coefC);
	 }
      }
      else{
	 for(t = 0; t < nSteps; t++){ 
	    row.insert(colIndex_x1(a,t), (t+1) * coefA);
	    row.insert(colIndex_z (a,t), (t+1) * coefC);
	 }
      }
      row.insert(colIndex_x2(a), -b_ad[*vi]);
      row.insert(colIndex_x3(a), -d_ad[*vi]);

      rhs = e_ad[*vi];
      model->M->appendRow(row);
      model->rowLB.push_back(rhs);
      model->rowUB.push_back(rhs);
      model->rowNames.push_back(rowName);      
      nRows++;
      
      CoinPackedVector rowLink;
      string rowNameLink = "linkv(a_" 
         + m_instance.getAtmName(a) + ",d_" 
         + m_instance.getDateName(d) + ")";	 
      rowLink.insert(colIndex_fm(pairIndex), 1.0);
      rowLink.insert(colIndex_v (pairIndex), -w_ad[*vi]);
      model->M->appendRow(rowLink);
      model->rowLB.push_back(-DecompInf);
      model->rowUB.push_back(0.0);
      model->rowNames.push_back(rowNameLink);	 
      nRows++;	 
   
      pairIndex++;
   }

   //---
   //---    for a in A:
   //---       sum{t in T} x1[a,t] <= 1
   //---       sum{d in D} v[a,d]  <= K[a] (for count)
   //---
   nRows += createConPickOne(model, a);
   if(includeCount)
      nRows += createConCount(model, a);
   
   //---
   //---    for a in A, t in T:
   //---       z[a,t] <= x1[a,t],            
   //---       z[a,t] <= x2[a],              
   //---       z[a,t] >= x1[a,t] + x2[a] - 1.
   //---
   nRows += createConZtoX(model, a);

   //---
   //--- create model columns
   //---
   createModelColumns(model, a);
   
   UtilPrintFuncEnd(m_osLog, m_classTag,
		    "createModelRelax1()", m_appParam.LogLevel, 2);
   
   return model;
}
Пример #20
0
bool OSI_X_SolverWrapper<SOLVERINTERFACE>::setup(const LP_Constraints & cstraints) //cstraints <-> constraints
{
  bool bOk = true;
  if ( si == NULL )
  {
    return false;
  }
  assert(_nbParams == cstraints._nbParams);

  
  int NUMVAR = cstraints._constraintMat.cols();
  int NUMCON = cstraints._constraintMat.rows();
  int NUMANZ = cstraints._constraintMat.cols() * cstraints._constraintMat.rows(); //DENSE MATRIX
  
  std::vector<double> col_lb(NUMVAR);//the column lower bounds
  std::vector<double> col_ub(NUMVAR);//the column upper bounds
  
  this->_nbParams = NUMVAR;

  if (cstraints._bminimize) 
  {
    si->setObjSense( 1 );
  }
  else  
  {
    si->setObjSense( -1 );
  }

  const Mat & A = cstraints._constraintMat;

  //Equality constraint will be handked by two constraintsdue to the API limitation. 
  size_t nbLine = A.rows() + std::count(cstraints._vec_sign.begin(), cstraints._vec_sign.end(), EQ);
  
  std::vector<double> row_lb(nbLine);//the row lower bounds
  std::vector<double> row_ub(nbLine);//the row upper bounds
  
  CoinPackedMatrix * matrix = new CoinPackedMatrix(false,0,0);
  matrix->setDimensions(0, NUMVAR);

  
  //-- Add row-wise constraint
  size_t indexRow = 0;
  for (int i=0; i < A.rows(); ++i) 
  {
    Vec temp = A.row(i);
    
    CoinPackedVector row;
    if ( cstraints._vec_sign[i] == EQ || cstraints._vec_sign[i] == LE )
    {
      int coef = 1;
      for ( int j = 0; j < A.cols() ; j++ )
      {
	row.insert(j, coef * temp.data()[j]);
      }
      row_lb[indexRow] = -1.0 * si->getInfinity();
      row_ub[indexRow] = coef * cstraints._Cst_objective(i);
      matrix->appendRow(row);
      indexRow++;
    }
    if ( cstraints._vec_sign[i] == EQ || cstraints._vec_sign[i] == GE )
    {
      int coef = -1;
      for ( int j = 0; j < A.cols() ; j++ )
      {
	      row.insert(j, coef * temp.data()[j]);
      }
      row_lb[indexRow] = -1.0 * si->getInfinity();
      row_ub[indexRow] = coef * cstraints._Cst_objective(i);
      matrix->appendRow(row);      
      indexRow++;
    }
  }
  
  //-- Setup bounds
  if (cstraints._vec_bounds.size() == 1) 
  {
    // Setup the same bound for all the parameter
    for (int i=0; i < this->_nbParams; ++i)
    {
      col_lb[i] = cstraints._vec_bounds[0].first;
      col_ub[i] = cstraints._vec_bounds[0].second;
    }
  }
  else  
  {

    for (int i=0; i < this->_nbParams; ++i)
    {      
      col_lb[i] = cstraints._vec_bounds[i].first;
      col_ub[i] = cstraints._vec_bounds[i].second;
    }
  }  
 
  si->loadProblem(*matrix, &col_lb[0], &col_ub[0], cstraints._vec_cost.empty() ? NULL : &cstraints._vec_cost[0], &row_lb[0], &row_ub[0] );
  
  delete matrix;
  
  return bOk;
}
Пример #21
0
//===========================================================================//
void MCF_DecompApp::createModelRelaxSparse(DecompConstraintSet* model,
      int                   commId)
{
   //---
   //--- SUBPROBLEM (A'): (one block for each k in K)
   //---      sum{(j,i) in A} x[k,i,j] -
   //---         sum{(i,j) in A} x[k,i,j] = d[i,k], for all i in N
   //---      x[k,i,j] integer >= l[i,j] <= u[i,j], for all (i,j) in A
   //--- For k=(s,t) in K,
   //---    d[i,k] = -d[k] if i=s
   //---           =  d[k] if i=t
   //---           =  0, otherwise
   //---
   int         a, i, head, tail, origColIndex, source, sink;
   int         numArcs        = m_instance.m_numArcs;
   int         numNodes       = m_instance.m_numNodes;
   int         numCommodities = m_instance.m_numCommodities;
   int         numCols        = numArcs;
   int         numRows        = numNodes;
   int         numColsOrig    = numArcs * numCommodities;
   MCF_Instance::arc*        arcs        = m_instance.m_arcs;
   MCF_Instance::commodity* commodities = m_instance.m_commodities;
   UtilPrintFuncBegin(m_osLog, m_classTag,
                      "createModelRelaxSparse()", m_appParam.LogLevel, 2);
   //---
   //--- create space for the model matrix (row-majored)
   //---
   model->M = new CoinPackedMatrix(false, 0.0, 0.0);

   if (!model->M) {
      throw UtilExceptionMemory("createModelCore", "MCF_DecompApp");
   }

   model->M->setDimensions(0, numCols);
   model->reserve(numRows, numCols);
   model->setSparse(numColsOrig);
   //---
   //--- get this commodity's source and sink node
   //---
   source = commodities[commId].source;
   sink   = commodities[commId].sink;

   //---
   //--- create the rows
   //---   NOTE: this is somewhat inefficient (but simple)
   //---
   for (i = 0; i < numNodes; i++) {
      CoinPackedVector row;

      for (a = 0; a < numArcs; a++) {
         tail = arcs[a].tail;
         head = arcs[a].head;

         if (head == i) {
            row.insert(a, 1.0);
         } else if (tail == i) {
            row.insert(a, -1.0);
         }
      }

      if (i == source)
         model->appendRow(row,
                          -commodities[commId].demand,
                          -commodities[commId].demand);
      else if (i == sink)
         model->appendRow(row,
                          commodities[commId].demand,
                          commodities[commId].demand);
      else {
         model->appendRow(row, 0.0, 0.0);
      }
   }

   //---
   //--- set the colLB, colUB, integerVars and sparse mapping
   //---
   origColIndex = commId * numArcs;

   for (a = 0; a < numArcs; a++) {
      double           arcLB = arcs[a].lb;
      double           arcUB = arcs[a].ub;
      model->pushCol(arcLB, arcUB, true, origColIndex);
      origColIndex++;
   }

   UtilPrintFuncEnd(m_osLog, m_classTag,
                    "createModelRelaxSparse()", m_appParam.LogLevel, 2);
}
Пример #22
0
//#############################################################################
void 
MibSHeuristic::objCutHeuristic()
{

  /* Solve the LP relaxation with the new constraint d^2 y <= d^y* */

  MibSModel * model = MibSModel_;

  //OsiSolverInterface * oSolver = model->origLpSolver_;
  OsiSolverInterface * oSolver = model->getSolver();
  //OsiSolverInterface * hSolver = new OsiCbcSolverInterface();
  OsiSolverInterface * hSolver = new OsiSymSolverInterface();

  double objSense(model->getLowerObjSense());  
  int lCols(model->getLowerDim());
  int uCols(model->getUpperDim());
  int tCols(lCols + uCols);
  int * lColIndices = model->getLowerColInd();
  int * uColIndices = model->getUpperColInd();
  double * lObjCoeffs = model->getLowerObjCoeffs();

  hSolver->loadProblem(*oSolver->getMatrixByCol(),
		       oSolver->getColLower(), oSolver->getColUpper(),
		       oSolver->getObjCoefficients(),
		       oSolver->getRowLower(), oSolver->getRowUpper());

  int j(0);
  for(j = 0; j < tCols; j++){
    if(oSolver->isInteger(j))
      hSolver->setInteger(j);
  }

  double * optLowerSolutionOrd = model->bS_->optLowerSolutionOrd_;

  CoinPackedVector objCon;
  int i(0), index(0);
  double rhs(0.0);

  for(i = 0; i < lCols; i++){
    index = lColIndices[i];
    objCon.insert(index, lObjCoeffs[i] * objSense);
    //should this be ordered? and should lObjCoeffs by at index?
    //rhs += optLowerSolutionOrd_[i] * lObjCoeffs[i] * objSense;
    rhs += optLowerSolutionOrd[i] * lObjCoeffs[i] * objSense;
  }

  //Hmm, I think this was wrong before...?
  //  hSolver->addRow(objCon, - hSolver->getInfinity(), rhs);
  hSolver->addRow(objCon, rhs, hSolver->getInfinity());

  /* optimize w.r.t. to the UL objective with the new row */
  if(0){
    dynamic_cast<OsiCbcSolverInterface *> 
      (hSolver)->getModelPtr()->messageHandler()->setLogLevel(0);
  }
  else{
    dynamic_cast<OsiSymSolverInterface *> 
      (hSolver)->setSymParam("prep_level", -1);
    
    dynamic_cast<OsiSymSolverInterface *> 
      (hSolver)->setSymParam("verbosity", -2);

    dynamic_cast<OsiSymSolverInterface *> 
      (hSolver)->setSymParam("max_active_nodes", 1);
  }

  hSolver->branchAndBound();

  if(0)
    hSolver->writeLp("objcutheuristic");

  if(hSolver->isProvenOptimal()){

    MibSSolution *mibSol = NULL;

    OsiSolverInterface * lSolver = model->bS_->setUpModel(hSolver, true);

    if(0){
       dynamic_cast<OsiCbcSolverInterface *> 
	  (lSolver)->getModelPtr()->messageHandler()->setLogLevel(0);
    }    
    else{
       dynamic_cast<OsiSymSolverInterface *> 
	  (lSolver)->setSymParam("prep_level", -1);
       
       dynamic_cast<OsiSymSolverInterface *> 
	  (lSolver)->setSymParam("verbosity", -2);
       
       dynamic_cast<OsiSymSolverInterface *> 
	  (lSolver)->setSymParam("max_active_nodes", 1);
    }

    lSolver->branchAndBound();

    const double * sol = hSolver->getColSolution();
    double objVal(lSolver->getObjValue() * objSense);
    double etol(etol_);
    double lowerObj = getLowerObj(sol, objSense);  
    
    double * optUpperSolutionOrd = new double[uCols];
    double * optLowerSolutionOrd = new double[lCols];
    
    CoinZeroN(optUpperSolutionOrd, uCols);
    CoinZeroN(optLowerSolutionOrd, lCols);

    if(fabs(objVal - lowerObj) < etol){
    
      /** Current solution is bilevel feasible **/
     
      mibSol = new MibSSolution(hSolver->getNumCols(),
				hSolver->getColSolution(),
				hSolver->getObjValue(),
				model);

     model->storeSolution(BlisSolutionTypeHeuristic, mibSol);
     mibSol = NULL;
 
    }
    else{

      /* solution is not bilevel feasible, create one that is */

     const double * uSol = hSolver->getColSolution();
     const double * lSol = lSolver->getColSolution();
     //int numElements(lSolver->getNumCols());
     int numElements(hSolver->getNumCols());
     int i(0), pos(0), index(0);
     double * lpSolution = new double[numElements];
     double upperObj(0.0);

     //FIXME: problem is still here.  indices may be wrong.  
     //also is all this necessary, or can we just paste together uSol and lSol?
     
     for(i = 0; i < numElements; i++){
       //index = indices[i];
       pos = model->bS_->binarySearch(0, lCols - 1, i, lColIndices);
       if(pos < 0){
	 pos = model->bS_->binarySearch(0, uCols - 1, i, uColIndices);
	 //optUpperSolutionOrd[pos] = values[i];
	 //optUpperSolutionOrd[pos] = uSol[pos];
	 if (pos >= 0){
	    optUpperSolutionOrd[pos] = uSol[i];
	 }
       }
       else{
	 //optLowerSolutionOrd[pos] = lSol[i];
	 optLowerSolutionOrd[pos] = lSol[pos];
       }
     }

     for(i = 0; i < uCols; i++){
       index = uColIndices[i];
       lpSolution[index] = optUpperSolutionOrd[i];
       upperObj += 
	 optUpperSolutionOrd[i] * hSolver->getObjCoefficients()[index];
     }

     for(i = 0; i < lCols; i++){
       index = lColIndices[i];
       lpSolution[index] = optLowerSolutionOrd[i];
       upperObj += 
	 optLowerSolutionOrd[i] * hSolver->getObjCoefficients()[index];
     }

     if(model->checkUpperFeasibility(lpSolution)){
       mibSol = new MibSSolution(hSolver->getNumCols(),
				 lpSolution,
				 upperObj * hSolver->getObjSense(),
				 model);

       model->storeSolution(BlisSolutionTypeHeuristic, mibSol);
       mibSol = NULL;
     }
     delete [] lpSolution;
    }
    delete lSolver;
  }

  delete hSolver;

}
/** Get an inner-approximation constraint obtained by drawing a chord linking the two given points x and x2. 
 * This only applies to nonlinear constraints featuring univariate functions (f(x) <= y).**/
bool
HeuristicInnerApproximation::getMyInnerApproximation(Bonmin::OsiTMINLPInterface &si, OsiCuts &cs, int ind,
    const double * x, const double * x2) {

  int n, m, nnz_jac_g, nnz_h_lag;
  Ipopt::TNLP::IndexStyleEnum index_style;
  Bonmin::TMINLP2TNLP * problem = si.problem(); 
  problem->get_nlp_info(n, m, nnz_jac_g, nnz_h_lag, index_style);
  double infty = si.getInfinity();


  CoinPackedVector cut;
  double lb = -infty;
  double ub = 0;


  double g = 0;
  double g2 = 0;
  double diff = 0;
  double a = 0;
  problem->eval_gi(n, x, 1, ind, g);
  problem->eval_gi(n, x2, 1, ind, g2);
  Bonmin::vector<int> jCol(n);
  int nnz;
  problem->eval_grad_gi(n, x2, 0, ind, nnz, jCol(), NULL);
  Bonmin::vector<double> jValues(nnz);
  problem->eval_grad_gi(n, x2, 0, ind, nnz, NULL, jValues());
  bool add = false;
  //printf("const %i nnz %i\n", ind, nnz);
  for (int i = 0; i < nnz; i++) {
    const int &colIdx = jCol[i];
    if(index_style == Ipopt::TNLP::FORTRAN_STYLE) jCol[i]--;
    diff = x[colIdx] - x2[colIdx];

    if (fabs(diff) >= 1e-8) {
       a = (g - g2) / diff;
       cut.insert(colIdx, a);
       ub = (a * x[colIdx] - g) - fabs(a * x[colIdx] - g)*1e-6;
       //printf("const %i col %i p[col] %g pp[col] %g g %g g2 %g diff %g\n",ind, colIdx, x[colIdx], x2[colIdx], g, g2, diff);
       add = true;
    } else {
       cut.insert(colIdx, jValues[i]);
       //printf("const %i col %i val %g\n",ind, colIdx, jValues[i]);
    }
  }

  if (add) {

    OsiRowCut newCut;
    newCut.setGloballyValidAsInteger(1);
    newCut.setLb(lb);
    
      //********* Perspective Extension ********//
    int binary_id = 0; // index corresponding to the binary variable activating the corresponding constraint
    const int* ids = problem->get_const_xtra_id(); // vector of indices corresponding to the binary variable activating the corresponding constraint
    // Get the index of the corresponding indicator binary variable
    binary_id = (ids == NULL) ? -1 : ids[ind];
    if(binary_id>0) {// If this hyperplane is a linearization of a disjunctive constraint, we link its righthand side to the corresponding indicator binary variable
        cut.insert(binary_id, -ub); // ∂x ≤ ub => ∂x - ub*z ≤ 0
        newCut.setUb(0);
    }
    else
        newCut.setUb(ub);
    //********* Perspective Extension ********//

    newCut.setRow(cut);
    cs.insert(newCut);
    //newCut.print();
    return true;
  }
  return false;
}
Пример #24
0
bool OSI_X_SolverWrapper::setup(const LP_Constraints & cstraints) //cstraints <-> constraints
{
  if ( si == nullptr )
  {
    return false;
  }
  assert(nbParams_ == cstraints.nbParams_);

  const unsigned int NUMVAR = cstraints.constraint_mat_.cols();
  std::vector<double>
    col_lb(NUMVAR), // the column lower bounds
    col_ub(NUMVAR); // the column upper bounds

  this->nbParams_ = NUMVAR;

  si->setObjSense( ((cstraints.bminimize_) ? 1 : -1) );

  const Mat & A = cstraints.constraint_mat_;

  //Equality constraint will be done by two constraints due to the API limitation ( >= & <=).
  const size_t nbLine = A.rows() +
    std::count(cstraints.vec_sign_.begin(), cstraints.vec_sign_.end(), LP_Constraints::LP_EQUAL);

  // Define default lower and upper bound to [-inf, inf]
  std::vector<double>
    row_lb(nbLine, -si->getInfinity()), // the row lower bounds
    row_ub(nbLine, si->getInfinity()); // the row upper bounds

  std::unique_ptr<CoinPackedMatrix> matrix(new CoinPackedMatrix(false,0,0));
  matrix->setDimensions(0, NUMVAR);

  //-- Add row-wise constraint
  size_t indexRow = 0;
  for (int i=0; i < A.rows(); ++i)
  {
    const Vec temp = A.row(i);
    CoinPackedVector row;

    if (cstraints.vec_sign_[i] == LP_Constraints::LP_EQUAL ||
        cstraints.vec_sign_[i] == LP_Constraints::LP_LESS_OR_EQUAL)
    {
      const int coef = 1;
      for ( int j = 0; j < A.cols(); ++j )
      {
        row.insert(j, coef * temp.data()[j]);
      }
      row_ub[indexRow] = coef * cstraints.constraint_objective_(i);
      matrix->appendRow(row);
      ++indexRow;
    }

    if (cstraints.vec_sign_[i] == LP_Constraints::LP_EQUAL ||
        cstraints.vec_sign_[i] == LP_Constraints::LP_GREATER_OR_EQUAL)
    {
      const int coef = -1;
      for ( int j = 0; j < A.cols(); ++j )
      {
        row.insert(j, coef * temp.data()[j]);
      }
      row_ub[indexRow] = coef * cstraints.constraint_objective_(i);
      matrix->appendRow(row);
      ++indexRow;
    }
  }

  //-- Setup bounds for all the parameters
  if (cstraints.vec_bounds_.size() == 1)
  {
    // Setup the same bound for all the parameters
    std::fill(col_lb.begin(), col_lb.end(), cstraints.vec_bounds_[0].first);
    std::fill(col_ub.begin(), col_ub.end(), cstraints.vec_bounds_[0].second);
  }
  else // each parameter have its own bounds
  {
    for (int i=0; i < this->nbParams_; ++i)
    {
      col_lb[i] = cstraints.vec_bounds_[i].first;
      col_ub[i] = cstraints.vec_bounds_[i].second;
    }
  }

  si->loadProblem(*matrix, &col_lb[0], &col_ub[0], cstraints.vec_cost_.empty() ? nullptr : &cstraints.vec_cost_[0], &row_lb[0], &row_ub[0] );

  return true;
}
Пример #25
0
// --------------------------------------------------------------------- //
int GAP_DecompApp::createModelPartAP(DecompConstraintSet* model)
{
   int             i, j, colIndex;
   int             status     = GAPStatusOk;
   int             nTasks     = m_instance.getNTasks();    //n
   int             nMachines  = m_instance.getNMachines(); //m
   int             nCols      = nTasks * nMachines;
   int             nRows      = nTasks;
   UtilPrintFuncBegin(m_osLog, m_classTag,
                      "createModelPartAP()", m_appParam.LogLevel, 2);
   //---
   //--- Build the core model constraints (AP = assignment problem).
   //---
   //--- m is number of machines (index i)
   //--- n is number of tasks    (index j)
   //---
   //--- sum{i in 1..m} x[i,j] = 1, j in 1..n
   //---
   //--- Example structure: m=3, n=4
   //---  x   x   x     = 1 [j=1]
   //---   x   x   x    = 1 [j=2]
   //---    x   x   x   = 1 [j=3]
   //---     x   x   x  = 1 [j=4]
   //---
   //---
   //--- Allocate an empty row-ordered CoinPackedMatrix. Since we plan
   //---   to add rows, set the column dimension and let the row dimension
   //---   be set dynamically.
   //---
   model->M = new CoinPackedMatrix(false, 0.0, 0.0);
   CoinAssertHint(model->M, "Error: Out of Memory");
   model->M->setDimensions(0, nCols);
   //---
   //--- we know the sizes needed, so reserve space for them (for efficiency)
   //---
   model->reserve(nRows, nCols);

   //---
   //--- create one row per task
   //---   rowNames are not needed, they are used for debugging
   //---
   for (j = 0; j < nTasks; j++) {
      CoinPackedVector row;
      string           rowName = "a(j_" + UtilIntToStr(j) + ")";

      for (i = 0; i < nMachines; i++) {
         colIndex = getIndexIJ(i, j);
         row.insert(colIndex, 1.0);
      }

      model->appendRow(row, 1.0, 1.0, rowName);
   }

   //---
   //--- set the col upper and lower bounds (all in [0,1])
   //---
   UtilFillN(model->colLB, nCols,  0.0);
   UtilFillN(model->colUB, nCols,  1.0);
   //---
   //--- set the indices of the integer variables of model
   //---   (all vars are binary)
   //---
   UtilIotaN(model->integerVars, nCols, 0);
   //---
   //--- set column names for debugging
   //---
   colIndex = 0;

   for (i = 0; i < nMachines; i++) {
      for (j = 0; j < nTasks; j++) {
         string colName = "x("
                          + UtilIntToStr(colIndex) + "_"
                          + UtilIntToStr(i) + "," + UtilIntToStr(j) + ")";
         model->colNames.push_back(colName);
         colIndex++;
      }
   }

   UtilPrintFuncEnd(m_osLog, m_classTag,
                    "createModelPartAP()", m_appParam.LogLevel, 2);
   return status;
}
Пример #26
0
//===========================================================================//
int GAP_DecompApp::createModelPartKP(DecompConstraintSet* model,
                                     vector<int>&          whichKnaps)
{
   int          i, j, b, colIndex;
   int          status     = GAPStatusOk;
   int          nTasks     = m_instance.getNTasks();    //n
   int          nMachines  = m_instance.getNMachines(); //m
   int          nKnaps     = static_cast<int>(whichKnaps.size());
   const int*   weight     = m_instance.getWeight();
   const int*   capacity   = m_instance.getCapacity();
   int          nCols      = nTasks * nMachines;
   int          nRows      = nKnaps;
   UtilPrintFuncBegin(m_osLog, m_classTag,
                      "createModelPartKP()", m_appParam.LogLevel, 2);
   //---
   //--- Build the relax model constraints (KP = assignment problem).
   //---
   //--- m is number of machines (index i)
   //--- n is number of tasks    (index j)
   //---
   //--- sum{j in 1..n} w[i,j] x[i,j] <= b[i], i in 1..m
   //--- x[i,j] in {0,1}, i in 1..m, j in 1..n
   //---
   //--- Example structure: m=3, n=4
   //---  xxxx         <= b[i=1]
   //---      xxxx     <= b[i=2]
   //---          xxxx <= b[i=3]
   //---
   //---
   //--- Allocate an empty row-ordered CoinPackedMatrix. Since we plan
   //---   to add rows, set the column dimension and let the row dimension
   //---   be set dynamically.
   //---
   model->M = new CoinPackedMatrix(false, 0.0, 0.0);
   CoinAssertHint(model->M, "Error: Out of Memory");
   model->M->setDimensions(0, nCols);
   //---
   //--- we know the sizes needed, so reserve space for them (for efficiency)
   //---
   model->reserve(nRows, nCols);
   //---
   //--- create one row per knapsack
   //---   rowNames are not needed, they are used for debugging
   //---
   vector<int>::iterator it;

   for (it = whichKnaps.begin(); it != whichKnaps.end(); ++it) {
      i = *it;
      CoinPackedVector row;
      string           rowName = "k(i_" + UtilIntToStr(i) + ")";

      for (j = 0; j < nTasks; j++) {
         colIndex = getIndexIJ(i, j);
         row.insert(colIndex, weight[colIndex]);
      }

      model->appendRow(row, -m_infinity, capacity[i], rowName);
   }

   //---
   //--- set the col upper and lower bounds (all in [0,1])
   //---
   UtilFillN(model->colLB, nCols,  0.0);
   UtilFillN(model->colUB, nCols,  1.0);
   //---
   //--- set the indices of the integer variables of model
   //---
   UtilIotaN(model->integerVars, nCols, 0);

   //---
   //--- tell the solver which columns are active (in this block)
   //---
   for (it = whichKnaps.begin(); it != whichKnaps.end(); ++it) {
      b = *it;

      for (i = 0; i < nMachines; i++) {
         for (j = 0; j < nTasks; j++) {
            colIndex = getIndexIJ(i, j);

            if (i == b) {
               model->activeColumns.push_back(colIndex);
            }
         }
      }
   }

   //---
   //--- set column names for debugging
   //---
   colIndex = 0;

   for (i = 0; i < nMachines; i++) {
      for (j = 0; j < nTasks; j++) {
         string colName = "x("
                          + UtilIntToStr(colIndex) + "_"
                          + UtilIntToStr(i) + "," + UtilIntToStr(j) + ")";
         model->colNames.push_back(colName);
         colIndex++;
      }
   }

   UtilPrintFuncEnd(m_osLog, m_classTag,
                    "createModelPartKP()", m_appParam.LogLevel, 2);
   return status;
}
Пример #27
0
//#############################################################################
void 
MibSHeuristic::lowerObjHeuristic()
{

  /* 
     optimize wrt to lower-level objective 
     over current feasible lp feasible region 
  */

  MibSModel * model = MibSModel_;

  OsiSolverInterface * oSolver = model->getSolver();
  //OsiSolverInterface * hSolver = new OsiCbcSolverInterface();
  OsiSolverInterface* hSolver = new OsiSymSolverInterface();

  double objSense(model->getLowerObjSense());  
  int lCols(model->getLowerDim());
  int uCols(model->getUpperDim());
  int * lColIndices = model->getLowerColInd();
  int * uColIndices = model->getUpperColInd();
  double * lObjCoeffs = model->getLowerObjCoeffs();
  
  //int tCols(lCols + uCols);
  int tCols(oSolver->getNumCols());
  //assert(tCols == oSolver->getNumCols());

  hSolver->loadProblem(*oSolver->getMatrixByCol(),
		       oSolver->getColLower(), oSolver->getColUpper(),
		       oSolver->getObjCoefficients(),
		       oSolver->getRowLower(), oSolver->getRowUpper());

  int j(0);
  for(j = 0; j < tCols; j++){
    if(oSolver->isInteger(j))
      hSolver->setInteger(j);
  }

  double * nObjCoeffs = new double[tCols];
  int i(0), index(0);
  
  CoinZeroN(nObjCoeffs, tCols);

  for(i = 0; i < lCols; i++){
    index = lColIndices[i];
    nObjCoeffs[index] = lObjCoeffs[i];
  }

  //MibS objective sense is the opposite of OSI's!
  hSolver->setObjSense(objSense);

  hSolver->setObjective(nObjCoeffs);
 
  //double cutoff(model->getCutoff());
  double cutoff(model->getKnowledgeBroker()->getIncumbentValue());

  if(model->getNumSolutions()){
  
    CoinPackedVector objCon;
    //double rhs(cutoff * objSense);
    //double smlTol(1.0);
    double rhs(cutoff);
       
    for(i = 0; i < tCols; i++){
      objCon.insert(i, oSolver->getObjCoefficients()[i] 
		    * oSolver->getObjSense());
    }
    
    hSolver->addRow(objCon, - hSolver->getInfinity(), rhs);
  }
  
  if(0)
     hSolver->writeLp("lobjheurstic");

  if(0){
    dynamic_cast<OsiCbcSolverInterface *> 
      (hSolver)->getModelPtr()->messageHandler()->setLogLevel(0);
  }    
  else{
    dynamic_cast<OsiSymSolverInterface *> 
      (hSolver)->setSymParam("prep_level", -1);
    
    dynamic_cast<OsiSymSolverInterface *> 
      (hSolver)->setSymParam("verbosity", -2);

    dynamic_cast<OsiSymSolverInterface *> 
      (hSolver)->setSymParam("max_active_nodes", 1);
  }

  hSolver->branchAndBound();

  if(hSolver->isProvenOptimal()){

    double upperObjVal(0.0);

    /*****************NEW ******************/

    MibSSolution *mibSol = NULL;

    OsiSolverInterface * lSolver = model->bS_->setUpModel(hSolver, true);

    if(0){
       lSolver->writeLp("tmp");
    }

    if(0){
       dynamic_cast<OsiCbcSolverInterface *> 
	  (lSolver)->getModelPtr()->messageHandler()->setLogLevel(0);
    }    
    else{
       dynamic_cast<OsiSymSolverInterface *> 
	  (lSolver)->setSymParam("prep_level", -1);
       
       dynamic_cast<OsiSymSolverInterface *> 
	  (lSolver)->setSymParam("verbosity", -2);
       
       dynamic_cast<OsiSymSolverInterface *> 
	  (lSolver)->setSymParam("max_active_nodes", 1);
    }

    lSolver->branchAndBound();

    if (lSolver->isProvenOptimal()){
       const double * sol = hSolver->getColSolution();
       double objVal(lSolver->getObjValue() * objSense);
       double etol(etol_);
       double lowerObj = getLowerObj(sol, objSense);  
       
       double * optUpperSolutionOrd = new double[uCols];
       double * optLowerSolutionOrd = new double[lCols];
       
       CoinZeroN(optUpperSolutionOrd, uCols);
       CoinZeroN(optLowerSolutionOrd, lCols);
       
       if(fabs(objVal - lowerObj) < etol){
	  
	  /** Current solution is bilevel feasible **/
	  
	  for(i = 0; i < tCols; i++)
	     upperObjVal += 
		hSolver->getColSolution()[i] * oSolver->getObjCoefficients()[i];
	  
	  mibSol = new MibSSolution(hSolver->getNumCols(),
				    hSolver->getColSolution(),
				    upperObjVal,
				    model);
	  
	  model->storeSolution(BlisSolutionTypeHeuristic, mibSol);
	  mibSol = NULL;
       }
       else{
	  
	  /* solution is not bilevel feasible, create one that is */
	  
	  const double * uSol = hSolver->getColSolution();
	  const double * lSol = lSolver->getColSolution();
	  int numElements(hSolver->getNumCols());
	  int i(0), pos(0), index(0);
	  double * lpSolution = new double[numElements];
	  double upperObj(0.0);
	  
	  //FIXME: problem is still here.  indices may be wrong.  
	  //also is all this necessary, or can we just paste together uSol and lSol?
	  //this may be an old comment
	  
	  for(i = 0; i < numElements; i++){
	     pos = model->bS_->binarySearch(0, lCols - 1, i, lColIndices);
	     if(pos < 0){
		pos = model->bS_->binarySearch(0, uCols - 1, i, uColIndices);
		if (pos >= 0){
		   optUpperSolutionOrd[pos] = uSol[i];
		}
	     }
	     else{
		optLowerSolutionOrd[pos] = lSol[pos];
	     }
	  }
	  
	  for(i = 0; i < uCols; i++){
	     index = uColIndices[i];
	     lpSolution[index] = optUpperSolutionOrd[i];
	     upperObj += 
		optUpperSolutionOrd[i] * oSolver->getObjCoefficients()[index];
	  }
	  
	  for(i = 0; i < lCols; i++){
	     index = lColIndices[i];
	     lpSolution[index] = optLowerSolutionOrd[i];
	     upperObj += 
		optLowerSolutionOrd[i] * oSolver->getObjCoefficients()[index];
	  }
	  
	  if(model->checkUpperFeasibility(lpSolution)){
	     mibSol = new MibSSolution(hSolver->getNumCols(),
				       lpSolution,
				       upperObj * oSolver->getObjSense(),
				       model);
	     
	     model->storeSolution(BlisSolutionTypeHeuristic, mibSol);
	     mibSol = NULL;
	  }
	  delete [] lpSolution;
       }
    }
    delete lSolver;
  }
  delete hSolver;

}
Пример #28
0
LPSolver::Status LPSolver::optimize(
    OptimizationGoal goal,        // goal of optimization (minimize or maximize)
    Array<double> &obj,           // objective function vector
    Array<int>    &matrixBegin,   // matrixBegin[i] = begin of column i
    Array<int>    &matrixCount,   // matrixCount[i] = number of nonzeroes in column i
    Array<int>    &matrixIndex,   // matrixIndex[n] = index of matrixValue[n] in its column
    Array<double> &matrixValue,	  // matrixValue[n] = non-zero value in matrix
    Array<double> &rightHandSide, // right-hand side of LP constraints
    Array<char>   &equationSense, // 'E' ==   'G' >=   'L' <=
    Array<double> &lowerBound,    // lower bound of x[i]
    Array<double> &upperBound,    // upper bound of x[i]
    double &optimum,              // optimum value of objective function (if result is lpOptimal)
    Array<double> &x              // x-vector of optimal solution (if result is lpOptimal)
)
{
    if(osi->getNumCols()>0) { // get a fresh one if necessary
        delete osi;
        osi = CoinManager::createCorrectOsiSolverInterface();
    }

    const int numRows = rightHandSide.size();
    const int numCols = obj.size();
#ifdef OGDF_DEBUG
    const int numNonzeroes = matrixIndex.size();
#endif

    // assert correctness of array boundaries
    OGDF_ASSERT(obj          .low() == 0 && obj          .size() == numCols);
    OGDF_ASSERT(matrixBegin  .low() == 0 && matrixBegin  .size() == numCols);
    OGDF_ASSERT(matrixCount  .low() == 0 && matrixCount  .size() == numCols);
    OGDF_ASSERT(matrixIndex  .low() == 0 && matrixIndex  .size() == numNonzeroes);
    OGDF_ASSERT(matrixValue  .low() == 0 && matrixValue  .size() == numNonzeroes);
    OGDF_ASSERT(rightHandSide.low() == 0 && rightHandSide.size() == numRows);
    OGDF_ASSERT(equationSense.low() == 0 && equationSense.size() == numRows);
    OGDF_ASSERT(lowerBound   .low() == 0 && lowerBound   .size() == numCols);
    OGDF_ASSERT(upperBound   .low() == 0 && upperBound   .size() == numCols);
    OGDF_ASSERT(x            .low() == 0 && x            .size() == numCols);

    osi->setObjSense(goal==lpMinimize ? 1 : -1);

    int i;

    CoinPackedVector zero;
    for(i = 0; i < numRows; ++i) {
        osi->addRow(zero,equationSense[i],rightHandSide[i],0);
    }
    for(int colNo = 0; colNo < numCols; ++colNo) {
        CoinPackedVector cpv;
        for(i = matrixBegin[colNo]; i<matrixBegin[colNo]+matrixCount[colNo]; ++i) {
            cpv.insert(matrixIndex[i],matrixValue[i]);
        }
        osi->addCol(cpv,lowerBound[colNo],upperBound[colNo],obj[colNo]);
    }


    osi->initialSolve();

    Status status;
    if(osi->isProvenOptimal()) {
        optimum = osi->getObjValue();
        const double* sol = osi->getColSolution();
        for(i = numCols; i-->0;)
            x[i]=sol[i];
        status = lpOptimal;
        OGDF_ASSERT_IF(dlExtendedChecking,
                       checkFeasibility(matrixBegin,matrixCount,matrixIndex,matrixValue,
                                        rightHandSide,equationSense,lowerBound,upperBound,x));

    } else if(osi->isProvenPrimalInfeasible())
        status = lpInfeasible;
    else if(osi->isProvenDualInfeasible())
        status = lpUnbounded;
    else
        OGDF_THROW_PARAM(AlgorithmFailureException,afcNoSolutionFound);

    return status;
}
Пример #29
0
//===========================================================================//
int ATM_DecompApp::createConZtoX(DecompConstraintSet * model,
				 const int             atmIndex){

   //---
   //---  for a in A, t in T:
   //---     z[a,t] = x1[a,t] * x2[a] 
   //---         <==>
   //--- OLD:
   //---  for a in A:
   //---     sum{t in T}  x1[a,t] <= 1 (where, T = 1..n)
   //---  for a in A, t in T:
   //---     z[a,t] >= 0 <= 1,                  
   //---     z[a,t] <= x1[a,t],            
   //---     z[a,t] <= x2[a],              
   //---     z[a,t] >= x1[a,t] + x2[a] - 1.
   //--- NEW: 
   //---  for a in A:
   //---     sum{t in T}  x1[a,t] = 1 (where, T = 0..n)
   //---     sum{t in T}   z[a,t] = x2[a]
   //---  for a in A, t in T:
   //---     z[a,t] >= 0 <= 1,                  
   //---     z[a,t] <= x1[a,t].
   //---
   int       t;
   int       nRows = 0;
   const int nSteps = m_appParam.NumSteps;
   if(m_appParam.UseTightModel){
      for(t = 0; t <= nSteps; t++){
	 CoinPackedVector row;
	 string strAT = "(a_" + m_instance.getAtmName(atmIndex) 
	    + ",t_" + UtilIntToStr(t) + ")";
	 string rowName = "ztox1" + strAT;	 
	 row.insert(colIndex_z (atmIndex,t),  1.0);
	 row.insert(colIndex_x1(atmIndex,t), -1.0);
	 model->appendRow(row, -DecompInf, 0.0, rowName);
	 nRows++;
      }
      CoinPackedVector row2;
      string rowName2 = "ztox2(a_" 
	 + m_instance.getAtmName(atmIndex) + ")"; 
      row2.insert(colIndex_x2(atmIndex), -1.0);
      for(t = 0; t <= nSteps; t++){
	 row2.insert(colIndex_z (atmIndex,t),  1.0);
      }
      model->appendRow(row2, 0.0, 0.0, rowName2);	 
      nRows++;         
   }
   else{
      for(t = 0; t < nSteps; t++){
	 CoinPackedVector row1, row2, row3;
	 string strAT = "(a_" + m_instance.getAtmName(atmIndex) 
	    + ",t_" + UtilIntToStr(t+1) + ")";
	 string rowName1 = "ztox1" + strAT;
	 string rowName2 = "ztox2" + strAT;
	 string rowName3 = "ztox3" + strAT;
	 
	 row1.insert(colIndex_z (atmIndex,t),  1.0);
	 row1.insert(colIndex_x1(atmIndex,t), -1.0);
	 model->appendRow(row1, -DecompInf, 0.0, rowName1);
	 
	 row2.insert(colIndex_z (atmIndex,t),  1.0);
	 row2.insert(colIndex_x2(atmIndex)  , -1.0);
	 model->appendRow(row2, -DecompInf, 0.0, rowName2);
	 
	 row3.insert(colIndex_z (atmIndex,t),  1.0);
	 row3.insert(colIndex_x1(atmIndex,t), -1.0);
	 row3.insert(colIndex_x2(atmIndex)  , -1.0);
	 model->appendRow(row3, -1.0, DecompInf, rowName3);
	 
	 nRows+=3;         
      }
   }
   return nRows;
}
Пример #30
0
//===========================================================================//
void MCF_DecompApp::createModelRelax(DecompConstraintSet* model,
                                     int                   commId)
{
   //---
   //--- SUBPROBLEM (A'): (one block for each k in K)
   //---      sum{(j,i) in A} x[k,i,j] -
   //---         sum{(i,j) in A} x[k,i,j] = d[i,k], for all i in N
   //---      x[k,i,j] integer >= l[i,j] <= u[i,j], for all (i,j) in A
   //--- For k=(s,t) in K,
   //---    d[i,k] = -d[k] if i=s
   //---           =  d[k] if i=t
   //---           =  0, otherwise
   //---
   int         a, i, head, tail, colIndex, source, sink;
   int         numCommodities = m_instance.m_numCommodities;
   int         numArcs        = m_instance.m_numArcs;
   int         numNodes       = m_instance.m_numNodes;
   int         numCols        = numCommodities * numArcs;
   int         numRows        = numNodes;
   MCF_Instance::arc*        arcs        = m_instance.m_arcs;
   MCF_Instance::commodity* commodities = m_instance.m_commodities;
   UtilPrintFuncBegin(m_osLog, m_classTag,
                      "createModelRelax()", m_appParam.LogLevel, 2);
   //---
   //--- create space for the model matrix (row-majored)
   //---
   model->M = new CoinPackedMatrix(false, 0.0, 0.0);

   if (!model->M) {
      throw UtilExceptionMemory("createModelCore", "MCF_DecompApp");
   }

   model->M->setDimensions(0, numCols);
   model->reserve(numRows, numCols);
   //---
   //--- get this commodity's source and sink node
   //---
   source = commodities[commId].source;
   sink   = commodities[commId].sink;

   //---
   //--- create the rows
   //---   NOTE: this is somewhat inefficient (but simple)
   //---
   for (i = 0; i < numNodes; i++) {
      CoinPackedVector row;

      for (a = 0; a < numArcs; a++) {
         tail = arcs[a].tail;
         head = arcs[a].head;

         if (head == i) {
            colIndex = commId * numArcs + a;
            row.insert(colIndex, 1.0);
         } else if (tail == i) {
            colIndex = commId * numArcs + a;
            row.insert(colIndex, -1.0);
         }
      }

      if (i == source)
         model->appendRow(row,
                          -commodities[commId].demand,
                          -commodities[commId].demand);
      else if (i == sink)
         model->appendRow(row,
                          commodities[commId].demand,
                          commodities[commId].demand);
      else {
         model->appendRow(row, 0.0, 0.0);
      }

      string rowName = "flow(" +
                       UtilIntToStr(commId) + "_" +
                       UtilIntToStr(i)      + "_" +
                       UtilIntToStr(source) + "," +
                       UtilIntToStr(sink)   + ")";
      model->rowNames.push_back(rowName);
   }

   //---
   //--- create a list of the "active" columns (those related
   //---   to this commmodity) all other columns are fixed to 0
   //---
   UtilFillN(model->colLB, numCols,  0.0);
   UtilFillN(model->colUB, numCols,  0.0);
   colIndex = commId * numArcs;

   for (a = 0; a < numArcs; a++) {
      double           arcLB = arcs[a].lb;
      double           arcUB = arcs[a].ub;
      model->colLB[colIndex] = arcLB;
      model->colUB[colIndex] = arcUB;
      model->activeColumns.push_back(colIndex);
      colIndex++;
   }

   //---
   //--- set the indices of the integer variables of model
   //---
   UtilIotaN(model->integerVars, numCols, 0);
   UtilPrintFuncEnd(m_osLog, m_classTag,
                    "createModelRelax()", m_appParam.LogLevel, 2);
}