Changeset 2576 for trunk


Ignore:
Timestamp:
May 27, 2019 2:59:51 PM (4 months ago)
Author:
unxusr
Message:

buffering rows in Cbc_C_Interface to speedup repeated calls of Cbc_addRow

File:
1 edited

Legend:

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

    r2574 r2576  
    408408}
    409409
     410enum FlushContents
     411{
     412  FCColumns,
     413  FCRows,
     414  FCBoth
     415};
     416
    410417// flushes buffers of new variables
    411 static void Cbc_flush( Cbc_Model *model )
    412 {
    413   if (model->nCols)
     418static void Cbc_flush( Cbc_Model *model, enum FlushContents fc = FCBoth )
     419{
     420  OsiSolverInterface *solver = model->model_->solver();
     421
     422  if (fc == FCBoth || fc == FCColumns)
    414423  {
    415     OsiSolverInterface *solver = model->model_->solver();
    416 
    417     int *starts = new int[model->nCols+1];
    418     for ( int i=0 ; (i<model->nCols+1) ; ++i )
    419       starts[i] = 0;
    420 
    421     int idx = 0; double coef = 0.0;
    422 
    423     int colsBefore = solver->getNumCols();
    424    
    425     solver->addCols( model->nCols, starts, &idx, &coef, model->cLB, model->cUB, model->cObj );
    426 
    427     for ( int i=0 ; i<model->nCols; ++i )
    428       if (model->cInt[i])
    429         solver->setInteger( colsBefore+i );
    430 
    431     for ( int i=0 ; i<model->nCols; ++i )
    432       solver->setColName( colsBefore+i, std::string(model->cNames+model->cNameStart[i]) );
    433 
    434     model->nCols = 0;
    435 
    436     delete[] starts;
    437   }
    438 }
     424    if (model->nCols)
     425    {
     426      int *starts = new int[model->nCols+1];
     427      for ( int i=0 ; (i<model->nCols+1) ; ++i )
     428        starts[i] = 0;
     429
     430      int idx = 0; double coef = 0.0;
     431
     432      int colsBefore = solver->getNumCols();
     433     
     434      solver->addCols( model->nCols, starts, &idx, &coef, model->cLB, model->cUB, model->cObj );
     435
     436      for ( int i=0 ; i<model->nCols; ++i )
     437        if (model->cInt[i])
     438          solver->setInteger( colsBefore+i );
     439
     440      for ( int i=0 ; i<model->nCols; ++i )
     441        solver->setColName( colsBefore+i, std::string(model->cNames+model->cNameStart[i]) );
     442
     443      model->nCols = 0;
     444
     445      delete[] starts;
     446    }
     447  }
     448  if (fc == FCRows || fc == FCBoth)
     449  {
     450    if (model->nRows)
     451    {
     452      int rowsBefore = solver->getNumRows();
     453      solver->addRows(model->nRows, model->rStart, model->rIdx, model->rCoef, model->rLB, model->rUB);
     454
     455      for ( int i=0 ; i<model->nRows; ++i )
     456      {
     457        solver->setRowName( rowsBefore+i, std::string(model->rNames+model->rNameStart[i]) );
     458        if (model->rowNameIndex)
     459        {
     460          NameIndex &rowNameIndex = *((NameIndex  *)model->rowNameIndex);
     461          rowNameIndex[std::string(model->rNames+model->rNameStart[i])] = i+rowsBefore;
     462        }
     463      }
     464
     465      model->nRows = 0;
     466    }
     467  }
     468} // flush cols, rows or both
    439469
    440470static void Cbc_checkSpaceColBuffer( Cbc_Model *model, int additionlNameSpace )
     
    534564}
    535565
     566static void Cbc_checkSpaceRowBuffer(Cbc_Model *model, int nzRow, int rowNameLen)
     567{
     568  if (model->rowSpace == 0)
     569  {
     570    // allocating buffer
     571    model->rowSpace = 8192;
     572    model->rStart = (int *)malloc(sizeof(int)*model->rowSpace);
     573    model->rStart[0] = 0;
     574    model->rLB = (double *)malloc(sizeof(double)*model->rowSpace);
     575    model->rUB = (double *)malloc(sizeof(double)*model->rowSpace);
     576    model->rNameStart = (int *)malloc(sizeof(int)*model->rowSpace);
     577    model->rNameStart[0] = 0;
     578
     579    model->rElementsSpace = std::max(131072, nzRow * 2);
     580    model->rIdx = (int *)malloc(sizeof(int)*model->rElementsSpace);
     581    model->rCoef = (double *)malloc(sizeof(double)*model->rElementsSpace);
     582
     583    model->rNameSpace = 131072;
     584    model->rNames = (char *)malloc(sizeof(char)*model->rNameSpace);
     585  }
     586  else
     587  {
     588    // checking if some resize is needed
     589    if (model->nRows+2 >= model->rowSpace)
     590    {
     591      // checking row space
     592      if (model->rowSpace < 1048576)
     593      {
     594        model->rowSpace *= 2;
     595        model->rStart = (int *)realloc(model->rStart, sizeof(int)*model->rowSpace);
     596        model->rLB = (double *)realloc(model->rLB, sizeof(double)*model->rowSpace);
     597        model->rUB = (double *)realloc(model->rUB, sizeof(double)*model->rowSpace);
     598        model->rNameStart = (int *)realloc(model->rNameStart, sizeof(int)*model->rowSpace);
     599      }
     600      else
     601      {
     602        Cbc_flush(model, FCRows);
     603      }
     604    } // rowSpace
     605
     606    if (model->rStart[model->nRows]+nzRow+1 >= model->rElementsSpace)
     607    {
     608      if (model->rElementsSpace<4194304 || nzRow>=4194304)
     609      {
     610        model->rElementsSpace *= 2;
     611        model->rElementsSpace = std::max(model->rElementsSpace, nzRow*2);
     612        model->rIdx = (int *)realloc(model->rIdx, sizeof(int)*model->rElementsSpace);
     613        model->rCoef = (double *)realloc(model->rCoef, sizeof(double)*model->rElementsSpace);
     614      }
     615      else
     616      {
     617        Cbc_flush(model, FCRows);
     618      }
     619    } // elements space
     620 
     621    if (model->rNameStart[model->nRows]+rowNameLen+2 >= model->rNameSpace)
     622    {
     623      if (model->rowSpace < 8388608)
     624      {
     625        model->rowSpace *= 2;
     626        model->rNames = (char *)realloc(model->rNames, sizeof(char)*model->rNameSpace);
     627      }
     628      else
     629      {
     630        Cbc_flush(model, FCRows);
     631      }
     632    } // row names resize
     633  } // resizing
     634} // Cbc_checkSpaceRowBuffer
     635
     636static void Cbc_addRowBuffer(
     637    Cbc_Model *model,
     638    int nz,
     639    const int *rIdx,
     640    const double *rCoef,
     641    double rLB,
     642    double rUB,
     643    const char *rName)
     644{
     645  int nameLen = strlen(rName);
     646  Cbc_checkSpaceRowBuffer(model, nz, nameLen);
     647
     648  model->rLB[model->nRows] = rLB;
     649  model->rUB[model->nRows] = rUB;
     650  memcpy(model->rIdx + model->rStart[model->nRows], rIdx, sizeof(int)*nz);
     651  memcpy(model->rCoef + model->rStart[model->nRows], rCoef, sizeof(double)*nz);
     652
     653  char *spcName = model->rNames + model->rNameStart[model->nRows];
     654  strcpy(spcName, rName);
     655
     656  model->nRows++;
     657  model->rStart[model->nRows] = model->rStart[model->nRows-1] + nz;
     658  model->rNameStart[model->nRows] = model->rNameStart[model->nRows-1] + nameLen + 1;
     659}
     660
     661static void Cbc_deleteRowBuffer(Cbc_Model *model)
     662{
     663  if (model->nRows)
     664  {
     665    free(model->rStart);
     666    free(model->rLB);
     667    free(model->rUB);
     668    free(model->rNameStart);
     669    free(model->rIdx);
     670    free(model->rCoef);
     671    free(model->rNames);
     672  }
     673}
    536674
    537675/* Default Cbc_Model constructor */
     
    568706  model->cObj = NULL;
    569707
     708  // initialize rows buffer
     709  model->rowSpace = 0;
     710  model->nRows = 0;
     711  model->rNameSpace = 0;
     712  model->rNameStart = 0;
     713  model->rNames = NULL;
     714  model->rLB = NULL;
     715  model->rUB = NULL;
     716  model->rElementsSpace = 0;
     717  model->rStart = NULL;
     718  model->rIdx = NULL;
     719  model->rCoef = NULL;
     720
    570721  if (VERBOSE > 0)
    571722    printf("%s return\n", prefix);
     
    583734
    584735  Cbc_deleteColBuffer(model);
     736  Cbc_deleteRowBuffer(model);
    585737
    586738  if (model->colNameIndex)
     
    841993  Cbc_getNumElements(Cbc_Model *model)
    842994{
     995  Cbc_flush(model);
     996
    843997  const char prefix[] = "Cbc_C_Interface::Cbc_getNumElements(): ";
    844998  //  const int  VERBOSE = 1;
     
    8571011Cbc_getNumIntegers(Cbc_Model *model)
    8581012{
    859   Cbc_flush(model);
     1013  Cbc_flush(model, FCColumns);
    8601014  return model->model_->solver()->getNumIntegers();
    8611015}
     
    8651019Cbc_getVectorStarts(Cbc_Model *model)
    8661020{
     1021  Cbc_flush(model);
    8671022  const CoinPackedMatrix *matrix = NULL;
    8681023  matrix = model->model_->solver()->getMatrixByCol();
     
    8731028Cbc_getIndices(Cbc_Model *model)
    8741029{
     1030  Cbc_flush(model, FCRows);
    8751031  const char prefix[] = "Cbc_C_Interface::Cbc_getIndices(): ";
    8761032  //  const int  VERBOSE = 1;
     
    8921048Cbc_getElements(Cbc_Model *model)
    8931049{
     1050  Cbc_flush(model, FCRows);
    8941051  const char prefix[] = "Cbc_C_Interface::Cbc_getElements(): ";
    8951052  //  const int  VERBOSE = 1;
     
    9431100    printf("%s return\n", prefix);
    9441101}
     1102
    9451103/* length of names (0 means no names0 */
    9461104COINLIBAPI size_t COINLINKAGE
     
    9601118  return result;
    9611119}
     1120
    9621121COINLIBAPI void COINLINKAGE
    9631122Cbc_getRowName(Cbc_Model *model, int iRow, char *name, size_t maxLength)
    9641123{
     1124  Cbc_flush(model, FCRows);
    9651125  std::string rowname = model->model_->solver()->getRowName(iRow);
    9661126  strncpy(name, rowname.c_str(), maxLength);
     
    9741134  assert( iColumn < Cbc_getNumCols(model) );
    9751135
    976   Cbc_flush(model);
     1136  Cbc_flush(model, FCColumns);
    9771137
    9781138  std::string colname = model->model_->solver()->getColName(iColumn);
     
    10011161Cbc_setRowName(Cbc_Model *model, int iRow, const char *name)
    10021162{
     1163  Cbc_flush(model, FCRows);
    10031164  OsiSolverInterface *solver = model->model_->solver();
    10041165  std::string previousName = solver->getRowName(iRow);
     
    11171278  return result;
    11181279}
     1280
    11191281/* Number of primal infeasibilities */
    11201282COINLIBAPI int COINLINKAGE
     
    11641326}
    11651327
    1166 CbcGetProperty(int, getNumRows)
     1328COINLIBAPI int COINLINKAGE
     1329Cbc_getNumRows(Cbc_Model *model)
     1330{
     1331  return model->model_->solver()->getNumRows() + model->nRows;
     1332}
     1333
     1334
    11671335CbcGetProperty(int, getIterationCount)
    11681336
    1169   /** Number of non-zero entries in a row */
    1170   COINLIBAPI int COINLINKAGE
    1171   Cbc_getRowNz(Cbc_Model *model, int row)
    1172 {
     1337/** Number of non-zero entries in a row */
     1338COINLIBAPI int COINLINKAGE
     1339Cbc_getRowNz(Cbc_Model *model, int row)
     1340{
     1341  Cbc_flush(model, FCRows);
    11731342  const CoinPackedMatrix *cpmRow = model->model_->solver()->getMatrixByRow();
    11741343  return cpmRow->getVectorLengths()[row];
     
    11791348Cbc_getRowIndices(Cbc_Model *model, int row)
    11801349{
     1350  Cbc_flush(model, FCRows);
    11811351  const CoinPackedMatrix *cpmRow = model->model_->solver()->getMatrixByRow();
    11821352  const CoinBigIndex *starts = cpmRow->getVectorStarts();
     
    11891359Cbc_getRowCoeffs(Cbc_Model *model, int row)
    11901360{
     1361  Cbc_flush(model, FCRows);
    11911362  const CoinPackedMatrix *cpmRow = model->model_->solver()->getMatrixByRow();
    11921363  const CoinBigIndex *starts = cpmRow->getVectorStarts();
     
    11991370Cbc_getColNz(Cbc_Model *model, int col)
    12001371{
     1372  Cbc_flush(model);
    12011373  const CoinPackedMatrix *cpmCol = model->model_->solver()->getMatrixByCol();
    12021374  return cpmCol->getVectorLengths()[col];
     
    12071379Cbc_getColIndices(Cbc_Model *model, int col)
    12081380{
     1381  Cbc_flush(model);
    12091382  const CoinPackedMatrix *cpmCol = model->model_->solver()->getMatrixByCol();
    12101383  const CoinBigIndex *starts = cpmCol->getVectorStarts();
     
    12171390Cbc_getColCoeffs(Cbc_Model *model, int col)
    12181391{
     1392  Cbc_flush(model);
    12191393  const CoinPackedMatrix *cpmCol = model->model_->solver()->getMatrixByCol();
    12201394  const CoinBigIndex *starts = cpmCol->getVectorStarts();
     
    12271401Cbc_getRowRHS(Cbc_Model *model, int row)
    12281402{
     1403  Cbc_flush(model, FCRows);
    12291404  return model->model_->solver()->getRightHandSide()[row];
    12301405}
     
    12341409Cbc_getRowSense(Cbc_Model *model, int row)
    12351410{
     1411  Cbc_flush(model, FCRows);
    12361412  return model->model_->solver()->getRowSense()[row];
    12371413}
     
    13121488
    13131489CbcGetProperty(int, isContinuousUnbounded)
    1314   CbcGetProperty(int, isNodeLimitReached)
    1315     CbcGetProperty(int, isSecondsLimitReached)
    1316       CbcGetProperty(int, isSolutionLimitReached)
    1317         CbcGetProperty(int, isInitialSolveAbandoned)
    1318           CbcGetProperty(int, isInitialSolveProvenOptimal)
    1319             CbcGetProperty(int, isInitialSolveProvenPrimalInfeasible)
    1320 
    1321               CbcGetProperty(double, getObjSense)
    1322 
    1323                 COINLIBAPI void COINLINKAGE
    1324   Cbc_setObjSense(Cbc_Model *model, double sense)
     1490CbcGetProperty(int, isNodeLimitReached)
     1491CbcGetProperty(int, isSecondsLimitReached)
     1492CbcGetProperty(int, isSolutionLimitReached)
     1493CbcGetProperty(int, isInitialSolveAbandoned)
     1494CbcGetProperty(int, isInitialSolveProvenOptimal)
     1495CbcGetProperty(int, isInitialSolveProvenPrimalInfeasible)
     1496
     1497CbcGetProperty(double, getObjSense)
     1498
     1499COINLIBAPI void COINLINKAGE
     1500Cbc_setObjSense(Cbc_Model *model, double sense)
    13251501{
    13261502  Cbc_flush(model);
     
    13381514Cbc_getColLower(Cbc_Model *model)
    13391515{
    1340   Cbc_flush(model);
     1516  Cbc_flush(model, FCColumns);
    13411517  return model->model_->solver()->getColLower();
    13421518}
     
    13451521Cbc_getColUpper(Cbc_Model *model)
    13461522{
    1347   Cbc_flush(model);
     1523  Cbc_flush(model, FCColumns);
    13481524  return model->model_->solver()->getColUpper();
    13491525}
     
    13681544Cbc_setColLower(Cbc_Model *model, int index, double value)
    13691545{
    1370   Cbc_flush(model);
     1546  Cbc_flush(model, FCColumns);
    13711547  model->model_->solver()->setColLower( index, value );
    13721548}
     
    13751551Cbc_setColUpper(Cbc_Model *model, int index, double value)
    13761552{
    1377   Cbc_flush(model);
     1553  Cbc_flush(model, FCColumns);
    13781554  model->model_->solver()->setColUpper( index, value );
    13791555}
     
    13901566Cbc_printModel(Cbc_Model *model, const char *argPrefix)
    13911567{
     1568  Cbc_flush(model);
    13921569  const char prefix[] = "Cbc_C_Interface::Cbc_printModel(): ";
    13931570  const int VERBOSE = 4;
     
    14521629    printf("%s begin\n", prefix);
    14531630
    1454   Cbc_flush(model);
     1631  Cbc_flush(model, FCColumns);
    14551632
    14561633  bool result = false;
     
    14961673  result->cObj = NULL;
    14971674
     1675  model->rowSpace = 0;
     1676  model->nRows = 0;
     1677  model->rNameSpace = 0;
     1678  model->rNameStart = 0;
     1679  model->rNames = NULL;
     1680  model->rLB = NULL;
     1681  model->rUB = NULL;
     1682  model->rElementsSpace = 0;
     1683  model->rStart = NULL;
     1684  model->rIdx = NULL;
     1685  model->rCoef = NULL;
     1686
    14981687  if (VERBOSE > 0)
    14991688    printf("%s return\n", prefix);
     
    15091698    printf("%s begin\n", prefix);
    15101699
    1511   Cbc_flush(model);
     1700  Cbc_flush(model, FCColumns);
    15121701
    15131702  model->model_->solver()->setContinuous(iColumn);
     
    15161705    printf("%s return\n", prefix);
    15171706}
     1707
    15181708/** Set this the variable to be integer */
    15191709COINLIBAPI void COINLINKAGE
     
    15251715    printf("%s begin\n", prefix);
    15261716
    1527   Cbc_flush(model);
     1717  Cbc_flush(model, FCColumns);
    15281718
    15291719  model->model_->solver()->setInteger(iColumn);
     
    15641754  const int *cols, const double *coefs, char sense, double rhs)
    15651755{
    1566   Cbc_flush(model);
     1756  Cbc_flush(model, FCColumns);
    15671757  OsiSolverInterface *solver = model->model_->solver();
    15681758  double rowLB = -DBL_MAX, rowUB = DBL_MAX;
     
    15901780    abort();
    15911781  }
    1592   solver->addRow(nz, cols, coefs, rowLB, rowUB);
    1593   solver->setRowName(solver->getNumRows() - 1, std::string(name));
    1594 
    1595   if (model->rowNameIndex)
    1596   {
    1597     NameIndex &rowNameIndex = *((NameIndex  *)model->rowNameIndex);
    1598     rowNameIndex[std::string(name)] = Cbc_getNumRows(model)-1;
    1599   }
     1782
     1783  Cbc_addRowBuffer(model, nz, cols, coefs, rowLB, rowUB, name);
    16001784}
    16011785
     
    16031787Cbc_deleteRows(Cbc_Model *model, int numRows, const int rows[])
    16041788{
    1605   Cbc_flush(model);
     1789  Cbc_flush(model, FCRows);
    16061790  OsiSolverInterface *solver = model->model_->solver();
    16071791
     
    16191803Cbc_deleteCols(Cbc_Model *model, int numCols, const int cols[])
    16201804{
    1621   Cbc_flush(model);
     1805  Cbc_flush(model, FCColumns);
    16221806  OsiSolverInterface *solver = model->model_->solver();
    16231807
Note: See TracChangeset for help on using the changeset viewer.