예제 #1
0
파일: problem.cpp 프로젝트: h-g-s/npsep
void* problem_convert_to_osi(Problem *p)
{
    int i;
    double rowLb, rowUb;
    OsiSolverInterface *solver = new OsiClpSolverInterface();
    CoinBuild cb;

    solver->setIntParam(OsiNameDiscipline, 2);
    solver->messageHandler()->setLogLevel(0);
    solver->setHintParam(OsiDoReducePrint,true,OsiHintTry);

    for(i = 0; i < p->numCols; i++)
    {
        solver->addCol(0, NULL, NULL, p->colLb[i], p->colUb[i], p->objCoef[i]);
        solver->setColName(i, p->colName[i]);
        
        if(p->colType[i] == CONTINUOUS)
            solver->setContinuous(i);
        else 
            solver->setInteger(i);
    }

    for(i = 0; i < p->numRows; i++)
    {
        switch(p->rowSense[i])
        {
            case 'E':
                rowLb = p->rhs[i];
                rowUb = p->rhs[i];
            break;

            case 'L':
                rowLb = -p->infty;
                rowUb = p->rhs[i];
            break;

            case 'G':
                rowLb = p->rhs[i];
                rowUb = p->infty;
            break;

            default:
                fprintf(stderr, "Error: invalid type of constraint!\n");
                exit(EXIT_FAILURE);
        }

        cb.addRow(p->rowNElements[i], p->idxsByRow[i], p->coefsByRow[i], rowLb, rowUb);
    }

    solver->addRows(cb);
    
    for(i = 0; i < p->numRows; i++)
        solver->setRowName(i, p->rowName[i]);

    return solver;
}
예제 #2
0
파일: addRows.cpp 프로젝트: rafapaz/FlopCpp
int main(int argc, const char *argv[])
{
     try {
          // Empty model
          ClpSimplex  model;

          // Objective - just nonzeros
          int objIndex[] = {0, 2};
          double objValue[] = {1.0, 4.0};
          // Upper bounds - as dense vector
          double upper[] = {2.0, COIN_DBL_MAX, 4.0};

          // Create space for 3 columns
          model.resize(0, 3);
          // Fill in
          int i;
          // Virtuous way
          // First objective
          for (i = 0; i < 2; i++)
               model.setObjectiveCoefficient(objIndex[i], objValue[i]);
          // Now bounds (lower will be zero by default but do again)
          for (i = 0; i < 3; i++) {
               model.setColumnLower(i, 0.0);
               model.setColumnUpper(i, upper[i]);
          }
          /*
            We could also have done in non-virtuous way e.g.
            double * objective = model.objective();
            and then set directly
          */
          // Faster to add rows all at once - but this is easier to show
          // Now add row 1 as >= 2.0
          int row1Index[] = {0, 2};
          double row1Value[] = {1.0, 1.0};
          model.addRow(2, row1Index, row1Value,
                       2.0, COIN_DBL_MAX);
          // Now add row 2 as == 1.0
          int row2Index[] = {0, 1, 2};
          double row2Value[] = {1.0, -5.0, 1.0};
          model.addRow(3, row2Index, row2Value,
                       1.0, 1.0);
          // solve
          model.dual();

          /*
            Adding one row at a time has a significant overhead so let's
            try a more complicated but faster way

            First time adding in 10000 rows one by one
          */
          model.allSlackBasis();
          ClpSimplex modelSave = model;
          double time1 = CoinCpuTime();
          int k;
          for (k = 0; k < 10000; k++) {
               int row2Index[] = {0, 1, 2};
               double row2Value[] = {1.0, -5.0, 1.0};
               model.addRow(3, row2Index, row2Value,
                            1.0, 1.0);
          }
          printf("Time for 10000 addRow is %g\n", CoinCpuTime() - time1);
          model.dual();
          model = modelSave;
          // Now use build
          CoinBuild buildObject;
          time1 = CoinCpuTime();
          for (k = 0; k < 10000; k++) {
               int row2Index[] = {0, 1, 2};
               double row2Value[] = {1.0, -5.0, 1.0};
               buildObject.addRow(3, row2Index, row2Value,
                                  1.0, 1.0);
          }
          model.addRows(buildObject);
          printf("Time for 10000 addRow using CoinBuild is %g\n", CoinCpuTime() - time1);
          model.dual();
          model = modelSave;
          int del[] = {0, 1, 2};
          model.deleteRows(2, del);
          // Now use build +-1
          CoinBuild buildObject2;
          time1 = CoinCpuTime();
          for (k = 0; k < 10000; k++) {
               int row2Index[] = {0, 1, 2};
               double row2Value[] = {1.0, -1.0, 1.0};
               buildObject2.addRow(3, row2Index, row2Value,
                                   1.0, 1.0);
          }
          model.addRows(buildObject2, true);
          printf("Time for 10000 addRow using CoinBuild+-1 is %g\n", CoinCpuTime() - time1);
          model.dual();
          model = modelSave;
          model.deleteRows(2, del);
          // Now use build +-1
          CoinModel modelObject2;
          time1 = CoinCpuTime();
          for (k = 0; k < 10000; k++) {
               int row2Index[] = {0, 1, 2};
               double row2Value[] = {1.0, -1.0, 1.0};
               modelObject2.addRow(3, row2Index, row2Value,
                                   1.0, 1.0);
          }
          model.addRows(modelObject2, true);
          printf("Time for 10000 addRow using CoinModel+-1 is %g\n", CoinCpuTime() - time1);
          model.dual();
          model = ClpSimplex();
          // Now use build +-1
          CoinModel modelObject3;
          time1 = CoinCpuTime();
          for (k = 0; k < 10000; k++) {
               int row2Index[] = {0, 1, 2};
               double row2Value[] = {1.0, -1.0, 1.0};
               modelObject3.addRow(3, row2Index, row2Value,
                                   1.0, 1.0);
          }
          model.loadProblem(modelObject3, true);
          printf("Time for 10000 addRow using CoinModel load +-1 is %g\n", CoinCpuTime() - time1);
          model.writeMps("xx.mps");
          model.dual();
          model = modelSave;
          // Now use model
          CoinModel modelObject;
          time1 = CoinCpuTime();
          for (k = 0; k < 10000; k++) {
               int row2Index[] = {0, 1, 2};
               double row2Value[] = {1.0, -5.0, 1.0};
               modelObject.addRow(3, row2Index, row2Value,
                                  1.0, 1.0);
          }
          model.addRows(modelObject);
          printf("Time for 10000 addRow using CoinModel is %g\n", CoinCpuTime() - time1);
          model.dual();
          model.writeMps("b.mps");
          // Method using least memory - but most complicated
          time1 = CoinCpuTime();
          // Assumes we know exact size of model and matrix
          // Empty model
          ClpSimplex  model2;
          {
               // Create space for 3 columns and 10000 rows
               int numberRows = 10000;
               int numberColumns = 3;
               // This is fully dense - but would not normally be so
               int numberElements = numberRows * numberColumns;
               // Arrays will be set to default values
               model2.resize(numberRows, numberColumns);
               double * elements = new double [numberElements];
               CoinBigIndex * starts = new CoinBigIndex [numberColumns+1];
               int * rows = new int [numberElements];;
               int * lengths = new int[numberColumns];
               // Now fill in - totally unsafe but ....
               // no need as defaults to 0.0 double * columnLower = model2.columnLower();
               double * columnUpper = model2.columnUpper();
               double * objective = model2.objective();
               double * rowLower = model2.rowLower();
               double * rowUpper = model2.rowUpper();
               // Columns - objective was packed
               for (k = 0; k < 2; k++) {
                    int iColumn = objIndex[k];
                    objective[iColumn] = objValue[k];
               }
               for (k = 0; k < numberColumns; k++)
                    columnUpper[k] = upper[k];
               // Rows
               for (k = 0; k < numberRows; k++) {
                    rowLower[k] = 1.0;
                    rowUpper[k] = 1.0;
               }
               // Now elements
               double row2Value[] = {1.0, -5.0, 1.0};
               CoinBigIndex put = 0;
               for (k = 0; k < numberColumns; k++) {
                    starts[k] = put;
                    lengths[k] = numberRows;
                    double value = row2Value[k];
                    for (int i = 0; i < numberRows; i++) {
                         rows[put] = i;
                         elements[put] = value;
                         put++;
                    }
               }
               starts[numberColumns] = put;
               // assign to matrix
               CoinPackedMatrix * matrix = new CoinPackedMatrix(true, 0.0, 0.0);
               matrix->assignMatrix(true, numberRows, numberColumns, numberElements,
                                    elements, rows, starts, lengths);
               ClpPackedMatrix * clpMatrix = new ClpPackedMatrix(matrix);
               model2.replaceMatrix(clpMatrix, true);
               printf("Time for 10000 addRow using hand written code is %g\n", CoinCpuTime() - time1);
               // If matrix is really big could switch off creation of row copy
               // model2.setSpecialOptions(256);
          }
          model2.dual();
          model2.writeMps("a.mps");
          // Print column solution
          int numberColumns = model.numberColumns();

          // Alternatively getColSolution()
          double * columnPrimal = model.primalColumnSolution();
          // Alternatively getReducedCost()
          double * columnDual = model.dualColumnSolution();
          // Alternatively getColLower()
          double * columnLower = model.columnLower();
          // Alternatively getColUpper()
          double * columnUpper = model.columnUpper();
          // Alternatively getObjCoefficients()
          double * columnObjective = model.objective();

          int iColumn;

          std::cout << "               Primal          Dual         Lower         Upper          Cost"
                    << std::endl;

          for (iColumn = 0; iColumn < numberColumns; iColumn++) {
               double value;
               std::cout << std::setw(6) << iColumn << " ";
               value = columnPrimal[iColumn];
               if (fabs(value) < 1.0e5)
                    std::cout << setiosflags(std::ios::fixed | std::ios::showpoint) << std::setw(14) << value;
               else
                    std::cout << setiosflags(std::ios::scientific) << std::setw(14) << value;
               value = columnDual[iColumn];
               if (fabs(value) < 1.0e5)
                    std::cout << setiosflags(std::ios::fixed | std::ios::showpoint) << std::setw(14) << value;
               else
                    std::cout << setiosflags(std::ios::scientific) << std::setw(14) << value;
               value = columnLower[iColumn];
               if (fabs(value) < 1.0e5)
                    std::cout << setiosflags(std::ios::fixed | std::ios::showpoint) << std::setw(14) << value;
               else
                    std::cout << setiosflags(std::ios::scientific) << std::setw(14) << value;
               value = columnUpper[iColumn];
               if (fabs(value) < 1.0e5)
                    std::cout << setiosflags(std::ios::fixed | std::ios::showpoint) << std::setw(14) << value;
               else
                    std::cout << setiosflags(std::ios::scientific) << std::setw(14) << value;
               value = columnObjective[iColumn];
               if (fabs(value) < 1.0e5)
                    std::cout << setiosflags(std::ios::fixed | std::ios::showpoint) << std::setw(14) << value;
               else
                    std::cout << setiosflags(std::ios::scientific) << std::setw(14) << value;

               std::cout << std::endl;
          }
          std::cout << "--------------------------------------" << std::endl;
          // Test CoinAssert
          std::cout << "If Clp compiled with -g below should give assert, if with -O1 or COIN_ASSERT CoinError" << std::endl;
          model = modelSave;
          model.deleteRows(2, del);
          // Deliberate error
          model.deleteColumns(1, del + 2);
          // Now use build +-1
          CoinBuild buildObject3;
          time1 = CoinCpuTime();
          for (k = 0; k < 10000; k++) {
               int row2Index[] = {0, 1, 2};
               double row2Value[] = {1.0, -1.0, 1.0};
               buildObject3.addRow(3, row2Index, row2Value,
                                   1.0, 1.0);
          }
          model.addRows(buildObject3, true);
     } catch (CoinError e) {
          e.print();
          if (e.lineNumber() >= 0)
               std::cout << "This was from a CoinAssert" << std::endl;
     }
     return 0;
}
예제 #3
0
int main(int argc, const char *argv[])
{
     {
          // Empty model
          ClpSimplex  model;

          // Bounds on rows - as dense vector
          double lower[] = {2.0, 1.0};
          double upper[] = {COIN_DBL_MAX, 1.0};

          // Create space for 2 rows
          model.resize(2, 0);
          // Fill in
          int i;
          // Now row bounds
          for (i = 0; i < 2; i++) {
               model.setRowLower(i, lower[i]);
               model.setRowUpper(i, upper[i]);
          }
          // Now add column 1
          int column1Index[] = {0, 1};
          double column1Value[] = {1.0, 1.0};
          model.addColumn(2, column1Index, column1Value,
                          0.0, 2, 1.0);
          // Now add column 2
          int column2Index[] = {1};
          double column2Value[] = { -5.0};
          model.addColumn(1, column2Index, column2Value,
                          0.0, COIN_DBL_MAX, 0.0);
          // Now add column 3
          int column3Index[] = {0, 1};
          double column3Value[] = {1.0, 1.0};
          model.addColumn(2, column3Index, column3Value,
                          0.0, 4.0, 4.0);
          // solve
          model.dual();

          /*
            Adding one column at a time has a significant overhead so let's
            try a more complicated but faster way

            First time adding in 10000 columns one by one

          */
          model.allSlackBasis();
          ClpSimplex modelSave = model;
          double time1 = CoinCpuTime();
          int k;
          for (k = 0; k < 10000; k++) {
               int column2Index[] = {0, 1};
               double column2Value[] = {1.0, -5.0};
               model.addColumn(2, column2Index, column2Value,
                               0.0, 1.0, 10000.0);
          }
          printf("Time for 10000 addColumn is %g\n", CoinCpuTime() - time1);
          model.dual();
          model = modelSave;
          // Now use build
          CoinBuild buildObject;
          time1 = CoinCpuTime();
          for (k = 0; k < 100000; k++) {
               int column2Index[] = {0, 1};
               double column2Value[] = {1.0, -5.0};
               buildObject.addColumn(2, column2Index, column2Value,
                                     0.0, 1.0, 10000.0);
          }
          model.addColumns(buildObject);
          printf("Time for 100000 addColumn using CoinBuild is %g\n", CoinCpuTime() - time1);
          model.dual();
          model = modelSave;
          // Now use build +-1
          int del[] = {0, 1, 2};
          model.deleteColumns(3, del);
          CoinBuild buildObject2;
          time1 = CoinCpuTime();
          for (k = 0; k < 10000; k++) {
               int column2Index[] = {0, 1};
               double column2Value[] = {1.0, 1.0, -1.0};
               int bias = k & 1;
               buildObject2.addColumn(2, column2Index, column2Value + bias,
                                      0.0, 1.0, 10000.0);
          }
          model.addColumns(buildObject2, true);
          printf("Time for 10000 addColumn using CoinBuild+-1 is %g\n", CoinCpuTime() - time1);
          model.dual();
          model = modelSave;
          // Now use build +-1
          model.deleteColumns(3, del);
          CoinModel modelObject2;
          time1 = CoinCpuTime();
          for (k = 0; k < 10000; k++) {
               int column2Index[] = {0, 1};
               double column2Value[] = {1.0, 1.0, -1.0};
               int bias = k & 1;
               modelObject2.addColumn(2, column2Index, column2Value + bias,
                                      0.0, 1.0, 10000.0);
          }
          model.addColumns(modelObject2, true);
          printf("Time for 10000 addColumn using CoinModel+-1 is %g\n", CoinCpuTime() - time1);
          //model.writeMps("xx.mps");
          model.dual();
          model = modelSave;
          // Now use model
          CoinModel modelObject;
          time1 = CoinCpuTime();
          for (k = 0; k < 100000; k++) {
               int column2Index[] = {0, 1};
               double column2Value[] = {1.0, -5.0};
               modelObject.addColumn(2, column2Index, column2Value,
                                     0.0, 1.0, 10000.0);
          }
          model.addColumns(modelObject);
          printf("Time for 100000 addColumn using CoinModel is %g\n", CoinCpuTime() - time1);
          model.dual();
          // Print column solution Just first 3 columns
          int numberColumns = model.numberColumns();
          numberColumns = CoinMin(3, numberColumns);

          // Alternatively getColSolution()
          double * columnPrimal = model.primalColumnSolution();
          // Alternatively getReducedCost()
          double * columnDual = model.dualColumnSolution();
          // Alternatively getColLower()
          double * columnLower = model.columnLower();  // Alternatively getColUpper()
          double * columnUpper = model.columnUpper();
          // Alternatively getObjCoefficients()
          double * columnObjective = model.objective();

          int iColumn;

          std::cout << "               Primal          Dual         Lower         Upper          Cost"
                    << std::endl;

          for (iColumn = 0; iColumn < numberColumns; iColumn++) {
               double value;
               std::cout << std::setw(6) << iColumn << " ";
               value = columnPrimal[iColumn];
               if (fabs(value) < 1.0e5)
                    std::cout << std::setiosflags(std::ios::fixed | std::ios::showpoint) << std::setw(14) << value;
               else
                    std::cout << std::setiosflags(std::ios::scientific) << std::setw(14) << value;
               value = columnDual[iColumn];
               if (fabs(value) < 1.0e5)
                    std::cout << std::setiosflags(std::ios::fixed | std::ios::showpoint) << std::setw(14) << value;
               else
                    std::cout << std::setiosflags(std::ios::scientific) << std::setw(14) << value;
               value = columnLower[iColumn];
               if (fabs(value) < 1.0e5)
                    std::cout << std::setiosflags(std::ios::fixed | std::ios::showpoint) << std::setw(14) << value;
               else
                    std::cout << std::setiosflags(std::ios::scientific) << std::setw(14) << value;
               value = columnUpper[iColumn];
               if (fabs(value) < 1.0e5)
                    std::cout << std::setiosflags(std::ios::fixed | std::ios::showpoint) << std::setw(14) << value;
               else
                    std::cout << std::setiosflags(std::ios::scientific) << std::setw(14) << value;
               value = columnObjective[iColumn];
               if (fabs(value) < 1.0e5)
                    std::cout << std::setiosflags(std::ios::fixed | std::ios::showpoint) << std::setw(14) << value;
               else
                    std::cout << std::setiosflags(std::ios::scientific) << std::setw(14) << value;

               std::cout << std::endl;
          }
          std::cout << "--------------------------------------" << std::endl;
     }
     {
          // Now copy a model
          ClpSimplex  model;
          int status;
          if (argc < 2) {
#if defined(SAMPLEDIR)
               status = model.readMps(SAMPLEDIR "/p0033.mps", true);
#else
               fprintf(stderr, "Do not know where to find sample MPS files.\n");
               exit(1);
#endif
          } else
               status = model.readMps(argv[1]);
          if (status) {
               printf("errors on input\n");
               exit(77);
          }
          model.initialSolve();
          int numberRows = model.numberRows();
          int numberColumns = model.numberColumns();
          const double * rowLower = model.rowLower();
          const double * rowUpper = model.rowUpper();

          // Start off model2
          ClpSimplex model2;
          model2.addRows(numberRows, rowLower, rowUpper, NULL);

          // Build object
          CoinBuild buildObject;
          // Add columns
          const double * columnLower = model.columnLower();
          const double * columnUpper = model.columnUpper();
          const double * objective = model.objective();
          CoinPackedMatrix * matrix = model.matrix();
          const int * row = matrix->getIndices();
          const int * columnLength = matrix->getVectorLengths();
          const CoinBigIndex * columnStart = matrix->getVectorStarts();
          const double * elementByColumn = matrix->getElements();
          for (int iColumn = 0; iColumn < numberColumns; iColumn++) {
               CoinBigIndex start = columnStart[iColumn];
               buildObject.addColumn(columnLength[iColumn], row + start, elementByColumn + start,
                                     columnLower[iColumn], columnUpper[iColumn],
                                     objective[iColumn]);
          }

          // add in
          model2.addColumns(buildObject);
          model2.initialSolve();
     }
     {
          // and again
          ClpSimplex  model;
          int status;
          if (argc < 2) {
#if defined(SAMPLEDIR)
               status = model.readMps(SAMPLEDIR "/p0033.mps", true);
#else
               fprintf(stderr, "Do not know where to find sample MPS files.\n");
               exit(1);
#endif
          } else
               status = model.readMps(argv[1]);
          if (status) {
               printf("errors on input\n");
               exit(77);
          }
          model.initialSolve();
          int numberRows = model.numberRows();
          int numberColumns = model.numberColumns();
          const double * rowLower = model.rowLower();
          const double * rowUpper = model.rowUpper();

          // Build object
          CoinModel buildObject;
          for (int iRow = 0; iRow < numberRows; iRow++)
               buildObject.setRowBounds(iRow, rowLower[iRow], rowUpper[iRow]);

          // Add columns
          const double * columnLower = model.columnLower();
          const double * columnUpper = model.columnUpper();
          const double * objective = model.objective();
          CoinPackedMatrix * matrix = model.matrix();
          const int * row = matrix->getIndices();
          const int * columnLength = matrix->getVectorLengths();
          const CoinBigIndex * columnStart = matrix->getVectorStarts();
          const double * elementByColumn = matrix->getElements();
          for (int iColumn = 0; iColumn < numberColumns; iColumn++) {
               CoinBigIndex start = columnStart[iColumn];
               buildObject.addColumn(columnLength[iColumn], row + start, elementByColumn + start,
                                     columnLower[iColumn], columnUpper[iColumn],
                                     objective[iColumn]);
          }

          // add in
          ClpSimplex model2;
          model2.loadProblem(buildObject);
          model2.initialSolve();
     }
     return 0;
}
예제 #4
0
파일: sample5.cpp 프로젝트: Flymir/coin-all
int main (int argc, const char *argv[])
{

  /* Define your favorite OsiSolver.

     CbcModel clones the solver so use solver1 up to the time you pass it
     to CbcModel then use a pointer to cloned solver (model.solver())
  */
  
  OsiClpSolverInterface solver1;
  /* From now on we can build model in a solver independent way.
     You can add rows one at a time but for large problems this is slow so
     this example uses CoinBuild or CoinModel
  */
  OsiSolverInterface * solver = &solver1;
  // Data (is exmip1.mps in Mps/Sample
  // Objective 
  double objValue[]={1.0,2.0,0.0,0.0,0.0,0.0,0.0,-1.0};
  // Lower bounds for columns
  double columnLower[]={2.5,0.0,0.0,0.0,0.5,0.0,0.0,0.0};
  // Upper bounds for columns
  double columnUpper[]={COIN_DBL_MAX,4.1,1.0,1.0,4.0,
                  COIN_DBL_MAX,COIN_DBL_MAX,4.3};
  // Lower bounds for row activities
  double rowLower[]={2.5,-COIN_DBL_MAX,-COIN_DBL_MAX,1.8,3.0};
  // Upper bounds for row activities
  double rowUpper[]={COIN_DBL_MAX,2.1,4.0,5.0,15.0};
  // Matrix stored packed
  int column[] = {0,1,3,4,7,
                  1,2,
                  2,5,
                  3,6,
                  4,7};
  double element[] = {3.0,1.0,-2.0,-1.0,-1.0,
                      2.0,1.1,
                      1.0,1.0,
                      2.8,-1.2,
                      1.0,1.9};
  int starts[]={0,5,7,9,11,13};
  // Integer variables (note upper bound already 1.0)
  int whichInt[]={2,3};
  int numberRows=(int) (sizeof(rowLower)/sizeof(double));
  int numberColumns=(int) (sizeof(columnLower)/sizeof(double));
#define BUILD 2
#if BUILD==1
  // Using CoinBuild 
  // First do columns (objective and bounds)
  int i;
  // We are not adding elements 
  for (i=0;i<numberColumns;i++) {
    solver->addCol(0,NULL,NULL,columnLower[i],columnUpper[i],
                    objValue[i]);
  }
  // mark as integer
  for (i=0;i<(int) (sizeof(whichInt)/sizeof(int));i++)
    solver->setInteger(whichInt[i]);
  // Now build rows
  CoinBuild build;
  for (i=0;i<numberRows;i++) {
    int startRow = starts[i];
    int numberInRow = starts[i+1]-starts[i];
    build.addRow(numberInRow,column+startRow,element+startRow,
                 rowLower[i],rowUpper[i]);
  }  
  // add rows into solver
  solver->addRows(build);
#else
  /* using CoinModel - more flexible but still beta.
     Can do exactly same way but can mix and match much more.
     Also all operations are on building object
  */
  CoinModel build;
  // First do columns (objective and bounds)
  int i;
  for (i=0;i<numberColumns;i++) {
    build.setColumnBounds(i,columnLower[i],columnUpper[i]);
    build.setObjective(i,objValue[i]);
  }
  // mark as integer
  for (i=0;i<(int) (sizeof(whichInt)/sizeof(int));i++)
    build.setInteger(whichInt[i]);
  // Now build rows
  for (i=0;i<numberRows;i++) {
    int startRow = starts[i];
    int numberInRow = starts[i+1]-starts[i];
    build.addRow(numberInRow,column+startRow,element+startRow,
                 rowLower[i],rowUpper[i]);
  }  
  // add rows into solver
  solver->loadFromCoinModel(build);
#endif

  // Pass to solver
  CbcModel model(*solver);
  model.solver()->setHintParam(OsiDoReducePrint,true,OsiHintTry);


  // Set up some cut generators and defaults
  // Probing first as gets tight bounds on continuous

  CglProbing generator1;
  generator1.setUsingObjective(true);
  generator1.setMaxPass(3);
  generator1.setMaxProbe(100);
  generator1.setMaxLook(50);
  generator1.setRowCuts(3);
  //  generator1.snapshot(*model.solver());
  //generator1.createCliques(*model.solver(),2,1000,true);
  //generator1.setMode(0);

  CglGomory generator2;
  // try larger limit
  generator2.setLimit(300);

  CglKnapsackCover generator3;

  CglOddHole generator4;
  generator4.setMinimumViolation(0.005);
  generator4.setMinimumViolationPer(0.00002);
  // try larger limit
  generator4.setMaximumEntries(200);

  CglClique generator5;
  generator5.setStarCliqueReport(false);
  generator5.setRowCliqueReport(false);

  CglMixedIntegerRounding mixedGen;
  CglFlowCover flowGen;
  
  // Add in generators
  model.addCutGenerator(&generator1,-1,"Probing");
  model.addCutGenerator(&generator2,-1,"Gomory");
  model.addCutGenerator(&generator3,-1,"Knapsack");
  model.addCutGenerator(&generator4,-1,"OddHole");
  model.addCutGenerator(&generator5,-1,"Clique");
  model.addCutGenerator(&flowGen,-1,"FlowCover");
  model.addCutGenerator(&mixedGen,-1,"MixedIntegerRounding");

  OsiClpSolverInterface * osiclp = dynamic_cast< OsiClpSolverInterface*> (model.solver());
  // go faster stripes
  if (osiclp->getNumRows()<300&&osiclp->getNumCols()<500) {
    osiclp->setupForRepeatedUse(2,0);
    printf("trying slightly less reliable but faster version (? Gomory cuts okay?)\n");
    printf("may not be safe if doing cuts in tree which need accuracy (level 2 anyway)\n");
  }

  // Allow rounding heuristic

  CbcRounding heuristic1(model);
  model.addHeuristic(&heuristic1);

  // And local search when new solution found

  CbcHeuristicLocal heuristic2(model);
  model.addHeuristic(&heuristic2);

  // Redundant definition of default branching (as Default == User)
  CbcBranchUserDecision branch;
  model.setBranchingMethod(&branch);

  // Definition of node choice
  CbcCompareUser compare;
  model.setNodeComparison(compare);

  // Do initial solve to continuous
  model.initialSolve();

  // Could tune more
  model.setMinimumDrop(CoinMin(1.0,
			     fabs(model.getMinimizationObjValue())*1.0e-3+1.0e-4));

  if (model.getNumCols()<500)
    model.setMaximumCutPassesAtRoot(-100); // always do 100 if possible
  else if (model.getNumCols()<5000)
    model.setMaximumCutPassesAtRoot(100); // use minimum drop
  else
    model.setMaximumCutPassesAtRoot(20);
  //model.setMaximumCutPasses(5);

  // Switch off strong branching if wanted
  // model.setNumberStrong(0);
  // Do more strong branching if small
  if (model.getNumCols()<5000)
    model.setNumberStrong(10);

  model.solver()->setIntParam(OsiMaxNumIterationHotStart,100);

  // If time is given then stop after that number of minutes
  if (argc>2) {
    int minutes = atoi(argv[2]);
    std::cout<<"Stopping after "<<minutes<<" minutes"<<std::endl;
    assert (minutes>=0);
    model.setDblParam(CbcModel::CbcMaximumSeconds,60.0*minutes);
  }
  // Switch off most output
  if (model.getNumCols()<3000) {
    model.messageHandler()->setLogLevel(1);
    //model.solver()->messageHandler()->setLogLevel(0);
  } else {
    model.messageHandler()->setLogLevel(2);
    model.solver()->messageHandler()->setLogLevel(1);
  }
  double time1 = CoinCpuTime();

  // Do complete search
  
  model.branchAndBound();

  std::cout<<" Branch and cut took "<<CoinCpuTime()-time1<<" seconds, "
	   <<model.getNodeCount()<<" nodes with objective "
	   <<model.getObjValue()
	   <<(!model.status() ? " Finished" : " Not finished")
	   <<std::endl;

  // Print more statistics
  std::cout<<"Cuts at root node changed objective from "<<model.getContinuousObjective()
	   <<" to "<<model.rootObjectiveAfterCuts()<<std::endl;

  int numberGenerators = model.numberCutGenerators();
  for (int iGenerator=0;iGenerator<numberGenerators;iGenerator++) {
    CbcCutGenerator * generator = model.cutGenerator(iGenerator);
    std::cout<<generator->cutGeneratorName()<<" was tried "
	     <<generator->numberTimesEntered()<<" times and created "
	     <<generator->numberCutsInTotal()<<" cuts of which "
	     <<generator->numberCutsActive()<<" were active after adding rounds of cuts"
	     <<std::endl;
  }
  // Print solution if any - we can't get names from Osi!

  if (model.getMinimizationObjValue()<1.0e50) {
    int numberColumns = model.solver()->getNumCols();
    
    const double * solution = model.solver()->getColSolution();
    
    int iColumn;
    std::cout<<std::setiosflags(std::ios::fixed|std::ios::showpoint)<<std::setw(14);
    
    std::cout<<"--------------------------------------"<<std::endl;
    for (iColumn=0;iColumn<numberColumns;iColumn++) {
      double value=solution[iColumn];
      if (fabs(value)>1.0e-7&&model.solver()->isInteger(iColumn)) 
	std::cout<<std::setw(6)<<iColumn<<" "<<value<<std::endl;
    }
    std::cout<<"--------------------------------------"<<std::endl;
  
    std::cout<<std::resetiosflags(std::ios::fixed|std::ios::showpoint|std::ios::scientific);
  }
  return 0;
}    
예제 #5
0
파일: makeDual.cpp 프로젝트: coin-or/Clp
int main(int argc, const char *argv[])
{
     ClpSimplex  model;
     int status;
     if (argc < 2) {
#if defined(SAMPLEDIR)
          status = model.readMps(SAMPLEDIR "/p0033.mps", true);
#else
          fprintf(stderr, "Do not know where to find sample MPS files.\n");
          exit(1);
#endif
     } else
          status = model.readMps(argv[1]);
     if (status) {
          printf("errors on input\n");
          exit(77);
     }
     {
          // check if we need to change bounds to rows
          int numberColumns = model.numberColumns();
          const double * columnLower = model.columnLower();
          const double * columnUpper = model.columnUpper();
          int iColumn;
          CoinBuild build;
          double one = 1.0;
          for (iColumn = 0; iColumn < numberColumns; iColumn++) {
               if (columnUpper[iColumn] < 1.0e20 &&
                         columnLower[iColumn] > -1.0e20) {
                    if (fabs(columnLower[iColumn]) < fabs(columnUpper[iColumn])) {
                         double value = columnUpper[iColumn];
                         model.setColumnUpper(iColumn, COIN_DBL_MAX);
                         build.addRow(1, &iColumn, &one, -COIN_DBL_MAX, value);
                    } else {
                         double value = columnLower[iColumn];
                         model.setColumnLower(iColumn, -COIN_DBL_MAX);
                         build.addRow(1, &iColumn, &one, value, COIN_DBL_MAX);
                    }
               }
          }
          if (build.numberRows())
               model.addRows(build);
     }
     int numberColumns = model.numberColumns();
     const double * columnLower = model.columnLower();
     const double * columnUpper = model.columnUpper();
     int numberRows = model.numberRows();
     double * rowLower = CoinCopyOfArray(model.rowLower(), numberRows);
     double * rowUpper = CoinCopyOfArray(model.rowUpper(), numberRows);

     const double * objective = model.objective();
     CoinPackedMatrix * matrix = model.matrix();
     // get transpose
     CoinPackedMatrix rowCopy = *matrix;
     int iRow, iColumn;
     int numberExtraRows = 0;
     for (iRow = 0; iRow < numberRows; iRow++) {
          if (rowLower[iRow] <= -1.0e20) {
          } else if (rowUpper[iRow] >= 1.0e20) {
          } else {
               if (rowUpper[iRow] != rowLower[iRow])
                    numberExtraRows++;
          }
     }
     const int * row = matrix->getIndices();
     const int * columnLength = matrix->getVectorLengths();
     const CoinBigIndex * columnStart = matrix->getVectorStarts();
     const double * elementByColumn = matrix->getElements();
     double objOffset = 0.0;
     for (iColumn = 0; iColumn < numberColumns; iColumn++) {
          double offset = 0.0;
          if (columnUpper[iColumn] >= 1.0e20) {
               if (columnLower[iColumn] > -1.0e20)
                    offset = columnLower[iColumn];
          } else if (columnLower[iColumn] <= -1.0e20) {
               offset = columnUpper[iColumn];
          } else {
               // taken care of before
               abort();
          }
          if (offset) {
               objOffset += offset * objective[iColumn];
               for (CoinBigIndex j = columnStart[iColumn];
                         j < columnStart[iColumn] + columnLength[iColumn]; j++) {
                    int iRow = row[j];
                    if (rowLower[iRow] > -1.0e20)
                         rowLower[iRow] -= offset * elementByColumn[j];
                    if (rowUpper[iRow] < 1.0e20)
                         rowUpper[iRow] -= offset * elementByColumn[j];
               }
          }
     }
     int * which = new int[numberRows+numberExtraRows];
     rowCopy.reverseOrdering();
     rowCopy.transpose();
     double * fromRowsLower = new double[numberRows+numberExtraRows];
     double * fromRowsUpper = new double[numberRows+numberExtraRows];
     double * newObjective = new double[numberRows+numberExtraRows];
     double * fromColumnsLower = new double[numberColumns];
     double * fromColumnsUpper = new double[numberColumns];
     for (iColumn = 0; iColumn < numberColumns; iColumn++) {
          // Offset is already in
          if (columnUpper[iColumn] >= 1.0e20) {
               if (columnLower[iColumn] > -1.0e20) {
                    fromColumnsLower[iColumn] = -COIN_DBL_MAX;
                    fromColumnsUpper[iColumn] = objective[iColumn];
               } else {
                    // free
                    fromColumnsLower[iColumn] = objective[iColumn];
                    fromColumnsUpper[iColumn] = objective[iColumn];
               }
          } else if (columnLower[iColumn] <= -1.0e20) {
               fromColumnsLower[iColumn] = objective[iColumn];
               fromColumnsUpper[iColumn] = COIN_DBL_MAX;
          } else {
               abort();
          }
     }
     int kRow = 0;
     for (iRow = 0; iRow < numberRows; iRow++) {
          if (rowLower[iRow] <= -1.0e20) {
               assert(rowUpper[iRow] < 1.0e20);
               newObjective[kRow] = -rowUpper[iRow];
               fromRowsLower[kRow] = -COIN_DBL_MAX;
               fromRowsUpper[kRow] = 0.0;
               which[kRow] = iRow;
               kRow++;
          } else if (rowUpper[iRow] >= 1.0e20) {
               newObjective[kRow] = -rowLower[iRow];
               fromRowsLower[kRow] = 0.0;
               fromRowsUpper[kRow] = COIN_DBL_MAX;
               which[kRow] = iRow;
               kRow++;
          } else {
               if (rowUpper[iRow] == rowLower[iRow]) {
                    newObjective[kRow] = -rowLower[iRow];
                    fromRowsLower[kRow] = -COIN_DBL_MAX;;
                    fromRowsUpper[kRow] = COIN_DBL_MAX;
                    which[kRow] = iRow;
                    kRow++;
               } else {
                    // range
                    newObjective[kRow] = -rowUpper[iRow];
                    fromRowsLower[kRow] = -COIN_DBL_MAX;
                    fromRowsUpper[kRow] = 0.0;
                    which[kRow] = iRow;
                    kRow++;
                    newObjective[kRow] = -rowLower[iRow];
                    fromRowsLower[kRow] = 0.0;
                    fromRowsUpper[kRow] = COIN_DBL_MAX;
                    which[kRow] = iRow;
                    kRow++;
               }
          }
     }
     if (numberExtraRows) {
          CoinPackedMatrix newCopy;
          newCopy.submatrixOfWithDuplicates(rowCopy, kRow, which);
          rowCopy = newCopy;
     }
     ClpSimplex modelDual;
     modelDual.loadProblem(rowCopy, fromRowsLower, fromRowsUpper, newObjective,
                           fromColumnsLower, fromColumnsUpper);
     modelDual.setObjectiveOffset(objOffset);
     delete [] fromRowsLower;
     delete [] fromRowsUpper;
     delete [] fromColumnsLower;
     delete [] fromColumnsUpper;
     delete [] newObjective;
     delete [] which;
     delete [] rowLower;
     delete [] rowUpper;
     modelDual.writeMps("dual.mps");
     return 0;
}