Main Page | Class Hierarchy | Alphabetical List | Class List | File List | Class Members

sprint2.cpp

00001 // Copyright (C) 2003, International Business Machines
00002 // Corporation and others.  All Rights Reserved.
00003 
00004 #include "ClpSimplex.hpp"
00005 #include "ClpPresolve.hpp"
00006 #include "CoinSort.hpp"
00007 #include <iomanip>
00008 
00009 int main (int argc, const char *argv[])
00010 {
00011   ClpSimplex  model;
00012   int status;
00013   // Keep names
00014   if (argc<2) {
00015     status=model.readMps("small.mps",true);
00016   } else {
00017     status=model.readMps(argv[1],true);
00018   }
00019   if (status)
00020     exit(10);
00021   /*
00022     This driver implements the presolve variation of Sprint.
00023     This assumes we can get feasible easily
00024   */
00025 
00026   int numberRows = model.numberRows();
00027   int numberColumns = model.numberColumns();
00028 
00029   // We will need arrays to choose variables.  These are too big but ..
00030   double * weight = new double [numberRows+numberColumns];
00031   int * sort = new int [numberRows+numberColumns];
00032 
00033   double * columnLower = model.columnLower();
00034   double * columnUpper = model.columnUpper();
00035   double * saveLower = new double [numberColumns];
00036   memcpy(saveLower,columnLower,numberColumns*sizeof(double));
00037   double * saveUpper = new double [numberColumns];
00038   memcpy(saveUpper,columnUpper,numberColumns*sizeof(double));
00039   // Fix in some magical way so remaining problem is easy
00040   // This is from a real-world problem
00041   for (int iColumn=0;iColumn<numberColumns;iColumn++) {
00042     char firstCharacter = model.columnName(iColumn)[0];
00043     if (firstCharacter=='F'||firstCharacter=='P'
00044         ||firstCharacter=='L'||firstCharacter=='T') {
00045       columnUpper[iColumn]=columnLower[iColumn];
00046     }
00047   }
00048   double * solution = model.primalColumnSolution();
00049 
00050   // Just do this number of passes
00051   int maxPass=100;
00052   int iPass;
00053   double lastObjective=1.0e31;
00054 
00055   // Just take this number of columns in small problem
00056   int smallNumberColumns = 3*numberRows;
00057   // And we want number of rows to be this
00058   int smallNumberRows = numberRows/4;
00059 
00060   for (iPass=0;iPass<maxPass;iPass++) {
00061     printf("Start of pass %d\n",iPass);
00062     ClpSimplex * model2;
00063     ClpPresolve pinfo;
00064     int numberPasses=1; // can change this
00065     model2 = pinfo.presolvedModel(model,1.0e-8,false,numberPasses,false);
00066     if (!model2) {
00067       fprintf(stdout,"ClpPresolve says %s is infeasible with tolerance of %g\n",
00068               argv[1],1.0e-8);
00069       // model was infeasible - maybe try again with looser tolerances
00070       model2 = pinfo.presolvedModel(model,1.0e-7,false,numberPasses,false);
00071       if (!model2) {
00072         fprintf(stdout,"ClpPresolve says %s is infeasible with tolerance of %g\n",
00073                 argv[1],1.0e-7);
00074         exit(2);
00075       }
00076     }
00077     // change factorization frequency from 200
00078     model2->setFactorizationFrequency(100+model2->numberRows()/50);
00079     model2->primal();
00080     pinfo.postsolve(true);
00081 
00082     // adjust smallNumberColumns if necessary
00083     if (iPass) {
00084       double ratio = ((double) smallNumberRows)/((double) model2->numberRows());
00085       smallNumberColumns = (int) (smallNumberColumns*ratio);
00086     }
00087     delete model2;
00088     /* After this postsolve model should be optimal.
00089        We can use checkSolution and test feasibility */
00090     model.checkSolution();
00091     if (model.numberDualInfeasibilities()||
00092         model.numberPrimalInfeasibilities()) 
00093       printf("%g dual %g(%d) Primal %g(%d)\n",
00094              model.objectiveValue(),
00095              model.sumDualInfeasibilities(),
00096              model.numberDualInfeasibilities(),
00097              model.sumPrimalInfeasibilities(),
00098              model.numberPrimalInfeasibilities());
00099     // Put back true bounds
00100     memcpy(columnLower,saveLower,numberColumns*sizeof(double));
00101     memcpy(columnUpper,saveUpper,numberColumns*sizeof(double));
00102     if ((model.objectiveValue()>lastObjective-1.0e-7&&iPass>5)||
00103         iPass==maxPass-1) {
00104       break; // finished
00105     } else {
00106       lastObjective = model.objectiveValue();
00107       // now massage weight so all basic in plus good djs
00108       for (int iColumn=0;iColumn<numberColumns;iColumn++) {
00109         double dj = weight[iColumn];
00110         double value = solution[iColumn];
00111         if (model.getStatus(iColumn)==ClpSimplex::basic)
00112           dj = -1.0e50;
00113         else if (dj<0.0&&value<columnUpper[iColumn])
00114           dj = dj;
00115         else if (dj>0.0&&value>columnLower[iColumn])
00116           dj = -dj;
00117         else if (columnUpper[iColumn]>columnLower[iColumn])
00118           dj = fabs(dj);
00119         else
00120           dj = 1.0e50;
00121         weight[iColumn] = dj;
00122         sort[iColumn] = iColumn;
00123       }
00124       // sort
00125       CoinSort_2(weight,weight+numberColumns,sort);
00126       // and fix others
00127       for (int iColumn=smallNumberColumns;iColumn<numberColumns;iColumn++) {
00128         int kColumn = sort[iColumn];
00129         double value = solution[kColumn];
00130         columnLower[kColumn] = value;
00131         columnUpper[kColumn] = value;
00132       }
00133     }
00134   }
00135   delete [] weight;
00136   delete [] sort;
00137   delete [] saveLower;
00138   delete [] saveUpper;
00139   model.primal(1);
00140   return 0;
00141 }    

Generated on Wed Dec 3 14:37:37 2003 for CLP by doxygen 1.3.5