/home/coin/SVN-release/OS-2.4.1/Couenne/src/problem/reformulate.cpp

Go to the documentation of this file.
00001 /* $Id: reformulate.cpp 698 2011-06-20 13:36:43Z pbelotti $
00002  *
00003  * Name:    reformulate.cpp
00004  * Author:  Pietro Belotti
00005  * Purpose: apply reformulation
00006  *
00007  * This file is licensed under the Eclipse Public License (EPL)
00008  */
00009 
00010 #include <vector>
00011 
00012 #include "CoinHelperFunctions.hpp"
00013 #include "CoinTime.hpp"
00014 
00015 #include "BonBabSetupBase.hpp"
00016 
00017 #include "CouenneTypes.hpp"
00018 
00019 #include "CouenneExprVar.hpp"
00020 
00021 #include "CouenneProblem.hpp"
00022 #include "CouenneDepGraph.hpp"
00023 #include "CouenneLQelems.hpp"
00024 
00025 #include "CouenneRecordBestSol.hpp"
00026 
00027 #define THRESHOLD_OUTPUT_REFORMULATE 1000
00028 
00029 using namespace Couenne;
00030 
00032 void CouenneProblem::reformulate (CouenneCutGenerator *cg) {
00033   
00034   double now = CoinCpuTime ();
00035 
00036   if (nVars () > THRESHOLD_OUTPUT_REFORMULATE) {
00037     jnlst_ -> Printf (Ipopt::J_ERROR, J_COUENNE, "Reformulating problem: "); 
00038     fflush (stdout);
00039   }
00040 
00041   if (domain_.current () == NULL) {
00042 
00043     // create room for problem's variables and bounds, if no domain exists
00044     CouNumber 
00045       *x  = (CouNumber *) malloc (nVars() * sizeof (CouNumber)),
00046       *lb = (CouNumber *) malloc (nVars() * sizeof (CouNumber)),
00047       *ub = (CouNumber *) malloc (nVars() * sizeof (CouNumber));
00048 
00049     for (int i = nVars(); i--;) {
00050       x  [i] =  0.;
00051       lb [i] = -COUENNE_INFINITY;
00052       ub [i] =  COUENNE_INFINITY;
00053     }
00054 
00055     domain_.push (nVars (), x, lb, ub);
00056   }
00057 
00058   // link initial variables to problem's domain
00059   for (std::vector <exprVar *>::iterator i = variables_.begin ();
00060        i != variables_.end (); ++i)
00061     (*i) -> linkDomain (&domain_);
00062 
00063   if (jnlst_ -> ProduceOutput(Ipopt::J_SUMMARY, J_PROBLEM))
00064     print (std::cout);
00065 
00066   // save -- for statistic purposes -- number of original
00067   // constraints. Some of them will be deleted as definition of
00068   // auxiliary variables.
00069   nOrigCons_    = constraints_. size ();
00070   nOrigIntVars_ = nIntVars ();
00071 
00072   jnlst_->Printf (Ipopt::J_ERROR, J_PROBLEM,
00073                   "Problem size before reformulation: %d variables (%d integer), %d constraints.\n",
00074                   nOrigVars_, nOrigIntVars_, nOrigCons_);
00075 
00076   // reformulation
00077   if (!standardize ()) { // problem is infeasible if standardize returns false
00078 
00079     jnlst_->Printf(Ipopt::J_ERROR, J_COUENNE,
00080                    "Problem infeasible after reformulation\n");
00081     // fake infeasible bounds for Couenne to bail out
00082     for (int i = nVars (); i--;)
00083       Ub (i) = - (Lb (i) = 1.);
00084 
00085     return;
00086   }
00087 
00088   // clear all spurious variables pointers not referring to the variables_ vector
00089   realign ();
00090 
00091   // give a value to all auxiliary variables. Do it now to be able to
00092   // recognize complementarity constraints in fillDependence()
00093   initAuxs ();
00094 
00095   bool *isInt = new bool[nVars()];
00096   for(int i=0; i<nVars(); i++) {
00097     if(variables_[i]->isInteger()) {
00098       isInt[i] = true;
00099     }
00100     else {
00101       isInt[i] = false;
00102     }
00103   }
00104   recBSol->setInitIsInt(isInt, nVars());
00105   recBSol->setInitDomLb(domain()->lb(), nVars());
00106   recBSol->setInitDomUb(domain()->ub(), nVars());
00107   delete[] isInt;
00108 
00109   CouNumber cutoff;
00110   // check for initial solution given to Couenne. If feasible, set cutoff
00111 
00112 #ifdef FM_CHECKNLP2
00113   cutoff = X (objectives_ [0] -> Body () -> Index ());
00114   if(checkNLP2(X(), cutoff, false, // do not care about obj value
00115                true, // stop at first viol 
00116                false, // checkAll
00117                getFeasTol())) {
00118     
00119     jnlst_ -> Printf (Ipopt::J_ERROR, J_PROBLEM,
00120                       "Couenne: initial solution (value %g) is MINLP feasible\n",
00121                       cutoff);
00122 
00123 #ifdef FM_TRACE_OPTSOL
00124     getRecordBestSol()->update();
00125     setCutOff(getRecordBestSol()->getVal());
00126 #else /* not FM_TRACE_OPTSOL */
00127 
00128 #ifdef FM_UP_BND
00129     setCutOff(getRecordBestSol()->getModSolVal());
00130 #else
00131     setCutOff(getRecordBestSol()->getModSolVal(), 
00132               getRecordBestSol()->getModSol(nVars()));
00133 #endif
00134 #endif /* not FM_TRACE_OPTSOL */
00135 
00136   }
00137 #else /* not FM_CHECKNLP2 */
00138   if (checkNLP (X (), cutoff = X (objectives_ [0] -> Body () -> Index ()), true)) {
00139     jnlst_ -> Printf (Ipopt::J_ERROR, J_PROBLEM,
00140                       "Couenne: initial solution (value %g) is MINLP feasible\n",
00141                       cutoff);
00142 
00143 #ifdef FM_TRACE_OPTSOL
00144     getRecordBestSol()->update(X(), nVars(), cutoff, getFeasTol());
00145     setCutOff(getRecordBestSol()->getVal());
00146 #else /* not FM_TRACE_OPTSOL */
00147 
00148 #ifdef FM_UP_BND
00149     setCutOff (cutoff);
00150 #else
00151     setCutOff (cutoff, X ());    
00152 #endif
00153 #endif /* not FM_TRACE_OPTSOL */
00154 
00155   }
00156 #endif /* not FM_CHECKNLP2 */
00157  
00158   // fill dependence_ structure
00159   fillDependence (bonBase_, cg);
00160 
00161   // quadratic handling
00162   fillQuadIndices ();
00163 
00164   // if ((now = (CoinCpuTime () - now)) > 10.)
00165   //   jnlst_->Printf(Ipopt::J_ERROR, J_PROBLEM,
00166   //   "reformulation time %.3fs\n", now);
00167 
00168   jnlst_->Printf (Ipopt::J_WARNING, J_PROBLEM, "Initializing auxiliaries\n");
00169 
00170   // give a value to all auxiliary variables
00171   initAuxs ();
00172 
00173   int nActualVars = nIntVars_ = 0;
00174 
00175   // check how many integer variables we have now (including aux)
00176   for (int i=0; i<nVars(); i++)
00177     if (variables_ [i] -> Multiplicity () > 0) {
00178 
00179       nActualVars++;
00180       if (variables_ [i] -> isDefinedInteger ())
00181         nIntVars_++;
00182     }
00183 
00184   jnlst_->Printf(Ipopt::J_ERROR, J_PROBLEM,
00185                   "Problem size after  reformulation: %d variables (%d integer), %d constraints.\n",
00186                   nActualVars, nIntVars_, nCons());
00187 
00188   // check if optimal solution is available (for debug purposes)
00189   readOptimum ();
00190 
00191   if (bonBase_) {
00192 
00193     CouNumber 
00194       art_cutoff =  COIN_DBL_MAX,
00195       art_lower  = -COIN_DBL_MAX;
00196 
00197     bonBase_ -> options() -> GetNumericValue ("art_cutoff", art_cutoff, "couenne.");
00198     bonBase_ -> options() -> GetNumericValue ("art_lower",  art_lower,  "couenne.");
00199 
00200     if (art_cutoff <  1.e50) setCutOff (art_cutoff);
00201     if (art_lower  > -1.e50) {
00202       int indobj = objectives_ [0] -> Body () -> Index ();
00203       if (indobj >= 0)
00204         domain_.lb (indobj) = art_lower;
00205     }
00206   }
00207 
00208   if (jnlst_->ProduceOutput(Ipopt::J_DETAILED, J_PROBLEM)) {
00209     // We should route that also through the journalist
00210     print (std::cout);
00211   }
00212 
00213   createUnusedOriginals ();
00214 
00215   if (nOrigVars_  > THRESHOLD_OUTPUT_REFORMULATE)
00216     jnlst_ -> Printf (Ipopt::J_ERROR, J_COUENNE, "%.1f seconds\n", CoinCpuTime () - now); 
00217   else if (nVars () > 2*THRESHOLD_OUTPUT_REFORMULATE) 
00218     jnlst_ -> Printf (Ipopt::J_ERROR, J_COUENNE, "Reformulation: %.1f seconds\n", CoinCpuTime () - now); 
00219 
00220   if (orbitalBranching_) {
00221 
00222     jnlst_ -> Printf (Ipopt::J_ERROR, J_COUENNE, "Setting up symmetry groups\n"); 
00223     setupSymmetry ();
00224   }
00225 
00226   //writeAMPL ("extended-aw.mod", true);
00227   //writeAMPL ("original.mod", false);
00228 }

Generated on Thu Nov 10 03:05:46 2011 by  doxygen 1.4.7