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
00104
00105 if (rest -> code () == COU_EXPRCONST) {
00106
00107 CouNumber constRHS = rest -> Value ();
00108
00109 if (aSign != expression::AUX_LEQ) p -> Var (wind) -> lb () = constRHS;
00110 if (aSign != expression::AUX_GEQ) p -> Var (wind) -> ub () = constRHS;
00111
00112
00113 return NULL;
00114 }
00115
00116
00117
00118
00119
00120 p -> Commuted () [wind] = true;
00121
00122 if (p -> Jnlst () -> ProduceOutput (Ipopt::J_ALL, J_REFORMULATE)) {
00123 printf ("---> %d & ", wind); fflush (stdout);
00124 rest -> print (); printf ("[sign: %d]\n", aSign);
00125 }
00126
00127 assert (p -> Var (wind) -> Type () == VAR);
00128
00129 int xind = rest -> Index ();
00130
00131
00132
00133
00134 if ((xind >= 0) && (aSign == expression::AUX_EQ)) {
00135
00136
00137 exprAux *w = new exprAux (new exprClone (p -> Var (xind)), wind, 1 + p -> Var (xind) -> rank (),
00138 p -> Var (wind) -> isInteger () ?
00139 exprAux::Integer : exprAux::Continuous,
00140 p -> domain (), aSign);
00141 p -> auxiliarize (w);
00142 w -> zeroMult ();
00143
00144 replace (p, wind, xind);
00145
00146 p -> auxiliarize (p -> Var (wind), p -> Var (xind));
00147
00148
00149 } else {
00150
00151
00152 exprAux *w = new exprAux (rest, wind, 1 + rest -> rank (),
00153 ((p -> Var (wind) -> isInteger ()) ||
00154 (false && (rest -> isInteger ()) && (aSign == expression::AUX_EQ))) ?
00155 exprAux::Integer : exprAux::Continuous,
00156 p -> domain (), aSign);
00157
00158 if (p -> Jnlst () -> ProduceOutput (Ipopt::J_ALL, J_REFORMULATE)) {
00159 printf ("AuxSet:\n");
00160 for (std::set <exprAux *, compExpr>::iterator i = p -> AuxSet () -> begin ();
00161 i != p -> AuxSet () -> end (); ++i)
00162 if ((*i) -> Image () == NULL) {
00163 (*i) -> print (); printf (" does not have an image!!!\n");
00164 } else {
00165 printf ("-- "); (*i) -> print (); printf (" := ");
00166 (*i) -> Image () -> print (); printf ("\n");
00167 }
00168 }
00169
00170 std::set <exprAux *, compExpr>::iterator i = p -> AuxSet () -> end ();
00171
00172 if (aSign == expression::AUX_EQ)
00173 i = p -> AuxSet () -> find (w);
00174
00175
00176 if ((i == p -> AuxSet () -> end ()) || (aSign != expression::AUX_EQ)) {
00177
00178 p -> AuxSet () -> insert (w);
00179 p -> getDepGraph () -> insert (w);
00180
00181 if (p -> Jnlst () -> ProduceOutput (Ipopt::J_ALL, J_REFORMULATE)) {
00182 printf ("now replacing x [%d] with ", wind); fflush (stdout);
00183 w -> print (); printf (" := ");
00184 w -> Image () -> print (); printf ("\n");
00185 }
00186
00187
00188
00189 p -> auxiliarize (w);
00190 }
00191
00192 else {
00193
00194 if (p -> Jnlst () -> ProduceOutput (Ipopt::J_ALL, J_REFORMULATE)) {
00195 printf ("found aux occurrence of "); fflush (stdout);
00196 w -> print (); printf (" := ");
00197 w -> Image () -> print (); printf (" ... ");
00198 (*i) -> print (); printf (" := ");
00199 (*i) -> Image () -> print (); printf ("\n");
00200 }
00201
00202
00203
00204
00205
00206
00207
00208
00209 int xind = (*i) -> Index (), iMax, iMin;
00210
00211 if (xind < wind) {
00212 iMax = wind;
00213 iMin = xind;
00214 } else {
00215 iMax = xind;
00216 iMin = wind;
00217 }
00218
00219 replace (p, iMax, iMin);
00220
00221 p -> auxiliarize (p -> Var (iMax), p -> Var (iMin));
00222 p -> Var (iMax) -> zeroMult ();
00223 p -> auxiliarize (w);
00224 }
00225 }
00226
00227 return NULL;
00228 }
00229 }
00230
00231 if (p -> Jnlst () -> ProduceOutput (Ipopt::J_ALL, J_REFORMULATE))
00232 printf ("\nnormal\n-----------------\n");
00233
00234
00235
00236
00237
00238 return body_ -> standardize (p);
00239 }
00240
00241
00242
00243 void replace (CouenneProblem *p, int wind, int xind) {
00244
00245 exprVar
00246 *varLeaves = p -> Variables () [wind],
00247 *varStays = p -> Variables () [xind];
00248
00249
00250
00251 varStays -> lb () = varLeaves -> lb () = CoinMax (varStays -> lb (), varLeaves -> lb ());
00252 varStays -> ub () = varLeaves -> ub () = CoinMin (varStays -> ub (), varLeaves -> ub ());
00253
00254 if (varStays -> isInteger () ||
00255 varLeaves -> isInteger ()) {
00256
00257 varStays -> lb () = ceil (varStays -> lb ());
00258 varStays -> ub () = floor (varStays -> ub ());
00259
00260 if (varStays -> Type () == AUX)
00261 varStays -> setInteger (true);
00262 else {
00263
00264 p -> Variables () [xind] = varStays = new exprIVar (xind, p -> domain ());
00265 p -> auxiliarize (varStays);
00266
00267 }
00268 }
00269 }