00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include <vector>
00013
00014 #include "CoinHelperFunctions.hpp"
00015
00016 #include "CouenneTypes.hpp"
00017 #include "expression.hpp"
00018 #include "exprIVar.hpp"
00019 #include "exprClone.hpp"
00020 #include "CouenneProblem.hpp"
00021 #include "CouenneProblemElem.hpp"
00022 #include "depGraph.hpp"
00023
00024
00025
00027
00028 bool CouenneProblem::standardize () {
00029
00030 #ifdef DEBUG
00031 printf ("START: current point: %d vars -------------------\n",
00032 domain_.current () -> Dimension ());
00033 for (int i=0; i<domain_.current () -> Dimension (); i++)
00034 printf ("%3d %20g [%20g %20g]\n", i, domain_.x (i), domain_.lb (i), domain_.ub (i));
00035 #endif
00036
00037 bool retval = true;
00038
00039
00040
00041 graph_ = new DepGraph;
00042
00043 for (std::vector <exprVar *>::iterator i = variables_ . begin ();
00044 i != variables_ . end (); ++i)
00045 graph_ -> insert (*i);
00046
00047
00048
00049 int initVar = variables_ . size () - commonexprs_ . size ();
00050
00051
00052
00053
00054
00055
00056 #ifdef DEBUG
00057 if (commonexprs_.size ()) printf ("%d common exprs, initVar = %d = %d - %d\n",
00058 commonexprs_.size (),
00059 initVar,
00060 variables_ . size (),
00061 commonexprs_ . size ());
00062 #endif
00063
00064 for (std::vector <expression *>::iterator i = commonexprs_ . begin ();
00065 i != commonexprs_ . end (); ++i) {
00066
00067 #ifdef DEBUG
00068 printf ("-- stdz common expr [%d] :=", initVar); fflush (stdout);
00069 (*i) -> print (); printf ("\n"); fflush (stdout);
00070 #endif
00071
00072 exprAux *naux = (*i) -> standardize (this, false);
00073
00074 expression *img = naux -> Image ();
00075
00076
00077
00078
00079
00080 exprAux *newvar = new exprAux (img, initVar, 1 + img -> rank (), exprAux::Unset, &domain_);
00081
00082
00083 auxiliarize (newvar);
00084
00085 graph_ -> insert (newvar);
00086 graph_ -> erase (naux);
00087
00088
00089
00090 #ifdef DEBUG
00091 if (naux) {
00092 printf ("done: "); fflush (stdout);
00093 naux -> print ();
00094 printf (" := "); fflush (stdout);
00095 naux -> Image () -> print (); printf ("\n..."); fflush (stdout);
00096 } else if (*i) {
00097 (*i) -> print ();
00098
00099
00100 printf ("\n");
00101 } else printf ("[n]aux NULL!\n");
00102 #endif
00103
00104 initVar++;
00105 }
00106
00107
00108
00109 for (std::vector <CouenneObjective *>::iterator i = objectives_.begin ();
00110 i != objectives_.end (); ++i) {
00111
00112 #ifdef DEBUG
00113 printf ("Objective [code: %d]", (*i) -> Body () -> code ()); (*i) -> print ();
00114 #endif
00115
00116 exprAux *aux = (*i) -> standardize (this);
00117
00118 #ifdef DEBUG
00119 printf (" --> "); (*i) -> print ();
00120 if (aux) {printf (" -- aux is "); aux -> print (); printf ("\n");}
00121 #endif
00122
00123 if (aux) {
00124
00125 (*i) -> Body (new exprClone (aux));
00126 }
00127
00128 #ifdef DEBUG
00129 printf (" --> "); (*i) -> print (); printf ("...................\n");
00130 #endif
00131 }
00132
00133
00134
00135
00136
00137 commuted_ = new bool [nVars ()];
00138 for (int i = nVars (); i--;)
00139 *commuted_++ = false;
00140 commuted_ -= nVars ();
00141
00142
00143 std::vector <std::vector <CouenneConstraint *>::iterator> iters2erase;
00144
00145
00146
00147 for (std::vector <CouenneConstraint *>::iterator i = constraints_.begin ();
00148 i != constraints_.end (); ++i) {
00149
00150 #ifdef DEBUG
00151 printf ("############# Constraint ");
00152 (*i) -> print ();
00153 #endif
00154
00155 exprAux *aux = (*i) -> standardize (this);
00156
00157 #ifdef DEBUG
00158 printf (" ==> [%d] ", aux ? (aux -> Index ()) : -1);
00159 (*i) -> print ();
00160 #endif
00161
00162 if (aux) {
00163
00164
00165
00166
00167 aux -> top_level () = true;
00168
00169
00170
00171
00172 (*i) -> Body (new exprClone (aux));
00173
00174 }
00175 else {
00176 CouNumber lb, ub;
00177 (*i) -> Body () -> getBounds (lb, ub);
00178 if ((((*((*i) -> Lb ())) ()) > ub) ||
00179 (((*((*i) -> Ub ())) ()) < lb)) {
00180 jnlst_ -> Printf (J_SUMMARY, J_PROBLEM, "found infeasible constraint [%g,%g]\n", lb, ub);
00181 #ifdef DEBUG
00182 (*i) -> print ();
00183 #endif
00184 retval = false;
00185 }
00186 iters2erase.push_back (i);
00187 }
00188
00189
00190
00191 #ifdef DEBUG
00192 printf (" --> ");
00193 (*i) -> print ();
00194 printf ("..............................................................\n");
00195
00196 #endif
00197
00198
00199
00200
00201 }
00202
00203 for (unsigned int i = iters2erase.size (); i--;)
00204 constraints_. erase (iters2erase [i]);
00205
00206 #ifdef DEBUG
00207
00208 printf ("done with standardization: (careful, bounds below can be nonsense)\n");
00209 print ();
00210 #endif
00211
00212
00213
00214 delete auxSet_;
00215
00216
00217 domain_.current () -> resize (nVars ());
00218
00219
00220 graph_ -> createOrder ();
00221
00222
00223 assert (graph_ -> checkCycles () == false);
00224
00225
00226
00227 int n = nVars ();
00228 numbering_ = new int [n];
00229 std::set <DepNode *, compNode> vertices = graph_ -> Vertices ();
00230
00231 for (std::set <DepNode *, compNode>::iterator i = vertices.begin ();
00232 i != vertices.end (); ++i)
00233
00234 numbering_ [(*i) -> Order ()] = (*i) -> Index ();
00235
00237
00238 for (int i = 0; i < nVars (); i++) {
00239
00240 int ord = numbering_ [i];
00241
00242 if (variables_ [ord] -> Type () == AUX) {
00243
00244
00245
00246
00247 if (variables_ [ord] -> Index () >= nOrigVars_) {
00248
00249 domain_.lb (ord) = -COIN_DBL_MAX;
00250 domain_.ub (ord) = COIN_DBL_MAX;
00251 }
00252
00253
00254
00255
00256 variables_ [ord] -> crossBounds ();
00257
00258
00259
00260 #ifdef DEBUG
00261 printf (":::: %3d %10g [%10g, %10g]",
00262 ord, domain_.x (ord), domain_.lb (ord), domain_.ub (ord));
00263 #endif
00264
00265
00266 domain_.x (ord) = (*(variables_ [ord] -> Image ())) ();
00267 domain_.lb (ord) = (*(variables_ [ord] -> Lb ())) ();
00268 domain_.ub (ord) = (*(variables_ [ord] -> Ub ())) ();
00269
00270 #ifdef DEBUG
00271 printf (" --> %10g [%10g, %10g] [",
00272 domain_.x (ord), domain_.lb (ord), domain_.ub (ord));
00273 variables_ [ord] -> Lb () -> print (); printf (",");
00274 variables_ [ord] -> Ub () -> print (); printf ("]\n");
00275 #endif
00276
00277 bool integer = variables_ [ord] -> isInteger ();
00278
00279 if (integer) {
00280 domain_.lb (ord) = ceil (domain_.lb (ord) - COUENNE_EPS);
00281 domain_.ub (ord) = floor (domain_.ub (ord) + COUENNE_EPS);
00282 }
00283 }
00284 }
00285
00286
00287
00288 std::string delete_redund;
00289 if (bonBase_)
00290 bonBase_ -> options () -> GetStringValue ("delete_redundant", delete_redund, "couenne.");
00291 else
00292 delete_redund = "yes";
00293
00294 if (delete_redund == "yes")
00295
00296
00297 for (std::vector <exprVar *>::iterator i = variables_.begin ();
00298 i != variables_.end (); ++i)
00299
00300 if ((*i) -> Type () == AUX) {
00301
00302 int type = (*i) -> Image () -> Type ();
00303
00304 if ((type == VAR) || (type == AUX)) {
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318 int
00319 indStays = (*i) -> Image () -> Index (),
00320 indLeaves = (*i) -> Index ();
00321
00322 if (indStays == indLeaves)
00323 continue;
00324
00325
00326
00327
00328
00329
00330 exprVar
00331 *varStays = variables_ [indStays],
00332 *varLeaves = variables_ [indLeaves];
00333
00334
00335
00336 varStays -> lb () = varLeaves -> lb () = CoinMax (varStays -> lb (), varLeaves -> lb ());
00337 varStays -> ub () = varLeaves -> ub () = CoinMin (varStays -> ub (), varLeaves -> ub ());
00338
00339 if (varStays -> isInteger () ||
00340 varLeaves -> isInteger ()) {
00341
00342 varStays -> lb () = ceil (varStays -> lb ());
00343 varStays -> ub () = floor (varStays -> ub ());
00344
00345 if (varStays -> Type () == AUX)
00346 varStays -> setInteger (true);
00347 else {
00348
00349 variables_ [indStays] = varStays = new exprIVar (indStays, &domain_);
00350 auxiliarize (varStays);
00351
00352 }
00353 }
00354
00355 auxiliarize (varLeaves, varStays);
00356
00357
00358 varLeaves -> zeroMult ();
00359 }
00360 }
00361
00367 for (int ii=0; ii < nVars (); ii++) {
00368
00369 int i = numbering_ [ii];
00370
00371 if ((Var (i) -> Multiplicity () > 0) &&
00372 (Var (i) -> Type () == AUX) &&
00373 (Var (i) -> Image () -> isInteger ()))
00374 Var (i) -> setInteger (true);
00375
00376
00377
00378 }
00379
00380
00381
00382 delete [] commuted_; commuted_ = NULL;
00383 delete graph_; graph_ = NULL;
00384
00385 return retval;
00386 }