// Copyright (C) 2005, International Business Machines // Corporation and others. All Rights Reserved. #if defined(_MSC_VER) // Turn off compiler warning about long names # pragma warning(disable:4786) #endif #ifdef NDEBUG #undef NDEBUG #endif #include #include "CoinMpsIO.hpp" #include "CoinModel.hpp" #include "CoinHelperFunctions.hpp" #include "CoinTime.hpp" //############################################################################# /* Build a model in some interesting way Nine blocks defined by 4 random numbers If next random number <0.4 addRow next possible If <0.8 addColumn if possible Otherwise do by element For each one use random <0.5 to add rim at same time At end fill in rim at random */ void buildRandom(CoinModel & baseModel, double random, double & timeIt, int iPass) { CoinModel model; int numberRows = baseModel.numberRows(); int numberColumns = baseModel.numberColumns(); int numberElements = baseModel.numberElements(); // Row numbers and column numbers int lastRow[4]; int lastColumn[4]; int i; lastRow[0]=0; lastColumn[0]=0; lastRow[3]=numberRows; lastColumn[3]=numberColumns; for ( i=1;i<3;i++) { int size; size = (int) ((0.25*random+0.2)*numberRows); random = CoinDrand48(); lastRow[i]=lastRow[i-1]+size; size = (int) ((0.25*random+0.2)*numberColumns); random = CoinDrand48(); lastColumn[i]=lastColumn[i-1]+size; } // whether block done 0 row first char block[9]={0,0,0,0,0,0,0,0,0}; // whether rowRim done char rowDone[3]={0,0,0}; // whether columnRim done char columnDone[3]={0,0,0}; // Save array for deleting elements CoinModelTriple * dTriple = new CoinModelTriple[numberElements]; numberElements=0; double time1 = CoinCpuTime(); for (int jBlock=0;jBlock<9;jBlock++) { int iType=-1; int iBlock=-1; if (random<0.4) { // trying addRow int j; for (j=0;j<3;j++) { int k; for (k=0;k<3;k++) { if (block[3*j+k]) break; //already taken } if (k==3) { // can do but decide which one iBlock = 3*j + (int) (CoinDrand48()*0.3); iType=0; break; } } } if (iType==-1&&random<0.8) { // trying addRow int j; for (j=0;j<3;j++) { int k; for (k=0;k<3;k++) { if (block[j+3*k]) break; //already taken } if (k==3) { // can do but decide which one iBlock = j + 3*((int) (CoinDrand48()*0.3)); iType=1; break; } } } if (iType==-1) { iType=2; int j; for (j=0;j<9;j++) { if (!block[j]) { iBlock=j; break; } } } random=CoinDrand48(); assert (iBlock>=0&&iBlock<9); assert (iType>=0); assert (!block[iBlock]); block[iBlock]=1+iType; int jRow = iBlock/3; int jColumn = iBlock%3; bool doRow = (CoinDrand48()<0.5)&&!rowDone[jRow]; bool doColumn = (CoinDrand48()<0.5&&!columnDone[jColumn]); if (!iType) { // addRow int * column = new int[lastColumn[jColumn+1]-lastColumn[jColumn]]; double * element = new double[lastColumn[jColumn+1]-lastColumn[jColumn]]; for (i=lastRow[jRow];i=0) { if (triple.column()>=lastColumn[jColumn]&&triple.column()=model.numberRows()); if (i>model.numberRows()) { assert (i==lastRow[jRow]); printf("need to fill in rows\n"); for (int k=0;k=0) { if (triple.row()>=lastRow[jRow]&&triple.row()=model.numberColumns()); if (i>model.numberColumns()) { assert (i==lastColumn[jColumn]); printf("need to fill in columns\n"); for (int k=0;k=0) { int iColumn = triple.column(); if (iColumn>=lastColumn[jColumn]&&iColumn=0) { int iRow = triple.row(); if (iRow>=lastRow[jRow]&&iRow=0;i--) { int iRow = (int) elements[i].row; int iColumn = elements[i].column; if (iRow>=lastRow[jRow]&&iRow=lastColumn[jColumn]&&iColumn=0) { int iColumn = triple.column(); if (iColumn>=lastColumn[jColumn]&&iColumn=0) { int iRow = triple.row(); if (iRow>=lastRow[jRow]&&iRow=0;i--) { int iRow = (int) elements[i].row; int iColumn = elements[i].column; if (iRow>=lastRow[jRow]&&iRow=lastColumn[jColumn]&&iColumn10) { double random2=CoinDrand48(); double randomDelete = 0.2 + 0.5*random2; // fraction to delete //model.validateLinks(); if (random2<0.2) { // delete some rows for (int j=lastRow[jRow];j=0) { int iColumn = triple.column(); assert (j==triple.row()); dTriple[numberElements].row = j; dTriple[numberElements].column=iColumn; dTriple[numberElements].value = triple.value(); numberElements++; triple=model.next(triple); } model.deleteRow(j); if (rowDone[jRow]) { // put back rim model.setRowLower(j,rowLower); model.setRowUpper(j,rowUpper); model.setRowName(j,rowName); } free(rowName); } } } else if (random2<0.4) { // delete some columns for (int j=lastColumn[jColumn];j=0) { int iRow = triple.row(); assert (j==triple.column()); dTriple[numberElements].column = j; dTriple[numberElements].row=iRow; dTriple[numberElements].value = triple.value(); numberElements++; triple=model.next(triple); } model.deleteColumn(j); if (columnDone[jColumn]) { // put back rim model.setColumnLower(j,columnLower); model.setColumnUpper(j,columnUpper); model.setObjective(j,objective); model.setIsInteger(j,integer); model.setColumnName(j,columnName); } free(columnName); } } } else { // delete some elements //model.validateLinks(); const CoinModelTriple * elements = baseModel.elements(); for (i=0;i=lastRow[jRow]&&iRow=lastColumn[jColumn]&&iColumn=0) numberElements++; } } } } } } // Do rim if necessary for (int k=0;k<3;k++) { if (!rowDone[k]) { for (i=lastRow[k];i=0;i--) temp.setRowLower(i,model.getRowLower(i)); for (i=0;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=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=0;i--) { temp.setColumnLower(i,model.getColumnLower(i)); temp.setColumnObjective(i,model.getColumnObjective(i)); temp.setColumnIsInteger(i,model.getColumnIsInteger(i)); } for (i=0;i=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 CoinMpsIO m; std::string fn = netlibDir+testModel; double time1 = CoinCpuTime(); int numErr = m.readMps(fn.c_str(),""); if ( numErr== 0 ) { printf("Time for readMps is %g seconds\n", CoinCpuTime()-time1); 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