bool MOSEK_SolveWrapper::setup(const LP_Constraints_Sparse & cstraints) //cstraints <-> constraints
{
  assert(nbParams_ == cstraints.nbParams_);

  MSK_deletetask(&task);

  int NUMVAR = this->nbParams_;
  int NUMCON = cstraints.constraint_mat_.rows();
  int NUMANZ = cstraints.constraint_mat_.nonZeros();

  MSKrescodee r = MSK_RES_OK;
  if ( r==MSK_RES_OK )
  {
    // Directs the log task stream to the 'printstr' function.
    if ( r==MSK_RES_OK )
      MSK_linkfunctotaskstream(task,MSK_STREAM_LOG,NULL,printstr);

    // Create the optimization task.
    r = MSK_maketask(env,NUMCON,NUMVAR,&task);

    // Give MOSEK an estimate of the size of the input data.
    //This is done to increase the speed of inputting data.
    // However, it is optional.
    if (r == MSK_RES_OK)
      r = MSK_putmaxnumvar(task,NUMVAR);

    if (r == MSK_RES_OK)
      r = MSK_putmaxnumcon(task,NUMCON);

    if (r == MSK_RES_OK)
      r = MSK_putmaxnumanz(task,NUMANZ);

    // Append 'NUMCON' empty constraints. The constraints will initially have no bounds.
    if ( r == MSK_RES_OK )
      r = MSK_append(task,MSK_ACC_CON,NUMCON);

    // Append 'NUMVAR' variables. The variables will initially be fixed at zero (x=0).
    if ( r == MSK_RES_OK )
      r = MSK_append(task,MSK_ACC_VAR,NUMVAR);
  }

  this->nbParams_ = NUMVAR;

  if (cstraints.bminimize_) {
    r = MSK_putobjsense(task, MSK_OBJECTIVE_SENSE_MINIMIZE);
  }
  else  {
    r = MSK_putobjsense(task, MSK_OBJECTIVE_SENSE_MAXIMIZE);
  }

  // Optionally add a constant term to the objective.
  if ( r ==MSK_RES_OK )
    r = MSK_putcfix(task,0.0);

  // Add the objective function if any
  if (!cstraints.vec_cost_.empty())  {
    // Set objective
    for (size_t i = 0; i < cstraints.vec_cost_.size(); ++i)
      r = MSK_putcj(task, i, cstraints.vec_cost_[i]);
  }

  //Add constraint row by row
  const sRMat & A = cstraints.constraint_mat_;
  std::vector<int> vec_colno;
  std::vector<double> vec_value;
  for (int i=0; i<A.rows(); ++i)
  {
    vec_colno.resize(0);
    vec_value.resize(0);
    for (sRMat::InnerIterator it(A,i); it; ++it)
    {
      vec_colno.push_back(it.col());
      vec_value.push_back(it.value());
    }
    // Insert a row
    r = MSK_putavec(task,
                    MSK_ACC_CON,      // Input row of A.
                    MSKidxt(i),       // Variable row index.
                    vec_colno.size(), // Number of non-zeros in row(i) A.
                    &vec_colno[0],    // Pointer to row indexes of row i.
                    &vec_value[0]);   // Pointer to Values of row i.
  }

  //Add bound on variables:
  if (cstraints.vec_bounds_.size() == 1) {

    for( size_t i = 0; i < NUMVAR; ++i) {
      if(r == MSK_RES_OK)
        r = MSK_putbound(task,
                         MSK_ACC_VAR,                         // Put bounds on variables.
                         MSKidxt(i),                          // Index of variable.
                         MSK_BK_RA, // Bound key.
                         cstraints.vec_bounds_[0].first,      // Numerical value of lower bound.
                         cstraints.vec_bounds_[0].second);    // Numerical value of upper bound.
    }
  }
  else{

    for( size_t i = 0; i < NUMVAR; ++i) {
    // Set the bounds on variable j.
    //    lower bound <= x_j <= upper bound

      if(r == MSK_RES_OK)
        r = MSK_putbound(task,
                         MSK_ACC_VAR,                         // Put bounds on variables.
                         MSKidxt(i),                          // Index of variable.
                         MSK_BK_RA, // Bound key.
                         cstraints.vec_bounds_[i].first,      // Numerical value of lower bound.
                         cstraints.vec_bounds_[i].second);    // Numerical value of upper bound.
    // in order to add sparse bounds use: MSK_putboundlist
    }
  }

  // Add bounds on constraint
  for(size_t i=0; i<NUMCON && r==MSK_RES_OK; ++i)
  {
    MSKboundkey_enum cst = convertSign(cstraints.vec_sign_[i]);
    if (cst == MSK_BK_UP || cst == MSK_BK_RA)
      r = MSK_putbound(task,
                     MSK_ACC_CON,   // Put bounds on constraints.
                     MSKidxt(i),    // Index of constraint.
                     cst,           // Bound key.
                     -MSK_INFINITY, // Numerical value of lower bound.
                     cstraints.constraint_objective_(i));      //upper bound.
    else if (cst == MSK_BK_LO)
      r = MSK_putbound(task,
                     MSK_ACC_CON,   // Put bounds on constraints.
                     MSKidxt(i),    // Index of constraint.
                     cst,           // Bound key.
                     cstraints.constraint_objective_(i),
                    +MSK_INFINITY);
    else if (cst == MSK_BK_FX)
      r = MSK_putbound(task,
                     MSK_ACC_CON,   // Put bounds on constraints.
                     MSKidxt(i),    // Index of constraint.
                     cst,           // Bound key.
                     cstraints.constraint_objective_(i),
                     cstraints.constraint_objective_(i));
  }

  return r == MSK_RES_OK;
}
예제 #2
0
bool OSI_X_SolverWrapper<SOLVERINTERFACE>::setup(const LP_Constraints_Sparse & cstraints) //cstraints <-> constraints
{
  bool bOk = true;
  if ( si == NULL )
  {
    return false;
  }
  assert(nbParams_ == cstraints.nbParams_);

  const 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 sRMat & 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 rowindex = 0;
  for (int i=0; i < A.rows(); ++i)
  {
    std::vector<int> vec_colno;
    std::vector<double> vec_value;
    for (sRMat::InnerIterator it(A,i); it; ++it)
    {
      vec_colno.push_back(it.col());
      vec_value.push_back(it.value());
    }


    if ( cstraints.vec_sign_[i] == LP_Constraints::LP_EQUAL || cstraints.vec_sign_[i] == LP_Constraints::LP_LESS_OR_EQUAL )
    {
      int coef = 1;
      row_lb[rowindex] = -1.0 * si->getInfinity();
      row_ub[rowindex] = coef * cstraints.constraint_objective_(i);
      matrix->appendRow( vec_colno.size(),
                   &vec_colno[0],
                   &vec_value[0] );
      rowindex++;
    }

    if ( cstraints.vec_sign_[i] == LP_Constraints::LP_EQUAL || cstraints.vec_sign_[i] == LP_Constraints::LP_GREATER_OR_EQUAL )
    {
      int coef = -1;
      for ( std::vector<double>::iterator iter_val = vec_value.begin();
        iter_val != vec_value.end();
        iter_val++)
      {
        *iter_val *= coef;
      }
      row_lb[rowindex] = -1.0 * si->getInfinity();
      row_ub[rowindex] = coef * cstraints.constraint_objective_(i);
      matrix->appendRow( vec_colno.size(),
                   &vec_colno[0],
                   &vec_value[0] );
      rowindex++;
    }
  }

  //-- 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;
}
예제 #3
0
bool OSI_X_SolverWrapper::setup(const LP_Constraints_Sparse & cstraints) //cstraints <-> constraints
{
  if ( si == nullptr )
  {
    return false;
  }
  assert(nbParams_ == cstraints.nbParams_);

  const 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 sRMat & 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 rowindex = 0;
  for (int i=0; i < A.rows(); ++i)
  {
    std::vector<int> vec_colno;
    std::vector<double> vec_value;
    for (sRMat::InnerIterator it(A,i); it; ++it)
    {
      vec_colno.push_back(it.col());
      vec_value.push_back(it.value());
    }

    if ( cstraints.vec_sign_[i] == LP_Constraints::LP_EQUAL ||
         cstraints.vec_sign_[i] == LP_Constraints::LP_LESS_OR_EQUAL )
    {
      const int coef = 1;
      row_ub[rowindex] = coef * cstraints.constraint_objective_(i);
      matrix->appendRow( vec_colno.size(),
                   &vec_colno[0],
                   &vec_value[0] );
      ++rowindex;
    }

    if ( cstraints.vec_sign_[i] == LP_Constraints::LP_EQUAL ||
         cstraints.vec_sign_[i] == LP_Constraints::LP_GREATER_OR_EQUAL )
    {
      const int coef = -1;
      for (auto &  iter_val : vec_value)
      {
        iter_val *= coef;
      }
      row_ub[rowindex] = coef * cstraints.constraint_objective_(i);
      matrix->appendRow( vec_colno.size(),
                   &vec_colno[0],
                   &vec_value[0] );
      ++rowindex;
    }
  }

  //-- 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;
}