00001
00002
00003
00004
00005
00006
00007
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
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
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
00067
00068
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
00077 if (!standardize ()) {
00078
00079 jnlst_->Printf(Ipopt::J_ERROR, J_COUENNE,
00080 "Problem infeasible after reformulation\n");
00081
00082 for (int i = nVars (); i--;)
00083 Ub (i) = - (Lb (i) = 1.);
00084
00085 return;
00086 }
00087
00088
00089 realign ();
00090
00091
00092
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
00111
00112 #ifdef FM_CHECKNLP2
00113 int objind = objectives_ [0] -> Body () -> Index ();
00114 cutoff = objind >= 0 ? X (objind) : objectives_ [0] -> Body () -> Value ();
00115 if(checkNLP2(X(), cutoff, false,
00116 true,
00117 true,
00118 getFeasTol())) {
00119
00120 jnlst_ -> Printf (Ipopt::J_ERROR, J_PROBLEM,
00121 "Couenne: initial solution (value %g) is MINLP feasible\n",
00122 cutoff);
00123
00124 #ifdef FM_TRACE_OPTSOL
00125 getRecordBestSol()->update();
00126 setCutOff(getRecordBestSol()->getVal());
00127 #else
00128
00129 #ifdef FM_UP_BND
00130 setCutOff(getRecordBestSol()->getModSolVal());
00131 #else
00132 setCutOff(getRecordBestSol()->getModSolVal(),
00133 getRecordBestSol()->getModSol(nVars()));
00134 #endif
00135 #endif
00136
00137 }
00138 #else
00139 if (checkNLP (X (), cutoff = X (objectives_ [0] -> Body () -> Index ()), true)) {
00140 jnlst_ -> Printf (Ipopt::J_ERROR, J_PROBLEM,
00141 "Couenne: initial solution (value %g) is MINLP feasible\n",
00142 cutoff);
00143
00144 #ifdef FM_TRACE_OPTSOL
00145 getRecordBestSol()->update(X(), nVars(), cutoff, getFeasTol());
00146 setCutOff(getRecordBestSol()->getVal());
00147 #else
00148
00149 #ifdef FM_UP_BND
00150 setCutOff (cutoff);
00151 #else
00152 setCutOff (cutoff, X ());
00153 #endif
00154 #endif
00155
00156 }
00157 #endif
00158
00159
00160 fillDependence (bonBase_, cg);
00161
00162
00163 fillQuadIndices ();
00164
00165
00166
00167
00168
00169 jnlst_->Printf (Ipopt::J_WARNING, J_PROBLEM, "Initializing auxiliaries\n");
00170
00171
00172 initAuxs ();
00173
00174 int nActualVars = nIntVars_ = 0;
00175
00176
00177 for (int i=0; i<nVars(); i++)
00178 if (variables_ [i] -> Multiplicity () > 0) {
00179
00180 nActualVars++;
00181 if (variables_ [i] -> isDefinedInteger ())
00182 nIntVars_++;
00183 }
00184
00185 jnlst_->Printf(Ipopt::J_ERROR, J_PROBLEM,
00186 "Problem size after reformulation: %d variables (%d integer), %d constraints.\n",
00187 nActualVars, nIntVars_, nCons());
00188
00189
00190 readOptimum ();
00191
00192 if (bonBase_) {
00193
00194 CouNumber
00195 art_cutoff = COIN_DBL_MAX,
00196 art_lower = -COIN_DBL_MAX;
00197
00198 bonBase_ -> options() -> GetNumericValue ("art_cutoff", art_cutoff, "couenne.");
00199 bonBase_ -> options() -> GetNumericValue ("art_lower", art_lower, "couenne.");
00200
00201 if (art_cutoff < 1.e50) setCutOff (art_cutoff);
00202 if (art_lower > -1.e50) {
00203 int indobj = objectives_ [0] -> Body () -> Index ();
00204 if (indobj >= 0)
00205 domain_.lb (indobj) = art_lower;
00206 }
00207 }
00208
00209 if (jnlst_->ProduceOutput(Ipopt::J_DETAILED, J_PROBLEM)) {
00210
00211 print (std::cout);
00212 }
00213
00214 createUnusedOriginals ();
00215
00216 if (nOrigVars_ > THRESHOLD_OUTPUT_REFORMULATE)
00217 jnlst_ -> Printf (Ipopt::J_ERROR, J_COUENNE, "%.1f seconds\n", CoinCpuTime () - now);
00218 else if (nVars () > 2*THRESHOLD_OUTPUT_REFORMULATE)
00219 jnlst_ -> Printf (Ipopt::J_ERROR, J_COUENNE, "Reformulation: %.1f seconds\n", CoinCpuTime () - now);
00220
00221 if (orbitalBranching_) {
00222
00223 jnlst_ -> Printf (Ipopt::J_ERROR, J_COUENNE, "Setting up symmetry groups\n");
00224 setupSymmetry ();
00225 }
00226
00227
00228
00229 }