Changeset 2471


Ignore:
Timestamp:
Jan 10, 2019 2:33:56 PM (5 weeks ago)
Author:
unxusr
Message:

speeding up repeated calls to Cbc_addCol in the C interface by including a temporary buffer

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Cbc/src/Cbc_C_Interface.cpp

    r2467 r2471  
    226226}
    227227
     228// flushes buffers of new variables
     229static void Cbc_flush( Cbc_Model *model )
     230{
     231  if (model->nCols)
     232  {
     233    OsiSolverInterface *solver = model->model_->solver();
     234
     235    int *starts = new int[model->nCols+1];
     236    for ( int i=0 ; (i<model->nCols+1) ; ++i )
     237      starts[i] = 0;
     238
     239    int idx = 0; double coef = 0.0;
     240
     241    int colsBefore = solver->getNumCols();
     242   
     243    solver->addCols( model->nCols, starts, &idx, &coef, model->cLB, model->cUB, model->cObj );
     244
     245    for ( int i=0 ; i<model->nCols; ++i )
     246      if (model->cInt[i])
     247        solver->setInteger( colsBefore+i );
     248
     249    for ( int i=0 ; i<model->nCols; ++i )
     250      solver->setColName( colsBefore+i, std::string(model->cNames+model->cNameStart[i]) );
     251
     252    model->nCols = 0;
     253
     254    delete[] starts;
     255  }
     256}
     257
     258static void Cbc_checkSpaceColBuffer( Cbc_Model *model, int additionlNameSpace )
     259{
     260  // initialize buffer
     261  if ( model->colSpace == 0 )
     262  {
     263    // initial buffer allocation
     264    model->colSpace = 8192;
     265    int c = model->colSpace;
     266    model->nCols = 0;
     267    model->cNameSpace = 16384;
     268
     269    model->cNameStart = (int *) malloc( sizeof(int)*c );
     270    assert( model->cNameStart );
     271    model->cNameStart[0] = 0;
     272
     273    model->cInt = (char *) malloc( sizeof(char)*c );
     274    assert( model->cInt );
     275
     276    model->cNames = (char *) malloc( sizeof(char)*model->cNameSpace );
     277    assert( model->cNames );
     278
     279    model->cLB = (double *) malloc( sizeof(double)*c );
     280    assert( model->cLB );
     281
     282    model->cUB = (double *)malloc( sizeof(double)*c );
     283    assert( model->cUB );
     284
     285    model->cObj = (double *)malloc( sizeof(double)*c );
     286    assert( model->cObj );
     287  }
     288  else
     289  {
     290    // check buffer space
     291    if (model->nCols+2 >= model->colSpace)
     292    {
     293      model->colSpace *= 2;
     294      int c = model->colSpace;
     295
     296      model->cNameStart = (int *) realloc( model->cNameStart, sizeof(int)*c );
     297      assert( model->cNameStart );
     298
     299      model->cInt = (char *) realloc( model->cInt, sizeof(char)*c );
     300      assert( model->cInt );
     301
     302      model->cLB = (double *) realloc( model->cLB, sizeof(double)*c );
     303      assert( model->cLB );
     304
     305      model->cUB = (double *) realloc( model->cUB, sizeof(double)*c );
     306      assert( model->cUB );
     307
     308      model->cObj = (double *) realloc( model->cObj, sizeof(double)*c );
     309      assert( model->cObj );
     310    }
     311    // check string buffer space
     312    int slen = additionlNameSpace + 1;
     313    int reqsize = slen + model->cNameStart[model->nCols]+1;
     314    if (reqsize>model->cNameSpace)
     315    {
     316      model->cNameSpace *= 2;
     317      model->cNames = (char *) realloc( model->cNames, sizeof(char)*model->cNameSpace );
     318    }
     319  }
     320}
     321
     322static void Cbc_addColBuffer( Cbc_Model *model,
     323    const char *name, double lb, double ub, double obj,
     324    char isInteger )
     325{
     326  Cbc_checkSpaceColBuffer( model, 512 );
     327  int p = model->nCols;
     328  model->cInt[p] = isInteger;
     329  model->cLB[p] = lb;
     330  model->cUB[p] = ub;
     331  model->cObj[p] = obj;
     332 
     333  int ps = model->cNameStart[p];
     334  strcpy( model->cNames+ps, name );
     335  int len = strlen(name);
     336
     337  model->nCols++;
     338  model->cNameStart[model->nCols] = ps + len + 1;
     339}
     340
     341static void Cbc_deleteColBuffer( Cbc_Model *model )
     342{
     343  if ( model->colSpace > 0 )
     344  {
     345    free(model->cNameStart);
     346    free(model->cInt);
     347    free(model->cNames);
     348    free(model->cLB);
     349    free(model->cUB);
     350    free(model->cObj);
     351  }
     352}
     353
     354
    228355/* Default Cbc_Model constructor */
    229356COINLIBAPI Cbc_Model *COINLINKAGE
     
    243370  model->relax_ = 0;
    244371
     372  // initialize columns buffer
     373  model->colSpace = 0;
     374  model->nCols = 0;
     375  model->cNameSpace = 0;
     376  model->cNameStart = NULL;
     377  model->cInt = NULL;
     378  model->cNames= NULL;
     379  model->cLB = NULL;
     380  model->cUB = NULL;
     381  model->cObj = NULL;
     382
    245383  if (VERBOSE > 0)
    246384    printf("%s return\n", prefix);
     
    256394    printf("%s begin\n", prefix);
    257395  fflush(stdout);
     396
     397  Cbc_deleteColBuffer(model);
    258398
    259399  if (VERBOSE > 1)
     
    355495Cbc_writeMps(Cbc_Model *model, const char *filename)
    356496{
     497  Cbc_flush(model);
     498
    357499  const char prefix[] = "Cbc_C_Interface::Cbc_writeMps(): ";
    358500  //  const int  VERBOSE = 2;
     
    373515Cbc_writeLp(Cbc_Model *model, const char *filename)
    374516{
     517  Cbc_flush(model);
     518
    375519  const char prefix[] = "Cbc_C_Interface::Cbc_writeLp(): ";
    376520  //  const int  VERBOSE = 2;
     
    418562Cbc_setInitialSolution(Cbc_Model *model, const double *sol)
    419563{
     564  Cbc_flush(model);
    420565  int n = Cbc_getNumCols(model);
    421566  // We need to manually compute the objective here for some reason
     
    477622Cbc_getNumIntegers(Cbc_Model *model)
    478623{
     624  Cbc_flush(model);
    479625  return model->model_->solver()->getNumIntegers();
    480626}
     
    586732  name[maxLength - 1] = '\0';
    587733}
    588 COINLIBAPI void COINLINKAGE
    589 Cbc_getColName(Cbc_Model *model, int iRow, char *name, size_t maxLength)
    590 {
    591   std::string colname = model->model_->solver()->getColName(iRow);
     734
     735COINLIBAPI void COINLINKAGE
     736Cbc_getColName(Cbc_Model *model, int iColumn, char *name, size_t maxLength)
     737{
     738  assert( iColumn >= 0 );
     739  assert( iColumn < Cbc_getNumCols(model) );
     740
     741  Cbc_flush(model);
     742
     743  std::string colname = model->model_->solver()->getColName(iColumn);
    592744  strncpy(name, colname.c_str(), maxLength);
    593745  name[maxLength - 1] = '\0';
     
    597749Cbc_setColName(Cbc_Model *model, int iColumn, const char *name)
    598750{
     751  Cbc_flush(model);
    599752  model->model_->solver()->setColName(iColumn, name);
    600753}
     
    615768Cbc_solve(Cbc_Model *model)
    616769{
     770  Cbc_flush( model );
     771
    617772  OsiSolverInterface *solver = model->solver_;
    618773  if (solver->getNumIntegers() == 0 || model->relax_ == 1) {
     
    710865}
    711866
    712 CbcGetProperty(int, getNumCols)
    713   CbcGetProperty(int, getNumRows)
    714     CbcGetProperty(int, getIterationCount)
     867COINLIBAPI int COINLINKAGE
     868Cbc_getNumCols(Cbc_Model *model)
     869{
     870  return model->model_->solver()->getNumCols() + model->nCols;
     871}
     872
     873CbcGetProperty(int, getNumRows)
     874CbcGetProperty(int, getIterationCount)
    715875
    716876  /** Number of non-zero entries in a row */
     
    8711031  Cbc_setObjSense(Cbc_Model *model, double sense)
    8721032{
     1033  Cbc_flush(model);
    8731034  model->model_->setObjSense(sense);
    8741035}
     
    8761037CbcGetProperty(const double *, getRowActivity)
    8771038
    878   CbcGetProperty(const double *, getRowLower)
    879     CbcSetSolverProperty(double, setRowLower)
    880       CbcGetProperty(const double *, getRowUpper)
    881         CbcSetSolverProperty(double, setRowUpper)
    882           CbcGetProperty(const double *, getObjCoefficients)
    883             CbcSetSolverProperty(double, setObjCoeff)
    884               CbcGetProperty(const double *, getColLower)
    885                 CbcSetSolverProperty(double, setColLower)
    886                   CbcGetProperty(const double *, getColUpper)
    887                     CbcSetSolverProperty(double, setColUpper)
    888 
    889                       CbcGetProperty(double, getBestPossibleObjValue)
    890 
    891                         COINLIBAPI double *COINLINKAGE
    892   Cbc_bestSolution(Cbc_Model *model)
     1039CbcGetProperty(const double *, getRowLower)
     1040CbcSetSolverProperty(double, setRowLower)
     1041CbcGetProperty(const double *, getRowUpper)
     1042CbcSetSolverProperty(double, setRowUpper)
     1043
     1044COINLIBAPI const double *COINLINKAGE
     1045Cbc_getColLower(Cbc_Model *model)
     1046{
     1047  Cbc_flush(model);
     1048  return model->model_->solver()->getColLower();
     1049}
     1050
     1051COINLIBAPI const double *COINLINKAGE
     1052Cbc_getColUpper(Cbc_Model *model)
     1053{
     1054  Cbc_flush(model);
     1055  return model->model_->solver()->getColUpper();
     1056}
     1057
     1058CbcGetProperty(double, getBestPossibleObjValue)
     1059
     1060COINLIBAPI const double *COINLINKAGE
     1061Cbc_getObjCoefficients(Cbc_Model *model)
     1062{
     1063  Cbc_flush(model);
     1064  return model->model_->solver()->getObjCoefficients();
     1065}
     1066
     1067COINLIBAPI void COINLINKAGE
     1068Cbc_setObjCoeff(Cbc_Model *model, int index, double value)
     1069{
     1070  model->model_->solver()->setObjCoeff( index, value );
     1071}
     1072
     1073COINLIBAPI void COINLINKAGE
     1074Cbc_setColLower(Cbc_Model *model, int index, double value)
     1075{
     1076  Cbc_flush(model);
     1077  model->model_->solver()->setColLower( index, value );
     1078}
     1079
     1080COINLIBAPI void COINLINKAGE
     1081Cbc_setColUpper(Cbc_Model *model, int index, double value)
     1082{
     1083  Cbc_flush(model);
     1084  model->model_->solver()->setColUpper( index, value );
     1085}
     1086
     1087
     1088COINLIBAPI double *COINLINKAGE
     1089Cbc_bestSolution(Cbc_Model *model)
    8931090{
    8941091  return model->model_->bestSolution();
     
    9611158    printf("%s begin\n", prefix);
    9621159
     1160  Cbc_flush(model);
     1161
    9631162  bool result = false;
    9641163  result = model->model_->isInteger(i);
     
    9711170CbcGetProperty(int, getNodeCount)
    9721171
    973   /** Return a copy of this model */
    974   COINLIBAPI Cbc_Model *COINLINKAGE
    975   Cbc_clone(Cbc_Model *model)
    976 {
     1172/** Return a copy of this model */
     1173COINLIBAPI Cbc_Model *COINLINKAGE
     1174Cbc_clone(Cbc_Model *model)
     1175{
     1176
    9771177  const char prefix[] = "Cbc_C_Interface::Cbc_clone(): ";
    9781178  //  const int  VERBOSE = 1;
     
    9801180    printf("%s begin\n", prefix);
    9811181
     1182  Cbc_flush(model);
    9821183  Cbc_Model *result = new Cbc_Model();
    9831184  result->model_ = new CbcModel(*(model->model_));
     
    10001201    printf("%s begin\n", prefix);
    10011202
     1203  Cbc_flush(model);
     1204
    10021205  model->model_->solver()->setContinuous(iColumn);
    10031206
     
    10131216  if (VERBOSE > 0)
    10141217    printf("%s begin\n", prefix);
     1218
     1219  Cbc_flush(model);
    10151220
    10161221  model->model_->solver()->setInteger(iColumn);
     
    10281233  OsiSolverInterface *solver = model->model_->solver();
    10291234
    1030   solver->addCol(nz, rows, coefs, lb, ub, obj, std::string(name));
    1031   if (isInteger)
    1032     solver->setInteger(solver->getNumCols() - 1);
     1235  if ( nz==0 )
     1236  {
     1237    Cbc_addColBuffer( model, name, lb, ub, obj, isInteger );
     1238  }
     1239  else
     1240  {
     1241    solver->addCol(nz, rows, coefs, lb, ub, obj, std::string(name));
     1242    if (isInteger)
     1243      solver->setInteger(solver->getNumCols() - 1);
     1244  }
    10331245}
    10341246
     
    10381250  const int *cols, const double *coefs, char sense, double rhs)
    10391251{
     1252  Cbc_flush(model);
    10401253  OsiSolverInterface *solver = model->model_->solver();
    10411254  double rowLB = -DBL_MAX, rowUB = DBL_MAX;
     
    10731286  const int *colIndices, const double *weights, const int type)
    10741287{
     1288  Cbc_flush(model);
    10751289  const char prefix[] = "Cbc_C_Interface::Cbc_addSOS(): ";
    10761290  //const int  VERBOSE = 4;
     
    11621376Cbc_setMIPStart(Cbc_Model *model, int count, const char **colNames, const double colValues[])
    11631377{
     1378  Cbc_flush(model);
    11641379  model->model_->setMIPStart(count, colNames, colValues);
    11651380}
     
    11681383Cbc_setMIPStartI(Cbc_Model *model, int count, const int colIdxs[], const double colValues[])
    11691384{
     1385  Cbc_flush(model);
    11701386  CbcModel *cbcModel = model->model_;
    11711387  OsiSolverInterface *solver = cbcModel->solver();
Note: See TracChangeset for help on using the changeset viewer.