00001
00002
00003
00004
00005
00006
00007 #include "ClpSimplex.hpp"
00008 #include "ClpNonLinearCost.hpp"
00009 #include "CoinMpsIO.hpp"
00010 #include <iomanip>
00011
00012 int main (int argc, const char *argv[])
00013 {
00014 int status;
00015 CoinMpsIO m;
00016 if (argc<2)
00017 status=m.readMps("model1.mps","");
00018 else
00019 status=m.readMps(argv[1],"");
00020
00021 if (status) {
00022 fprintf(stdout,"Bad readMps %s\n",argv[1]);
00023 exit(1);
00024 }
00025
00026
00027 ClpSimplex model1;
00028 model1.loadProblem(*m.getMatrixByCol(),
00029 m.getColLower(),m.getColUpper(),
00030 m.getObjCoefficients(),
00031 m.getRowLower(),m.getRowUpper());
00032 model1.dual();
00033
00034 const CoinPackedMatrix * matrix1 = m.getMatrixByCol();
00035 const int * start1 = matrix1->getVectorStarts();
00036 const int * length1 = matrix1->getVectorLengths();
00037 const int * row1 = matrix1->getIndices();
00038 const double * element1 = matrix1->getElements();
00039
00040 const double * columnLower1 = m.getColLower();
00041 const double * columnUpper1 = m.getColUpper();
00042 const double * rowLower1 = m.getRowLower();
00043 const double * rowUpper1 = m.getRowUpper();
00044 const double * objective1 = m.getObjCoefficients();
00045
00046 int numberColumns = m.getNumCols();
00047 int numberRows = m.getNumRows();
00048 int numberElements = m.getNumElements();
00049
00050
00051 int numberColumns2 = (numberColumns+1);
00052 int * start2 = new int[numberColumns2+1];
00053 int * row2 = new int[numberElements];
00054 double * element2 = new double[numberElements];
00055 int * segstart = new int[numberColumns+1];
00056 double * breakpt = new double[2*numberColumns];
00057 double * slope = new double[2*numberColumns];
00058
00059 double * objective2 = new double[numberColumns2];
00060 double * columnLower2 = new double[numberColumns2];
00061 double * columnUpper2 = new double[numberColumns2];
00062 double * rowLower2 = new double[numberRows];
00063 double * rowUpper2 = new double[numberRows];
00064
00065
00066 memcpy(rowLower2,rowLower1,numberRows*sizeof(double));
00067 memcpy(rowUpper2,rowUpper1,numberRows*sizeof(double));
00068 double objectiveOffset = 0.0;
00069
00070
00071 double * newSolution = new double [numberColumns];
00072 const double * oldSolution = model1.primalColumnSolution();
00073
00074 int iColumn;
00075 for (iColumn=0;iColumn<numberColumns;iColumn++)
00076 printf("%g ",oldSolution[iColumn]);
00077 printf("\n");
00078
00079 numberColumns2=0;
00080 numberElements=0;
00081 start2[0]=0;
00082 int segptr=0;
00083
00084 segstart[0]=0;
00085
00086
00087 for (iColumn=0;iColumn<numberColumns;iColumn++) {
00088
00089 bool ifcopy=1;
00090 if (iColumn<numberColumns-1) {
00091 int joff = length1[iColumn];
00092 for (int j=start1[iColumn];j<start1[iColumn]+length1[iColumn];j++) {
00093 if (row1[j] != row1[j+joff]){
00094 ifcopy=0;
00095 break;
00096 }
00097 if (element1[j] != element1[j+joff]){
00098 ifcopy=0;
00099 break;
00100 }
00101 }
00102 } else {
00103 ifcopy=0;
00104 }
00105
00106
00107 if (ifcopy) {
00108 double lo1 = columnLower1[iColumn];
00109 double up1 = columnUpper1[iColumn];
00110 double obj1 = objective1[iColumn];
00111 double sol1 = oldSolution[iColumn];
00112 double lo2 = columnLower1[iColumn+1];
00113 double up2 = columnUpper1[iColumn+1];
00114 double obj2 = objective1[iColumn+1];
00115 double sol2 = oldSolution[iColumn+1];
00116 if(fabs(up1-lo2)>1.0e-8) {
00117
00118 double temp;
00119 temp = lo1;
00120 lo1=lo2;
00121 lo2=temp;
00122 temp = up1;
00123 up1=up2;
00124 up2=temp;
00125 temp = obj1;
00126 obj1=obj2;
00127 obj2=temp;
00128 temp = sol1;
00129 sol1=sol2;
00130 sol2=temp;
00131 assert(fabs(up1-lo2)<1.0e-8);
00132 }
00133
00134 double fixed = up1;
00135
00136 objectiveOffset += fixed*obj2;
00137 for (int j=start1[iColumn];j<start1[iColumn]+length1[iColumn];j++) {
00138 int iRow = row1[j];
00139 double value = element1[j];
00140 if (rowLower2[iRow]>-1.0e30)
00141 rowLower2[iRow] -= value*fixed;
00142 if (rowUpper2[iRow]<1.0e30)
00143 rowUpper2[iRow] -= value*fixed;
00144 }
00145 newSolution[numberColumns2]=fixed;
00146 if (fabs(sol1-fixed)>1.0e-8)
00147 newSolution[numberColumns2]=sol1;
00148 if (fabs(sol2-fixed)>1.0e-8)
00149 newSolution[numberColumns2]=sol2;
00150 columnLower2[numberColumns2] = lo1;
00151 columnUpper2[numberColumns2] = up2;
00152 objective2[numberColumns2] = 0.0;
00153 breakpt[segptr] = lo1;
00154 slope[segptr++] = obj1;
00155 breakpt[segptr] = lo2;
00156 slope[segptr++] = obj2;
00157 for (int j=start1[iColumn];j<start1[iColumn]+length1[iColumn];j++) {
00158 row2[numberElements]=row1[j];
00159 element2[numberElements++] = element1[j];
00160 }
00161 start2[++numberColumns2]=numberElements;
00162 breakpt[segptr] = up2;
00163 slope[segptr++] = COIN_DBL_MAX;
00164 segstart[numberColumns2] = segptr;
00165 iColumn++;
00166 } else {
00167
00168 columnLower2[numberColumns2] = columnLower1[iColumn];
00169 columnUpper2[numberColumns2] = columnUpper1[iColumn];
00170 objective2[numberColumns2] = objective1[iColumn];
00171 breakpt[segptr] = columnLower1[iColumn];
00172 slope[segptr++] = objective1[iColumn];
00173 for (int j=start1[iColumn];j<start1[iColumn]+length1[iColumn];j++) {
00174 row2[numberElements]=row1[j];
00175 element2[numberElements++] = element1[j];
00176 }
00177 newSolution[numberColumns2]=oldSolution[iColumn];
00178 start2[++numberColumns2]=numberElements;
00179 breakpt[segptr] = columnUpper1[iColumn];
00180 slope[segptr++] = COIN_DBL_MAX;
00181 segstart[numberColumns2] = segptr;
00182 }
00183 }
00184
00185
00186 printf("New number of columns = %d\n",numberColumns2);
00187 printf("New number of elements = %d\n",numberElements);
00188 printf("Objective offset is %g\n",objectiveOffset);
00189
00190
00191 ClpSimplex model;
00192
00193
00194 model.loadProblem(numberColumns2,numberRows,
00195 start2,row2,element2,
00196 columnLower2,columnUpper2,
00197 objective2,
00198 rowLower2,rowUpper2);
00199 model.scaling(0);
00200 model.setDblParam(ClpObjOffset,-objectiveOffset);
00201
00202 int returnCode= model.createPiecewiseLinearCosts(segstart, breakpt, slope);
00203 assert (!returnCode);
00204
00205
00206 delete [] segstart;
00207 delete [] breakpt;
00208 delete [] slope;
00209 delete [] start2;
00210 delete [] row2 ;
00211 delete [] element2;
00212
00213 delete [] objective2;
00214 delete [] columnLower2;
00215 delete [] columnUpper2;
00216 delete [] rowLower2;
00217 delete [] rowUpper2;
00218
00219
00220 model.allSlackBasis();
00221 memcpy(model.primalColumnSolution(),newSolution,numberColumns2*sizeof(double));
00222
00223
00224 delete [] newSolution;
00225
00226
00227 const double * solution = model.primalColumnSolution();
00228 double * saveSol = new double[numberColumns2];
00229 memcpy(saveSol,solution,numberColumns2*sizeof(double));
00230 for (iColumn=0;iColumn<numberColumns2;iColumn++)
00231 printf("%g ",solution[iColumn]);
00232 printf("\n");
00233
00234 model.primal(1);
00235 for (iColumn=0;iColumn<numberColumns2;iColumn++) {
00236 if (fabs(solution[iColumn]-saveSol[iColumn])>1.0e-3)
00237 printf(" ** was %g ",saveSol[iColumn]);
00238 printf("%g ",solution[iColumn]);
00239 }
00240 printf("\n");
00241 model.primal(1);
00242 for (iColumn=0;iColumn<numberColumns2;iColumn++) {
00243 if (fabs(solution[iColumn]-saveSol[iColumn])>1.0e-3)
00244 printf(" ** was %g ",saveSol[iColumn]);
00245 printf("%g ",solution[iColumn]);
00246 }
00247 printf("\n");
00248 model.primal();
00249 for (iColumn=0;iColumn<numberColumns2;iColumn++) {
00250 if (fabs(solution[iColumn]-saveSol[iColumn])>1.0e-3)
00251 printf(" ** was %g ",saveSol[iColumn]);
00252 printf("%g ",solution[iColumn]);
00253 }
00254 printf("\n");
00255 model.allSlackBasis();
00256 for (iColumn=0;iColumn<numberColumns2;iColumn++) {
00257 if (fabs(solution[iColumn]-saveSol[iColumn])>1.0e-3)
00258 printf(" ** was %g ",saveSol[iColumn]);
00259 printf("%g ",solution[iColumn]);
00260 }
00261 printf("\n");
00262 model.setLogLevel(63);
00263 model.primal();
00264 for (iColumn=0;iColumn<numberColumns2;iColumn++) {
00265 if (fabs(solution[iColumn]-saveSol[iColumn])>1.0e-3)
00266 printf(" ** was %g ",saveSol[iColumn]);
00267 printf("%g ",solution[iColumn]);
00268 }
00269 printf("\n");
00270 return 0;
00271 }