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

sample1.cpp

00001 // Copyright (C) 2002, International Business Machines
00002 // Corporation and others.  All Rights Reserved.
00003 #if defined(_MSC_VER)
00004 // Turn off compiler warning about long names
00005 #  pragma warning(disable:4786)
00006 #endif
00007 
00008 #include <cassert>
00009 
00010 // For Branch and bound
00011 #include "OsiSolverInterface.hpp"
00012 #include "SbbModel.hpp"
00013 
00014 #ifdef COIN_USE_CLP
00015 #include "OsiClpSolverInterface.hpp"
00016 #endif
00017 #include "ClpPresolve.hpp"
00018 #include "SbbCompareUser.hpp"
00019 #include "CglProbing.hpp"
00020 
00021 //#############################################################################
00022 
00023 #ifdef NDEBUG
00024 #undef NDEBUG
00025 #endif
00026 // Time
00027 
00028 #include  <time.h>
00029 #if !defined(_MSC_VER)
00030 #include <sys/times.h>
00031 #include <sys/resource.h>
00032 #include <unistd.h>
00033 #endif
00034 static double cpuTime()
00035 {
00036   double cpu_temp;
00037 #if defined(_MSC_VER)
00038   unsigned int ticksnow;        /* clock_t is same as int */
00039   
00040   ticksnow = (unsigned int)clock();
00041   
00042   cpu_temp = (double)((double)ticksnow/CLOCKS_PER_SEC);
00043 #else
00044   struct rusage usage;
00045   getrusage(RUSAGE_SELF,&usage);
00046   cpu_temp = usage.ru_utime.tv_sec;
00047   cpu_temp += 1.0e-6*((double) usage.ru_utime.tv_usec);
00048 #endif
00049   return cpu_temp;
00050 }
00051 
00052 
00053 /************************************************************************
00054 
00055 This main program reads in an integer model from an mps file.
00056 
00057 It then sets up some Cgl cut generators and calls branch and cut.
00058 
00059 Branching is simple binary branching on integer variables.
00060 
00061 Node selection is depth first until first solution is found and then
00062 based on objective and number of unsatisfied integer variables.
00063 
00064 Variable branching selection is on maximum minimum-of-up-down change
00065 after strong branching on 5 variables closest to 0.5.
00066 
00067 A simple rounding heuristic is used.
00068 
00069 Any cut generators based on Cgl can be added in same way
00070 
00071 You may also wish to look at SbbModel.hpp
00072 
00073 
00074 ************************************************************************/
00075 
00076 
00077 int main (int argc, const char *argv[])
00078 {
00079 
00080   // Define your favorite OsiSolver
00081   
00082 #ifdef COIN_USE_CLP
00083   ClpSimplex simplex;
00084 #endif
00085   double time0 = cpuTime();
00086   double time1 = time0;
00087   double time2;
00088 
00089   // Read in model using argv[1]
00090   // and assert that it is a clean model
00091 
00092   assert(!simplex.readMps(argv[1],""));
00093   time2 = cpuTime();
00094   std::cout<<"Input took "<<time2-time1<<" seconds"<<std::endl;;
00095   time1 = time2;
00096   // Should work with OsiPresolve but not sure - so this is complicated
00097   ClpPresolve pinfo;
00098   ClpSimplex * simplex2 = pinfo.presolvedModel(simplex,1.0e-8);
00099   time2 = cpuTime();
00100   std::cout<<"Presolve took "<<time2-time1<<" seconds"<<std::endl;;
00101   time1 = time2;
00102   OsiClpSolverInterface solver1(simplex2);
00103   solver1.writeMps("bad2");
00104   // Do initial solve to continuous
00105   solver1.initialSolve();
00106   time2 = cpuTime();
00107   std::cout<<"Continuous solve took "<<time2-time1<<" seconds"<<std::endl;;
00108   time1 = time2;
00109   solver1.messageHandler()->setLogLevel(0);
00110   SbbModel model(solver1);
00111   // Definition of node choice
00112   SbbCompareUser compare;
00113   model.setNodeComparison(compare);
00114 
00115   // Maybe probing due to very large coefficients
00116 
00117   CglProbing generator1;
00118   generator1.setUsingObjective(true);
00119   generator1.setMaxPass(3);
00120   generator1.setMaxProbe(100);
00121   generator1.setMaxLook(50);
00122   generator1.setRowCuts(3);
00123 
00124   
00125   // Add in generators
00126   // model.addCutGenerator(&generator1,-1,"Probing");
00127   // Switch off strong branching if wanted
00128   model.setNumberStrong(0);
00129   model.solver()->setIntParam(OsiMaxNumIterationHotStart,100);
00130   //model.solver()->setHintParam(OsiDoScale,false,OsiHintTry);
00131   // Switch off most output
00132   if (model.getNumCols()<3000) {
00133     model.messageHandler()->setLogLevel(1);
00134     model.solver()->messageHandler()->setLogLevel(0);
00135   } else {
00136     model.messageHandler()->setLogLevel(2);
00137     model.solver()->messageHandler()->setLogLevel(1);
00138   }
00139 
00140   // Do complete search
00141   
00142   model.branchAndBound();
00143   time2 = cpuTime();
00144   std::cout<<"Search took "<<time2-time1<<" seconds"<<std::endl;
00145   // as we made such a mess of presolve lets be safe
00146   OsiClpSolverInterface * clpSolver 
00147     = dynamic_cast<OsiClpSolverInterface *> (model.solver());
00148   assert (clpSolver);
00149   ClpSimplex * clp = clpSolver->getModelPtr();
00150   *simplex2 = *clp;
00151   pinfo.postsolve(true);
00152   time1 = time2;
00153   // Fix all integers
00154   const int * original = pinfo.originalColumns();
00155   double * lower2 = simplex2->columnLower();
00156   double * upper2 = simplex2->columnUpper();
00157   const char * info2 = simplex2->integerInformation();
00158   double * lower = simplex.columnLower();
00159   double * upper = simplex.columnUpper();
00160   int i;
00161   for (i=0;i<simplex2->numberColumns();i++) {
00162     if (info2[i]) {
00163       int iSeq = original[i];
00164       upper[iSeq]=upper2[i];
00165       lower[iSeq]=lower2[i];
00166     }
00167   }
00168 
00169   simplex.primal();
00170   time2 = cpuTime();
00171   std::cout<<"Cleanup took "<<time2-time1<<" seconds"<<std::endl;;
00172   std::cout<<"Total time "<<time2-time0<<" seconds"<<std::endl;;
00173   return 0;
00174 }    

Generated on Wed Dec 3 14:36:18 2003 for Sbb by doxygen 1.3.5