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

useVolume.cpp

00001 // Copyright (C) 2003, International Business Machines
00002 // Corporation and others.  All Rights Reserved.
00003 
00004 #include "ClpSimplex.hpp"
00005 #include "ClpFactorization.hpp"
00006 #include "VolVolume.hpp"
00007 
00008 //#############################################################################
00009 
00010 class lpHook : public VOL_user_hooks {
00011 private:
00012    lpHook(const lpHook&);
00013    lpHook& operator=(const lpHook&);
00014 private:
00016    double  *colupper_;
00018    double  *collower_;
00020    double  *objcoeffs_;
00022    double  *rhs_;
00024    char    *sense_;
00025 
00027    CoinPackedMatrix rowMatrix_;
00029    CoinPackedMatrix colMatrix_;
00030 
00031 public:
00032    lpHook(const double* clb, const double* cub, const double* obj,
00033           const double* rhs, const char* sense, const CoinPackedMatrix& mat);
00034    virtual ~lpHook();
00035    
00036 public:
00037    // for all hooks: return value of -1 means that volume should quit
00042    virtual int compute_rc(const VOL_dvector& u, VOL_dvector& rc);
00043 
00052    virtual int solve_subproblem(const VOL_dvector& dual, const VOL_dvector& rc,
00053                                 double& lcost, VOL_dvector& x, VOL_dvector& v,
00054                                 double& pcost);
00061    virtual int heuristics(const VOL_problem& p, 
00062                           const VOL_dvector& x, double& heur_val) {
00063       return 0;
00064    }
00065 };
00066  
00067 //#############################################################################
00068 
00069 lpHook::lpHook(const double* clb, const double* cub, const double* obj,
00070                const double* rhs, const char* sense,
00071                const CoinPackedMatrix& mat)
00072 {
00073    const int colnum = mat.getNumCols();
00074    const int rownum = mat.getNumRows();
00075 
00076    colupper_ = new double[colnum];
00077    collower_ = new double[colnum];
00078    objcoeffs_ = new double[colnum];
00079    rhs_ = new double[rownum];
00080    sense_ = new char[rownum];
00081 
00082    std::copy(clb, clb + colnum, collower_);
00083    std::copy(cub, cub + colnum, colupper_);
00084    std::copy(obj, obj + colnum, objcoeffs_);
00085    std::copy(rhs, rhs + rownum, rhs_);
00086    std::copy(sense, sense + rownum, sense_);
00087 
00088    if (mat.isColOrdered()) {
00089       colMatrix_.copyOf(mat);
00090       rowMatrix_.reverseOrderedCopyOf(mat);
00091    } else {
00092       rowMatrix_.copyOf(mat);
00093       colMatrix_.reverseOrderedCopyOf(mat);
00094    }
00095 }
00096 
00097 //-----------------------------------------------------------------------------
00098 
00099 lpHook::~lpHook()
00100 {
00101    delete[] colupper_;
00102    delete[] collower_;
00103    delete[] objcoeffs_;
00104    delete[] rhs_;
00105    delete[] sense_;
00106 }
00107 
00108 //#############################################################################
00109 
00110 int
00111 lpHook::compute_rc(const VOL_dvector& u, VOL_dvector& rc)
00112 {
00113    rowMatrix_.transposeTimes(u.v, rc.v);
00114    const int psize = rowMatrix_.getNumCols();
00115 
00116    for (int i = 0; i < psize; ++i)
00117       rc[i] = objcoeffs_[i] - rc[i];
00118    return 0;
00119 }
00120 
00121 //-----------------------------------------------------------------------------
00122 
00123 int
00124 lpHook::solve_subproblem(const VOL_dvector& dual, const VOL_dvector& rc,
00125                          double& lcost, VOL_dvector& x, VOL_dvector& v,
00126                          double& pcost)
00127 {
00128    int i;
00129    const int psize = x.size();
00130    const int dsize = v.size();
00131 
00132    // compute the lagrangean solution corresponding to the reduced costs
00133    for (i = 0; i < psize; ++i)
00134       x[i] = (rc[i] >= 0.0) ? collower_[i] : colupper_[i];
00135 
00136    // compute the lagrangean value (rhs*dual + primal*rc)
00137    lcost = 0;
00138    for (i = 0; i < dsize; ++i)
00139       lcost += rhs_[i] * dual[i];
00140    for (i = 0; i < psize; ++i)
00141       lcost += x[i] * rc[i];
00142 
00143    // compute the rhs - lhs 
00144    colMatrix_.times(x.v, v.v);
00145    for (i = 0; i < dsize; ++i)
00146       v[i] = rhs_[i] - v[i];
00147 
00148    // compute the lagrangean primal objective
00149    pcost = 0;
00150    for (i = 0; i < psize; ++i)
00151       pcost += x[i] * objcoeffs_[i];
00152 
00153    return 0;
00154 }
00155 
00156 //#############################################################################
00157 
00158 int main (int argc, const char *argv[])
00159 {
00160   ClpSimplex  model;
00161   int status;
00162 
00163   if (argc<2)
00164     status=model.readMps("../../Mps/Sample/p0033.mps",true);
00165   else
00166     status=model.readMps(argv[1],true);
00167   /*
00168     This driver uses volume algorithm
00169     then does dual - after adjusting costs
00170     then solves real problem
00171   */
00172 
00173   // do volume for a bit
00174   VOL_problem volprob;
00175   const CoinPackedMatrix* mat = model.matrix();
00176   const int psize = mat->getNumCols();
00177   const int dsize = mat->getNumRows();
00178   char * sense = new char[dsize];
00179   double * rhs = new double[dsize];
00180   const double * rowLower = model.rowLower();
00181   const double * rowUpper = model.rowUpper();
00182   // Set the lb/ub on the duals
00183   volprob.dsize = dsize;
00184   volprob.psize = psize;
00185   volprob.dual_lb.allocate(dsize);
00186   volprob.dual_ub.allocate(dsize);
00187   volprob.dsol.allocate(dsize);
00188   int i;
00189   for (i = 0; i < dsize; ++i) {
00190     if (rowUpper[i]==rowLower[i]) {
00191     // 'E':
00192       volprob.dual_lb[i] = -1.0e31;
00193       volprob.dual_ub[i] = 1.0e31;
00194       rhs[i]=rowUpper[i];
00195       sense[i]='E';
00196     } else if (rowLower[i]<-0.99e10&&rowUpper[i]<0.99e10) {
00197       // 'L':
00198       volprob.dual_lb[i] = -1.0e31;
00199       volprob.dual_ub[i] = 0.0;
00200       rhs[i]=rowUpper[i];
00201       sense[i]='L';
00202     } else if (rowLower[i]>-0.99e10&&rowUpper[i]>0.99e10) {
00203       // 'G':
00204       volprob.dual_lb[i] = 0.0;
00205       volprob.dual_ub[i] = 1.0e31;
00206       rhs[i]=rowLower[i];
00207       sense[i]='G';
00208     } else {
00209       printf("Volume Algorithm can't work if there is a non ELG row\n");
00210       abort();
00211     }
00212   }
00213   // Can't use read_param as private
00214   // anyway I want automatic use - so maybe this is problem
00215 #if 0
00216   FILE* infile = fopen("parameters", "r");
00217   if (!infile) {
00218     printf("Failure to open parameter file\n");
00219   } else {
00220     volprob.read_params("parameters");
00221   }
00222 #endif
00223 #if 0
00224   // should save and restore bounds
00225   model.tightenPrimalBounds();
00226 #else
00227   double * colUpper = model.columnUpper();
00228   for (i=0;i<psize;i++)
00229     colUpper[i]=1.0;
00230 #endif
00231   lpHook myHook(model.getColLower(), model.getColUpper(),
00232                 model.getObjCoefficients(),
00233                 rhs, sense, *mat);
00234   // move duals
00235   double * pi = model.dualRowSolution();
00236   memcpy(volprob.dsol.v,pi,dsize*sizeof(double));
00237   volprob.solve(myHook,  false /* not warmstart */);
00238   // For now stop as not doing any good
00239   exit(77);
00240   // create objectives
00241   int numberRows = model.numberRows();
00242   int numberColumns = model.numberColumns();
00243   memcpy(pi,volprob.dsol.v,numberRows*sizeof(double));
00244 #define MODIFYCOSTS
00245 #ifdef MODIFYCOSTS
00246   double * saveObj = new double[numberColumns];
00247   memcpy(saveObj,model.objective(),numberColumns*sizeof(double));
00248   memcpy(model.dualColumnSolution(),model.objective(),
00249          numberColumns*sizeof(double));
00250   model.clpMatrix()->transposeTimes(-1.0,pi,model.dualColumnSolution());
00251   memcpy(model.objective(),model.dualColumnSolution(),
00252          numberColumns*sizeof(double));
00253   const double * rowsol = model.primalRowSolution();
00254   //const double * rowLower = model.rowLower();
00255   //const double * rowUpper = model.rowUpper();
00256   double offset=0.0;
00257   for (i=0;i<numberRows;i++) {
00258     offset += pi[i]*rowsol[i];
00259   }
00260   double value2;
00261   model.getDblParam(ClpObjOffset,value2);
00262   printf("Offset %g %g\n",offset,value2);
00263   model.setRowObjective(pi);
00264   // zero out pi
00265   memset(pi,0,numberRows*sizeof(double));
00266 #endif
00267   // Could put some in basis - only partially tested
00268   model.allSlackBasis(); 
00269   model.factorization()->maximumPivots(1000);
00270   //model.setLogLevel(63);
00271   // solve
00272   model.dual(1);
00273   //model.primal(1);
00274 #ifdef MODIFYCOSTS
00275   memcpy(model.objective(),saveObj,numberColumns*sizeof(double));
00276   // zero out pi
00277   memset(pi,0,numberRows*sizeof(double));
00278   model.setRowObjective(pi);
00279   delete [] saveObj;
00280   model.primal();
00281 #endif
00282   
00283   return 0;
00284 }    

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