Ejemplo n.º 1
0
/*
  Install the name information from a CoinMpsIO object.
*/
void OsiSolverInterface::setRowColNames (const CoinMpsIO &mps)

{ int nameDiscipline,m,n ;
/*
  Determine how we're handling names. It's possible that the underlying solver
  has overridden getIntParam, but doesn't recognise OsiNameDiscipline. In that
  case, we want to default to auto names
*/
  bool recognisesOsiNames = getIntParam(OsiNameDiscipline,nameDiscipline) ;
  if (recognisesOsiNames == false)
  { nameDiscipline = 0 ; }
/*
  Whatever happens, we're about to clean out the current name vectors. Decide
  on an appropriate size and call reallocRowColNames to adjust capacity.
*/
  if (nameDiscipline == 0)
  { m = 0 ;
    n = 0 ; }
  else
  { m = mps.getNumRows() ;
    n = mps.getNumCols() ; }
  reallocRowColNames(rowNames_,m,colNames_,n) ;
/*
  If name discipline is auto, we're done already. Otherwise, load 'em
  up. If I understand MPS correctly, names are required.
*/
  if (nameDiscipline != 0)
  { rowNames_.resize(m) ;
    for (int i = 0 ; i < m ; i++)
    { rowNames_[i] = mps.rowName(i) ; }
    objName_ = mps.getObjectiveName() ;
    colNames_.resize(n) ;
    for (int j = 0 ; j < n ; j++)
    { colNames_[j] = mps.columnName(j) ; } }

  return ; }
