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
00148 for (std::vector <CouenneConstraint *>::iterator i = constraints_.begin ();
00149 i != constraints_.end (); ++i) {
00150
00151 #ifdef DEBUG
00152 printf ("############# Constraint ");
00153 (*i) -> print ();
00154 #endif
00155
00156 exprAux *aux = (*i) -> standardize (this);
00157
00158 #ifdef DEBUG
00159 printf (" ==> [%d] ", aux ? (aux -> Index ()) : -1);
00160 (*i) -> print ();
00161 #endif
00162
00163 if (aux) {
00164
00165 (*i) -> Body (new exprClone (aux));
00166
00167 }
00168 else {
00169 CouNumber lb, ub;
00170 (*i) -> Body () -> getBounds (lb, ub);
00171 if ((((*((*i) -> Lb ())) ()) > ub) ||
00172 (((*((*i) -> Ub ())) ()) < lb)) {
00173 printf ("found infeasible constraint [%g,%g]\n", lb, ub);
00174 (*i) -> print ();
00175 retval = false;
00176 }
00177 iters2erase.push_back (i);
00178 }
00179
00180
00181
00182 #ifdef DEBUG
00183 printf (" --> ");
00184 (*i) -> print ();
00185 printf ("..............................................................\n");
00186
00187 #endif
00188
00189
00190
00191
00192 }
00193
00194 for (unsigned int i = iters2erase.size (); i--;)
00195 constraints_. erase (iters2erase [i]);
00196
00197 #ifdef DEBUG
00198
00199 printf ("done with standardization: (careful, bounds below can be nonsense)\n");
00200 print ();
00201 #endif
00202
00203
00204
00205 delete auxSet_;
00206
00207
00208 domain_.current () -> resize (nVars ());
00209
00210
00211 graph_ -> createOrder ();
00212
00213
00214 assert (graph_ -> checkCycles () == false);
00215
00216
00217
00218 int n = nVars ();
00219 numbering_ = new int [n];
00220 std::set <DepNode *, compNode> vertices = graph_ -> Vertices ();
00221
00222 for (std::set <DepNode *, compNode>::iterator i = vertices.begin ();
00223 i != vertices.end (); ++i)
00224
00225 numbering_ [(*i) -> Order ()] = (*i) -> Index ();
00226
00228
00229 for (int i = 0; i < nVars (); i++) {
00230
00231 int ord = numbering_ [i];
00232
00233 if (variables_ [ord] -> Type () == AUX) {
00234
00235
00236
00237
00238 if (variables_ [ord] -> Index () >= nOrigVars_) {
00239
00240 domain_.lb (ord) = -COIN_DBL_MAX;
00241 domain_.ub (ord) = COIN_DBL_MAX;
00242 }
00243
00244
00245
00246
00247 variables_ [ord] -> crossBounds ();
00248
00249
00250
00251 #ifdef DEBUG
00252 printf (":::: %3d %10g [%10g, %10g]",
00253 ord, domain_.x (ord), domain_.lb (ord), domain_.ub (ord));
00254 #endif
00255
00256
00257 domain_.x (ord) = (*(variables_ [ord] -> Image ())) ();
00258 domain_.lb (ord) = (*(variables_ [ord] -> Lb ())) ();
00259 domain_.ub (ord) = (*(variables_ [ord] -> Ub ())) ();
00260
00261 #ifdef DEBUG
00262 printf (" --> %10g [%10g, %10g] [",
00263 domain_.x (ord), domain_.lb (ord), domain_.ub (ord));
00264 variables_ [ord] -> Lb () -> print (); printf (",");
00265 variables_ [ord] -> Ub () -> print (); printf ("]\n");
00266 #endif
00267
00268 bool integer = variables_ [ord] -> isInteger ();
00269
00270 if (integer) {
00271 domain_.lb (ord) = ceil (domain_.lb (ord) - COUENNE_EPS);
00272 domain_.ub (ord) = floor (domain_.ub (ord) + COUENNE_EPS);
00273 }
00274 }
00275 }
00276
00277
00278
00279 std::string delete_redund;
00280 if (bonBase_)
00281 bonBase_ -> options () -> GetStringValue ("delete_redundant", delete_redund, "couenne.");
00282 else
00283 delete_redund = "yes";
00284
00285 if (delete_redund == "yes")
00286
00287
00288 for (std::vector <exprVar *>::iterator i = variables_.begin ();
00289 i != variables_.end (); ++i)
00290
00291 if ((*i) -> Type () == AUX) {
00292
00293 int type = (*i) -> Image () -> Type ();
00294
00295 if ((type == VAR) || (type == AUX)) {
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309 int
00310 indStays = (*i) -> Image () -> Index (),
00311 indLeaves = (*i) -> Index ();
00312
00313 if (indStays == indLeaves)
00314 continue;
00315
00316
00317
00318
00319
00320
00321 exprVar
00322 *varStays = variables_ [indStays],
00323 *varLeaves = variables_ [indLeaves];
00324
00325
00326
00327 varStays -> lb () = varLeaves -> lb () = CoinMax (varStays -> lb (), varLeaves -> lb ());
00328 varStays -> ub () = varLeaves -> ub () = CoinMin (varStays -> ub (), varLeaves -> ub ());
00329
00330 if (varStays -> isInteger () ||
00331 varLeaves -> isInteger ()) {
00332
00333 varStays -> lb () = ceil (varStays -> lb ());
00334 varStays -> ub () = floor (varStays -> ub ());
00335
00336 if (varStays -> Type () == AUX)
00337 varStays -> setInteger (true);
00338 else {
00339
00340 variables_ [indStays] = varStays = new exprIVar (indStays, &domain_);
00341 auxiliarize (varStays);
00342
00343 }
00344 }
00345
00346 auxiliarize (varLeaves, varStays);
00347
00348
00349 varLeaves -> zeroMult ();
00350 }
00351 }
00352
00358 for (int ii=0; ii < nVars (); ii++) {
00359
00360 int i = numbering_ [ii];
00361
00362 if ((Var (i) -> Multiplicity () > 0) &&
00363 (Var (i) -> Type () == AUX) &&
00364 (Var (i) -> Image () -> isInteger ()))
00365 Var (i) -> setInteger (true);
00366
00367
00368
00369 }
00370
00371
00372
00373 delete [] commuted_; commuted_ = NULL;
00374 delete graph_; graph_ = NULL;
00375
00376 return retval;
00377 }