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