Ejemplo n.º 2
0
int main(int argc, const char *argv[])
{
     int status;
     CoinMpsIO m;
     if (argc < 2)
          status = m.readMps("model1.mps", "");
     else
          status = m.readMps(argv[1], "");

     if (status) {
          fprintf(stdout, "Bad readMps %s\n", argv[1]);
          exit(1);
     }

     // Load up model1 - so we can use known good solution
     ClpSimplex model1;
     model1.loadProblem(*m.getMatrixByCol(),
                        m.getColLower(), m.getColUpper(),
                        m.getObjCoefficients(),
                        m.getRowLower(), m.getRowUpper());
     model1.dual();
     // Get data arrays
     const CoinPackedMatrix * matrix1 = m.getMatrixByCol();
     const int * start1 = matrix1->getVectorStarts();
     const int * length1 = matrix1->getVectorLengths();
     const int * row1 = matrix1->getIndices();
     const double * element1 = matrix1->getElements();

     const double * columnLower1 = m.getColLower();
     const double * columnUpper1 = m.getColUpper();
     const double * rowLower1 = m.getRowLower();
     const double * rowUpper1 = m.getRowUpper();
     const double * objective1 = m.getObjCoefficients();

     int numberColumns = m.getNumCols();
     int numberRows = m.getNumRows();
     int numberElements = m.getNumElements();

     // Get new arrays
     int numberColumns2 = (numberColumns + 1);
     int * start2 = new int[numberColumns2+1];
     int * row2 = new int[numberElements];
     double * element2 = new double[numberElements];
     int * segstart = new int[numberColumns+1];
     double * breakpt  = new double[2*numberColumns];
     double * slope  = new double[2*numberColumns];

     double * objective2 = new double[numberColumns2];
     double * columnLower2 = new double[numberColumns2];
     double * columnUpper2 = new double[numberColumns2];
     double * rowLower2 = new double[numberRows];
     double * rowUpper2 = new double[numberRows];

     // We need to modify rhs
     memcpy(rowLower2, rowLower1, numberRows * sizeof(double));
     memcpy(rowUpper2, rowUpper1, numberRows * sizeof(double));
     double objectiveOffset = 0.0;

     // For new solution
     double * newSolution = new double [numberColumns];
     const double * oldSolution = model1.primalColumnSolution();

     int iColumn;
     for (iColumn = 0; iColumn < numberColumns; iColumn++)
          printf("%g ", oldSolution[iColumn]);
     printf("\n");

     numberColumns2 = 0;
     numberElements = 0;
     start2[0] = 0;
     int segptr = 0;

     segstart[0] = 0;

     // Now check for duplicates
     for (iColumn = 0; iColumn < numberColumns; iColumn++) {
          // test if column identical to next column
          bool ifcopy = 1;
          if (iColumn < numberColumns - 1) {
               int  joff = length1[iColumn];
               for (int j = start1[iColumn]; j < start1[iColumn] + length1[iColumn]; j++) {
                    if (row1[j] != row1[j+joff]) {
                         ifcopy = 0;
                         break;
                    }
                    if (element1[j] != element1[j+joff]) {
                         ifcopy = 0;
                         break;
                    }
               }
          } else {
               ifcopy = 0;
          }
          //if (iColumn>47||iColumn<45)
          //ifcopy=0;
          if (ifcopy) {
               double lo1 = columnLower1[iColumn];
               double up1 = columnUpper1[iColumn];
               double obj1 = objective1[iColumn];
               double sol1 = oldSolution[iColumn];
               double lo2 = columnLower1[iColumn+1];
               double up2 = columnUpper1[iColumn+1];
               double obj2 = objective1[iColumn+1];
               double sol2 = oldSolution[iColumn+1];
               if (fabs(up1 - lo2) > 1.0e-8) {
                    // try other way
                    double temp;
                    temp = lo1;
                    lo1 = lo2;
                    lo2 = temp;
                    temp = up1;
                    up1 = up2;
                    up2 = temp;
                    temp = obj1;
                    obj1 = obj2;
                    obj2 = temp;
                    temp = sol1;
                    sol1 = sol2;
                    sol2 = temp;
                    assert(fabs(up1 - lo2) < 1.0e-8);
               }
               // subtract out from rhs
               double fixed = up1;
               // do offset
               objectiveOffset += fixed * obj2;
               for (int j = start1[iColumn]; j < start1[iColumn] + length1[iColumn]; j++) {
                    int iRow = row1[j];
                    double value = element1[j];
                    if (rowLower2[iRow] > -1.0e30)
                         rowLower2[iRow] -= value * fixed;
                    if (rowUpper2[iRow] < 1.0e30)
                         rowUpper2[iRow] -= value * fixed;
               }
               newSolution[numberColumns2] = fixed;
               if (fabs(sol1 - fixed) > 1.0e-8)
                    newSolution[numberColumns2] = sol1;
               if (fabs(sol2 - fixed) > 1.0e-8)
                    newSolution[numberColumns2] = sol2;
               columnLower2[numberColumns2] = lo1;
               columnUpper2[numberColumns2] = up2;
               objective2[numberColumns2] = 0.0;
               breakpt[segptr] = lo1;
               slope[segptr++] = obj1;
               breakpt[segptr] = lo2;
               slope[segptr++] = obj2;
               for (int j = start1[iColumn]; j < start1[iColumn] + length1[iColumn]; j++) {
                    row2[numberElements] = row1[j];
                    element2[numberElements++] = element1[j];
               }
               start2[++numberColumns2] = numberElements;
               breakpt[segptr] = up2;
               slope[segptr++] = COIN_DBL_MAX;
               segstart[numberColumns2] = segptr;
               iColumn++; // skip next column
          } else {
               // normal column
               columnLower2[numberColumns2] = columnLower1[iColumn];
               columnUpper2[numberColumns2] = columnUpper1[iColumn];
               objective2[numberColumns2] = objective1[iColumn];
               breakpt[segptr] = columnLower1[iColumn];
               slope[segptr++] = objective1[iColumn];
               for (int j = start1[iColumn]; j < start1[iColumn] + length1[iColumn]; j++) {
                    row2[numberElements] = row1[j];
                    element2[numberElements++] = element1[j];
               }
               newSolution[numberColumns2] = oldSolution[iColumn];
               start2[++numberColumns2] = numberElements;
               breakpt[segptr] = columnUpper1[iColumn];
               slope[segptr++] = COIN_DBL_MAX;
               segstart[numberColumns2] = segptr;
          }
     }

     // print new number of columns, elements
     printf("New number of columns  = %d\n", numberColumns2);
     printf("New number of elements = %d\n", numberElements);
     printf("Objective offset is %g\n", objectiveOffset);


     ClpSimplex  model;

     // load up
     model.loadProblem(numberColumns2, numberRows,
                       start2, row2, element2,
                       columnLower2, columnUpper2,
                       objective2,
                       rowLower2, rowUpper2);
     model.scaling(0);
     model.setDblParam(ClpObjOffset, -objectiveOffset);
     // Create nonlinear objective
     int returnCode = model.createPiecewiseLinearCosts(segstart, breakpt, slope);
     assert(!returnCode);

     // delete
     delete [] segstart;
     delete [] breakpt;
     delete [] slope;
     delete [] start2;
     delete [] row2 ;
     delete [] element2;

     delete [] objective2;
     delete [] columnLower2;
     delete [] columnUpper2;
     delete [] rowLower2;
     delete [] rowUpper2;

     // copy in solution - (should be optimal)
     model.allSlackBasis();
     memcpy(model.primalColumnSolution(), newSolution, numberColumns2 * sizeof(double));
     //memcpy(model.columnLower(),newSolution,numberColumns2*sizeof(double));
     //memcpy(model.columnUpper(),newSolution,numberColumns2*sizeof(double));
     delete [] newSolution;
     //model.setLogLevel(63);

     const double * solution = model.primalColumnSolution();
     double * saveSol = new double[numberColumns2];
     memcpy(saveSol, solution, numberColumns2 * sizeof(double));
     for (iColumn = 0; iColumn < numberColumns2; iColumn++)
          printf("%g ", solution[iColumn]);
     printf("\n");
     // solve
     model.primal(1);
     for (iColumn = 0; iColumn < numberColumns2; iColumn++) {
          if (fabs(solution[iColumn] - saveSol[iColumn]) > 1.0e-3)
               printf(" ** was %g ", saveSol[iColumn]);
          printf("%g ", solution[iColumn]);
     }
     printf("\n");
     model.primal(1);
     for (iColumn = 0; iColumn < numberColumns2; iColumn++) {
          if (fabs(solution[iColumn] - saveSol[iColumn]) > 1.0e-3)
               printf(" ** was %g ", saveSol[iColumn]);
          printf("%g ", solution[iColumn]);
     }
     printf("\n");
     model.primal();
     for (iColumn = 0; iColumn < numberColumns2; iColumn++) {
          if (fabs(solution[iColumn] - saveSol[iColumn]) > 1.0e-3)
               printf(" ** was %g ", saveSol[iColumn]);
          printf("%g ", solution[iColumn]);
     }
     printf("\n");
     model.allSlackBasis();
     for (iColumn = 0; iColumn < numberColumns2; iColumn++) {
          if (fabs(solution[iColumn] - saveSol[iColumn]) > 1.0e-3)
               printf(" ** was %g ", saveSol[iColumn]);
          printf("%g ", solution[iColumn]);
     }
     printf("\n");
     model.setLogLevel(63);
     model.primal();
     for (iColumn = 0; iColumn < numberColumns2; iColumn++) {
          if (fabs(solution[iColumn] - saveSol[iColumn]) > 1.0e-3)
               printf(" ** was %g ", saveSol[iColumn]);
          printf("%g ", solution[iColumn]);
     }
     printf("\n");
     return 0;
}
Ejemplo n.º 3
0
//--------------------------------------------------------------------------
// Test building a model
void
CoinModelUnitTest(const std::string & mpsDir,
                  const std::string & netlibDir, const std::string & testModel)
{

    // Get a model
    CoinMpsIO m;
    std::string fn = mpsDir+"exmip1";
    int numErr = m.readMps(fn.c_str(),"mps");
    assert( numErr== 0 );

    int numberRows = m.getNumRows();
    int numberColumns = m.getNumCols();

    // Build by row from scratch
    {
        CoinPackedMatrix matrixByRow = * m.getMatrixByRow();
        const double * element = matrixByRow.getElements();
        const int * column = matrixByRow.getIndices();
        const CoinBigIndex * rowStart = matrixByRow.getVectorStarts();
        const int * rowLength = matrixByRow.getVectorLengths();
        const double * rowLower = m.getRowLower();
        const double * rowUpper = m.getRowUpper();
        const double * columnLower = m.getColLower();
        const double * columnUpper = m.getColUpper();
        const double * objective = m.getObjCoefficients();
        int i;
        CoinModel temp;
        for (i=0; i<numberRows; i++) {
            temp.addRow(rowLength[i],column+rowStart[i],
                        element+rowStart[i],rowLower[i],rowUpper[i],m.rowName(i));
        }
        // Now do column part
        for (i=0; i<numberColumns; i++) {
            temp.setColumnBounds(i,columnLower[i],columnUpper[i]);
            temp.setColumnObjective(i,objective[i]);
            if (m.isInteger(i))
                temp.setColumnIsInteger(i,true);;
        }
        // write out
        temp.writeMps("byRow.mps");
    }

    // Build by column from scratch and save
    CoinModel model;
    {
        CoinPackedMatrix matrixByColumn = * m.getMatrixByCol();
        const double * element = matrixByColumn.getElements();
        const int * row = matrixByColumn.getIndices();
        const CoinBigIndex * columnStart = matrixByColumn.getVectorStarts();
        const int * columnLength = matrixByColumn.getVectorLengths();
        const double * rowLower = m.getRowLower();
        const double * rowUpper = m.getRowUpper();
        const double * columnLower = m.getColLower();
        const double * columnUpper = m.getColUpper();
        const double * objective = m.getObjCoefficients();
        int i;
        for (i=0; i<numberColumns; i++) {
            model.addColumn(columnLength[i],row+columnStart[i],
                            element+columnStart[i],columnLower[i],columnUpper[i],
                            objective[i],m.columnName(i),m.isInteger(i));
        }
        // Now do row part
        for (i=0; i<numberRows; i++) {
            model.setRowBounds(i,rowLower[i],rowUpper[i]);
        }
        // write out
        model.writeMps("byColumn.mps");
    }

    // model was created by column - play around
    {
        CoinModel temp;
        int i;
        for (i=numberRows-1; i>=0; i--)
            temp.setRowLower(i,model.getRowLower(i));
        for (i=0; i<numberColumns; i++) {
            temp.setColumnUpper(i,model.getColumnUpper(i));
            temp.setColumnName(i,model.getColumnName(i));
        }
        for (i=numberColumns-1; i>=0; i--) {
            temp.setColumnLower(i,model.getColumnLower(i));
            temp.setColumnObjective(i,model.getColumnObjective(i));
            temp.setColumnIsInteger(i,model.getColumnIsInteger(i));
        }
        for (i=0; i<numberRows; i++) {
            temp.setRowUpper(i,model.getRowUpper(i));
            temp.setRowName(i,model.getRowName(i));
        }
        // Now elements
        for (i=0; i<numberRows; i++) {
            CoinModelLink triple=model.firstInRow(i);
            while (triple.column()>=0) {
                temp(i,triple.column(),triple.value());
                triple=model.next(triple);
            }
        }
        // and by column
        for (i=numberColumns-1; i>=0; i--) {
            CoinModelLink triple=model.lastInColumn(i);
            while (triple.row()>=0) {
                assert (triple.value()==temp(triple.row(),i));
                temp(triple.row(),i,triple.value());
                triple=model.previous(triple);
            }
        }
        // check equal
        model.setLogLevel(1);
        assert (!model.differentModel(temp,false));
    }
    // Try creating model with strings
    {
        CoinModel temp;
        int i;
        for (i=numberRows-1; i>=0; i--) {
            double value = model.getRowLower(i);
            if (value==-1.0)
                temp.setRowLower(i,"minusOne");
            else if (value==1.0)
                temp.setRowLower(i,"sqrt(plusOne)");
            else if (value==4.0)
                temp.setRowLower(i,"abs(4*plusOne)");
            else
                temp.setRowLower(i,value);
        }
        for (i=0; i<numberColumns; i++) {
            double value;
            value = model.getColumnUpper(i);
            if (value==-1.0)
                temp.setColumnUpper(i,"minusOne");
            else if (value==1.0)
                temp.setColumnUpper(i,"plusOne");
            else
                temp.setColumnUpper(i,value);
            temp.setColumnName(i,model.getColumnName(i));
        }
        for (i=numberColumns-1; i>=0; i--) {
            temp.setColumnLower(i,model.getColumnLower(i));
            temp.setColumnObjective(i,model.getColumnObjective(i));
            temp.setColumnIsInteger(i,model.getColumnIsInteger(i));
        }
        for (i=0; i<numberRows; i++) {
            double value = model.getRowUpper(i);
            if (value==-1.0)
                temp.setRowUpper(i,"minusOne");
            else if (value==1.0)
                temp.setRowUpper(i,"plusOne");
            else
                temp.setRowUpper(i,value);
            temp.setRowName(i,model.getRowName(i));
        }
        // Now elements
        for (i=0; i<numberRows; i++) {
            CoinModelLink triple=model.firstInRow(i);
            while (triple.column()>=0) {
                double value = triple.value();
                if (value==-1.0)
                    temp(i,triple.column(),"minusOne");
                else if (value==1.0)
                    temp(i,triple.column(),"plusOne");
                else if (value==-2.0)
                    temp(i,triple.column(),"minusOne-1.0");
                else if (value==2.0)
                    temp(i,triple.column(),"plusOne+1.0+minusOne+(2.0-plusOne)");
                else
                    temp(i,triple.column(),value);
                triple=model.next(triple);
            }
        }
        temp.associateElement("minusOne",-1.0);
        temp.associateElement("plusOne",1.0);
        temp.setProblemName("fromStrings");
        temp.writeMps("string.mps");

        // check equal
        model.setLogLevel(1);
        assert (!model.differentModel(temp,false));
    }
    // Test with various ways of generating
    {
        /*
          Get a model. Try first with netlibDir, fall back to mpsDir (sampleDir)
          if that fails.
        */
        CoinMpsIO m;
        std::string fn = netlibDir+testModel;
        double time1 = CoinCpuTime();
        int numErr = m.readMps(fn.c_str(),"");
        if (numErr != 0) {
            std::cout
                    << "Could not read " << testModel << " in " << netlibDir
                    << "; falling back to " << mpsDir << "." << std::endl ;
            fn = mpsDir+testModel ;
            numErr = m.readMps(fn.c_str(),"") ;
            if (numErr != 0) {
                std::cout << "Could not read " << testModel << "; skipping test." << std::endl ;
            }
        }
        if (numErr == 0) {
            std::cout
                    << "Time for readMps is "
                    << (CoinCpuTime()-time1) << " seconds." << std::endl ;
            int numberRows = m.getNumRows();
            int numberColumns = m.getNumCols();
            // Build model
            CoinModel model;
            CoinPackedMatrix matrixByRow = * m.getMatrixByRow();
            const double * element = matrixByRow.getElements();
            const int * column = matrixByRow.getIndices();
            const CoinBigIndex * rowStart = matrixByRow.getVectorStarts();
            const int * rowLength = matrixByRow.getVectorLengths();
            const double * rowLower = m.getRowLower();
            const double * rowUpper = m.getRowUpper();
            const double * columnLower = m.getColLower();
            const double * columnUpper = m.getColUpper();
            const double * objective = m.getObjCoefficients();
            int i;
            for (i=0; i<numberRows; i++) {
                model.addRow(rowLength[i],column+rowStart[i],
                             element+rowStart[i],rowLower[i],rowUpper[i],m.rowName(i));
            }
            // Now do column part
            for (i=0; i<numberColumns; i++) {
                model.setColumnBounds(i,columnLower[i],columnUpper[i]);
                model.setColumnObjective(i,objective[i]);
                model.setColumnName(i,m.columnName(i));
                if (m.isInteger(i))
                    model.setColumnIsInteger(i,true);;
            }
            // Test
            CoinSeedRandom(11111);
            time1 = 0.0;
            int nPass=50;
            for (i=0; i<nPass; i++) {
                double random = CoinDrand48();
                int iSeed = (int) (random*1000000);
                //iSeed = 776151;
                CoinSeedRandom(iSeed);
                std::cout << "before pass " << i << " with seed of " << iSeed << std::endl ;
                buildRandom(model,CoinDrand48(),time1,i);
                model.validateLinks();
            }
            std::cout
                    << "Time for " << nPass << " CoinModel passes is "
                    << time1 << " seconds\n" << std::endl ;
        }
    }
}