00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "CoinHelperFunctions.hpp"
00012
00013 #include "BonBabSetupBase.hpp"
00014
00015 #include "CouenneProblemElem.hpp"
00016 #include "CouenneProblem.hpp"
00017
00018 #include "CouenneExpression.hpp"
00019 #include "CouenneExprAux.hpp"
00020 #include "CouenneExprClone.hpp"
00021 #include "CouenneExprIVar.hpp"
00022 #include "CouenneDepGraph.hpp"
00023
00024 using namespace Couenne;
00025
00026
00027 void replace (CouenneProblem *p, int wind, int xind);
00028
00029
00031 exprAux *CouenneConstraint::standardize (CouenneProblem *p) {
00032
00033
00034
00035
00036
00037
00038
00039
00040 if (p -> Jnlst () -> ProduceOutput (Ipopt::J_ALL, J_REFORMULATE)) {
00041 printf ("Reformulating constraint: "); print ();
00042 printf (" ["); fflush (stdout); lb_ -> print ();
00043 printf (","); fflush (stdout); ub_ -> print (); fflush (stdout);
00044
00045
00046
00047 printf ("]\n");
00048 }
00049
00050
00051
00052
00053
00054
00055
00056 CouNumber
00057 rLb = (*lb_) (),
00058 rUb = (*ub_) ();
00059
00060 std::string
00061 use_auxcons,
00062 use_semiaux;
00063
00064 p -> bonBase () -> options () -> GetStringValue ("use_auxcons", use_auxcons, "couenne.");
00065 p -> bonBase () -> options () -> GetStringValue ("use_semiaux", use_semiaux, "couenne.");
00066
00067 if (( use_auxcons == "yes") &&
00068 (((use_semiaux == "yes") &&
00069 ((rLb < -COUENNE_INFINITY/2) ||
00070 (rUb > COUENNE_INFINITY/2))) ||
00071 (fabs (rLb-rUb) <= COUENNE_EPS))) {
00072
00073 enum expression::auxSign aSign = expression::AUX_EQ;
00074
00075 if (rLb < -COUENNE_INFINITY/2) aSign = expression::AUX_LEQ;
00076 else if (rUb > COUENNE_INFINITY/2) aSign = expression::AUX_GEQ;
00077
00078 CouNumber rhs = rLb >= -COUENNE_INFINITY/2 ? rLb : rUb;
00079
00080
00081
00082 expression *rest;
00083
00084
00085 int wind = p -> splitAux (rhs, body_, rest, p -> Commuted (), aSign);
00086
00087
00088
00089 if (wind >= 0) {
00090
00091
00092
00093 expression *restSimple = Simplified (rest);
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103 if (rest -> code () == COU_EXPRCONST) {
00104
00105 CouNumber constRHS = rest -> Value ();
00106
00107 if (aSign != expression::AUX_LEQ) p -> Var (wind) -> lb () = constRHS;
00108 if (aSign != expression::AUX_GEQ) p -> Var (wind) -> ub () = constRHS;
00109
00110
00111 return NULL;
00112 }
00113
00114
00115
00116
00117
00118 p -> Commuted () [wind] = true;
00119
00120 if (p -> Jnlst () -> ProduceOutput (Ipopt::J_ALL, J_REFORMULATE)) {
00121 printf ("---> %d & ", wind); fflush (stdout);
00122 rest -> print (); printf ("[sign: %d]\n", aSign);
00123 }
00124
00125 assert (p -> Var (wind) -> Type () == VAR);
00126
00127 int xind = rest -> Index ();
00128
00129
00130
00131
00132 if ((xind >= 0) && (aSign == expression::AUX_EQ)) {
00133
00134
00135 exprAux *w = new exprAux (new exprClone (p -> Var (xind)), wind, 1 + p -> Var (xind) -> rank (),
00136 p -> Var (wind) -> isInteger () ?
00137 exprAux::Integer : exprAux::Continuous,
00138 p -> domain (), aSign);
00139 p -> auxiliarize (w);
00140 w -> zeroMult ();
00141
00142 replace (p, wind, xind);
00143
00144 p -> auxiliarize (p -> Var (wind), p -> Var (xind));
00145
00146
00147 } else {
00148
00149
00150 exprAux *w = new exprAux (rest, wind, 1 + rest -> rank (),
00151 ((p -> Var (wind) -> isInteger ()) ||
00152 (false && (rest -> isInteger ()) && (aSign == expression::AUX_EQ))) ?
00153 exprAux::Integer : exprAux::Continuous,
00154 p -> domain (), aSign);
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168 std::set <exprAux *, compExpr>::iterator i = p -> AuxSet () -> end ();
00169
00170 if (aSign == expression::AUX_EQ)
00171 i = p -> AuxSet () -> find (w);
00172
00173
00174 if ((i == p -> AuxSet () -> end ()) || (aSign != expression::AUX_EQ)) {
00175
00176 p -> AuxSet () -> insert (w);
00177 p -> getDepGraph () -> insert (w);
00178
00179 if (p -> Jnlst () -> ProduceOutput (Ipopt::J_ALL, J_REFORMULATE)) {
00180 printf ("now replacing x [%d] with ", wind); fflush (stdout);
00181 w -> print (); printf (" := ");
00182 w -> Image () -> print (); printf ("\n");
00183 }
00184
00185
00186
00187 p -> auxiliarize (w);
00188 }
00189
00190 else {
00191
00192 if (p -> Jnlst () -> ProduceOutput (Ipopt::J_ALL, J_REFORMULATE)) {
00193 printf ("found aux occurrence of "); fflush (stdout);
00194 w -> print (); printf (" := ");
00195 w -> Image () -> print (); printf (" ... ");
00196 (*i) -> print (); printf (" := ");
00197 (*i) -> Image () -> print (); printf ("\n");
00198 }
00199
00200
00201
00202
00203
00204
00205
00206
00207 int xind = (*i) -> Index (), iMax, iMin;
00208
00209 if (xind < wind) {
00210 iMax = wind;
00211 iMin = xind;
00212 } else {
00213 iMax = xind;
00214 iMin = wind;
00215 }
00216
00217 replace (p, iMax, iMin);
00218
00219 p -> auxiliarize (p -> Var (iMax), p -> Var (iMin));
00220 p -> Var (iMax) -> zeroMult ();
00221 p -> auxiliarize (w);
00222 }
00223 }
00224
00225 return NULL;
00226 }
00227 }
00228
00229 if (p -> Jnlst () -> ProduceOutput (Ipopt::J_ALL, J_REFORMULATE))
00230 printf ("\nnormal\n-----------------\n");
00231
00232
00233
00234
00235
00236 return body_ -> standardize (p);
00237 }
00238
00239
00240
00241 void replace (CouenneProblem *p, int wind, int xind) {
00242
00243 exprVar
00244 *varLeaves = p -> Variables () [wind],
00245 *varStays = p -> Variables () [xind];
00246
00247
00248
00249 varStays -> lb () = varLeaves -> lb () = CoinMax (varStays -> lb (), varLeaves -> lb ());
00250 varStays -> ub () = varLeaves -> ub () = CoinMin (varStays -> ub (), varLeaves -> ub ());
00251
00252 if (varStays -> isInteger () ||
00253 varLeaves -> isInteger ()) {
00254
00255 varStays -> lb () = ceil (varStays -> lb ());
00256 varStays -> ub () = floor (varStays -> ub ());
00257
00258 if (varStays -> Type () == AUX)
00259 varStays -> setInteger (true);
00260 else {
00261
00262 p -> Variables () [xind] = varStays = new exprIVar (xind, p -> domain ());
00263 p -> auxiliarize (varStays);
00264
00265 }
00266 }
00267 }