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