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

ekk_interface.cpp

00001 #include <cassert>
00002 
00003 #include "ClpSimplexPrimal.hpp"
00004 #include "ClpFactorization.hpp"
00005 #include "ClpPresolve.hpp"
00006 #include "ekk_c_api.h"
00007 //#include "ekk_c_api_undoc.h"
00008  extern "C"{
00009  OSLLIBAPI void * OSLLINKAGE ekk_compressModel(EKKModel * model);
00010   OSLLIBAPI void OSLLINKAGE ekk_decompressModel(EKKModel * model,
00011                                                 void * compressInfo);
00012  }
00013 
00014 static ClpPresolve * presolveInfo=NULL;
00015 
00016 static ClpSimplex * clpmodel(EKKModel * model,int startup)
00017 {
00018   ClpSimplex * clp = new ClpSimplex();;
00019   int numberRows=ekk_getInumrows(model);
00020   int numberColumns= ekk_getInumcols(model);
00021   clp->loadProblem(numberColumns,numberRows,ekk_blockColumn(model,0),
00022                   ekk_blockRow(model,0),ekk_blockElement(model,0),
00023                   ekk_collower(model),ekk_colupper(model),
00024                   ekk_objective(model),
00025                   ekk_rowlower(model),ekk_rowupper(model));
00026   clp->setOptimizationDirection((int) ekk_getRmaxmin(model));
00027   clp->setPrimalTolerance(ekk_getRtolpinf(model));
00028   if (ekk_getRpweight(model)!=0.1)
00029     clp->setInfeasibilityCost(1.0/ekk_getRpweight(model));
00030   clp->setDualTolerance(ekk_getRtoldinf(model));
00031   if (ekk_getRdweight(model)!=0.1)
00032     clp->setDualBound(1.0/ekk_getRdweight(model));
00033   clp->setDblParam(ClpObjOffset,ekk_getRobjectiveOffset(model));
00034   const int * rowStatus =  ekk_rowstat(model);
00035   const double * rowSolution = ekk_rowacts(model);
00036   int i;
00037   clp->createStatus();
00038   double * clpSolution;
00039   clpSolution = clp->primalRowSolution();
00040   memcpy(clpSolution,rowSolution,numberRows*sizeof(double));
00041   const double * rowLower = ekk_rowlower(model);
00042   const double * rowUpper = ekk_rowupper(model);
00043   for (i=0;i<numberRows;i++) {
00044     ClpSimplex::Status status;
00045     if ((rowStatus[i]&0x80000000)!=0) {
00046       status = ClpSimplex::basic;
00047     } else {
00048       if (!startup) {
00049         // believe bits
00050         int ikey = rowStatus[i]&0x60000000;
00051         if (ikey==0x40000000) {
00052           // at ub
00053           status = ClpSimplex::atUpperBound;
00054           clpSolution[i]=rowUpper[i];
00055         } else if (ikey==0x20000000) {
00056           // at lb
00057           status = ClpSimplex::atLowerBound;
00058           clpSolution[i]=rowLower[i];
00059         } else if (ikey==0x60000000) {
00060           // free
00061           status = ClpSimplex::isFree;
00062           clpSolution[i]=0.0;
00063         } else {
00064           // fixed
00065           status = ClpSimplex::atLowerBound;
00066           clpSolution[i]=rowLower[i];
00067         }
00068       } else {
00069         status = ClpSimplex::superBasic;
00070       }
00071     }
00072     clp->setRowStatus(i,status);
00073   }
00074   
00075   const int * columnStatus = ekk_colstat(model);
00076   const double * columnSolution =  ekk_colsol(model);
00077   clpSolution = clp->primalColumnSolution();
00078   memcpy(clpSolution,columnSolution,numberColumns*sizeof(double));
00079   const double * columnLower = ekk_collower(model);
00080   const double * columnUpper = ekk_colupper(model);
00081   for (i=0;i<numberColumns;i++) {
00082     ClpSimplex::Status status;
00083     if ((columnStatus[i]&0x80000000)!=0) {
00084       status = ClpSimplex::basic;
00085     } else {
00086       if (!startup) {
00087         // believe bits
00088         int ikey = columnStatus[i]&0x60000000;
00089         if (ikey==0x40000000) {
00090           // at ub
00091           status = ClpSimplex::atUpperBound;
00092           clpSolution[i]=columnUpper[i];
00093         } else if (ikey==0x20000000) {
00094           // at lb
00095           status = ClpSimplex::atLowerBound;
00096           clpSolution[i]=columnLower[i];
00097         } else if (ikey==0x60000000) {
00098           // free
00099           status = ClpSimplex::isFree;
00100           clpSolution[i]=0.0;
00101         } else {
00102           // fixed
00103           status = ClpSimplex::atLowerBound;
00104           clpSolution[i]=columnLower[i];
00105         }
00106       } else {
00107         status = ClpSimplex::superBasic;
00108       }
00109     }
00110     clp->setColumnStatus(i,status);
00111   }
00112   return clp;
00113 }
00114 
00115 static int solve(EKKModel * model, int  startup,int algorithm,
00116                  int presolve)
00117 {
00118   // values pass or not
00119   if (startup)
00120     startup=1;
00121   // if scaled then be careful
00122   bool scaled = ekk_scaling(model)==1;
00123   if (scaled)
00124     ekk_scaleRim(model,1);
00125   void * compressInfo=NULL;
00126   ClpSimplex * clp;
00127   if (!presolve||!presolveInfo) {
00128     // no presolve or osl presolve - compact columns
00129     compressInfo=ekk_compressModel(model);
00130     clp = clpmodel(model,startup);;
00131   } else {
00132     // pick up clp model
00133     clp = presolveInfo->model();
00134   }
00135     
00136   // don't scale if alreday scaled
00137   if (scaled)
00138     clp->scaling(false);
00139   if (clp->numberRows()>10000)
00140     clp->factorization()->maximumPivots(100+clp->numberRows()/100);
00141   if (algorithm>0)
00142     clp->primal(startup);
00143   else
00144     clp->dual();
00145 
00146   int numberIterations = clp->numberIterations();
00147   if (presolve&&presolveInfo) {
00148     // very wasteful - create a clp copy of osl model
00149     ClpSimplex * clpOriginal = clpmodel(model,0);
00150     presolveInfo->setOriginalModel(clpOriginal);
00151     // do postsolve
00152     presolveInfo->postsolve(true);
00153     delete clp;
00154     delete presolveInfo;
00155     presolveInfo=NULL;
00156     clp = clpOriginal;
00157     if (presolve==3||(presolve==2&&clp->status())) {
00158       printf("Resolving from postsolved model\n");
00159       clp->primal(1);
00160       numberIterations += clp->numberIterations();
00161     }
00162   }
00163 
00164   // put back solution
00165 
00166   double * rowDual = (double *) ekk_rowduals(model);
00167   int numberRows=ekk_getInumrows(model);
00168   int numberColumns= ekk_getInumcols(model);
00169   int * rowStatus =  (int *) ekk_rowstat(model);
00170   double * rowSolution = (double *) ekk_rowacts(model);
00171   int i;
00172   int * columnStatus = (int *) ekk_colstat(model);
00173   double * columnSolution =  (double *) ekk_colsol(model);
00174   memcpy(rowSolution,clp->primalRowSolution(),numberRows*sizeof(double));
00175   memcpy(rowDual,clp->dualRowSolution(),numberRows*sizeof(double));
00176   for (i=0;i<numberRows;i++) {
00177     if (clp->getRowStatus(i)==ClpSimplex::basic)
00178       rowStatus[i]=0x80000000;
00179     else
00180       rowStatus[i]=0;
00181   }
00182   
00183   double * columnDual = (double *) ekk_colrcosts(model);
00184   memcpy(columnSolution,clp->primalColumnSolution(),
00185          numberColumns*sizeof(double));
00186   memcpy(columnDual,clp->dualColumnSolution(),numberColumns*sizeof(double));
00187   for (i=0;i<numberColumns;i++) {
00188     if (clp->getColumnStatus(i)==ClpSimplex::basic)
00189       columnStatus[i]=0x80000000;
00190     else
00191       columnStatus[i]=0;
00192   }
00193   ekk_setIprobstat(model,clp->status());
00194   ekk_setRobjvalue(model,clp->objectiveValue());
00195   ekk_setInumpinf(model,clp->numberPrimalInfeasibilities());
00196   ekk_setInumdinf(model,clp->numberDualInfeasibilities());
00197   ekk_setIiternum(model,numberIterations);
00198   ekk_setRsumpinf(model,clp->sumPrimalInfeasibilities());
00199   ekk_setRsumdinf(model,clp->sumDualInfeasibilities());
00200   delete clp;
00201   if (compressInfo ) 
00202     ekk_decompressModel(model,compressInfo);
00203 
00204   if (scaled)
00205       ekk_scaleRim(model,2);
00206   return 0;
00207 }
00208 /* As ekk_primalSimplex + postsolve instructions:
00209    presolve - 0 , no presolve, 1 presolve but no primal after postsolve,
00210                   2 do primal if any infeasibilities,
00211                   3 always do primal.
00212 */
00213 extern "C" int ekk_primalClp(EKKModel * model, int  startup, int presolve)
00214 {
00215   if (presolveInfo) {
00216     if (!presolve)
00217       presolve=3;
00218     return solve(model,startup,1, presolve);
00219   } else {
00220     return solve(model,startup,1, 0);
00221   }
00222 }
00223 
00224 /* As ekk_dualSimplex + postsolve instructions:
00225    presolve - 0 , no presolve, 1 presolve but no primal after postsolve,
00226                   2 do primal if any infeasibilities,
00227                   3 always do primal.
00228 */
00229 extern "C" int ekk_dualClp(EKKModel * model, int presolve)
00230 {
00231   if (presolveInfo) {
00232     if (!presolve)
00233       presolve=3;
00234     return solve(model,0,-1, presolve);
00235   } else {
00236     return solve(model,0,-1, 0);
00237   }
00238 }
00239 /* rather like ekk_preSolve (3) plus:
00240    keepIntegers - false to treat as if continuous
00241    pass   - do this many passes (0==default(5))
00242 
00243    returns 1 if infeasible
00244 */
00245 extern "C" int ekk_preSolveClp(EKKModel * model, bool keepIntegers,
00246                                int pass)
00247 {
00248   delete presolveInfo;
00249   presolveInfo = new ClpPresolve();
00250   bool scaled = ekk_scaling(model)==1;
00251   if (scaled)
00252       ekk_scaleRim(model,1);
00253   if (!pass)
00254     pass=5;
00255   // very wasteful - create a clp copy of osl model
00256   // 1 to keep solution as is
00257   ClpSimplex * clp = clpmodel(model,1);
00258   // could get round with tailored version of ClpPresolve.cpp
00259   ClpSimplex * newModel = 
00260     presolveInfo->presolvedModel(*clp,
00261                                  ekk_getRtolpinf(model),
00262                                  keepIntegers,pass,true);
00263   delete clp;
00264   presolveInfo->setOriginalModel(NULL);
00265   if (scaled)
00266       ekk_scaleRim(model,2);
00267   if (newModel) {
00268     return 0;
00269   } else {
00270     delete presolveInfo;
00271     presolveInfo=NULL;
00272     return 1;
00273   }
00274 }

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