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 cutoff = X (objectives_ [0] -> Body () -> Index ());
00114 if(checkNLP2(X(), cutoff, false,
00115 true,
00116 false,
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
00127
00128 #ifdef FM_UP_BND
00129 setCutOff(getRecordBestSol()->getModSolVal());
00130 #else
00131 setCutOff(getRecordBestSol()->getModSolVal(),
00132 getRecordBestSol()->getModSol(nVars()));
00133 #endif
00134 #endif
00135
00136 }
00137 #else
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
00147
00148 #ifdef FM_UP_BND
00149 setCutOff (cutoff);
00150 #else
00151 setCutOff (cutoff, X ());
00152 #endif
00153 #endif
00154
00155 }
00156 #endif
00157
00158
00159 fillDependence (bonBase_, cg);
00160
00161
00162 fillQuadIndices ();
00163
00164
00165
00166
00167
00168 jnlst_->Printf (Ipopt::J_WARNING, J_PROBLEM, "Initializing auxiliaries\n");
00169
00170
00171 initAuxs ();
00172
00173 int nActualVars = nIntVars_ = 0;
00174
00175
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
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
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
00227
00228 }