00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "CouenneProblemElem.hpp"
00012 #include "CouenneProblem.hpp"
00013
00014 #include "exprClone.hpp"
00015 #include "exprAux.hpp"
00016 #include "exprIVar.hpp"
00017 #include "depGraph.hpp"
00018
00019
00020
00021
00022 void replace (CouenneProblem *p, int wind, int xind);
00023
00024
00026 exprAux *CouenneConstraint::standardize (CouenneProblem *p) {
00027
00028
00029
00030
00031
00032
00033
00034
00035 #ifdef DEBUG
00036 printf ("################################\nStandardizing constraint: "); print ();
00037
00038 printf (" ["); fflush (stdout); lb_ -> print ();
00039 printf (","); fflush (stdout); ub_ -> print (); fflush (stdout);
00040
00041
00042
00043
00044
00045
00046 printf ("]\n");
00047 #endif
00048
00049 if (compareExpr (&lb_, &ub_) == 0) {
00050
00051
00052
00053
00054 expression *rest;
00055
00056
00057 int wind = p -> splitAux ((*lb_) (), body_, rest, p -> Commuted ());
00058
00059 if (wind >= 0) {
00060
00061
00062
00063 expression *restSimple = rest -> simplify ();
00064
00065 if (restSimple) {
00066 delete rest;
00067 rest = restSimple;
00068 }
00069
00070
00071
00072
00073 if (rest -> code () == COU_EXPRCONST) {
00074
00075 p -> Var (wind) -> lb () =
00076 p -> Var (wind) -> ub () = rest -> Value ();
00077
00078 delete rest;
00079 return NULL;
00080 }
00081
00082
00083
00084
00085
00086 p -> Commuted () [wind] = true;
00087
00088 #ifdef DEBUG
00089 printf ("---> %d & ", wind); fflush (stdout);
00090 rest -> print (); printf ("\n");
00091 #endif
00092
00093 assert (p -> Var (wind) -> Type () == VAR);
00094
00095
00096
00097
00098 int xind = rest -> Index ();
00099
00100 if (xind >= 0) {
00101
00102
00103 exprAux *w = new exprAux (new exprClone (p -> Var (xind)), wind, 1 + p -> Var (xind) -> rank (),
00104 p -> Var (wind) -> isInteger () ?
00105 exprAux::Integer : exprAux::Continuous,
00106 p -> domain ());
00107 p -> auxiliarize (w);
00108 w -> zeroMult ();
00109
00110 replace (p, wind, xind);
00111
00112 p -> auxiliarize (p -> Var (wind), p -> Var (xind));
00113
00114
00115
00116
00117
00118
00119
00120
00121 } else {
00122
00123
00124 exprAux *w = new exprAux (rest, wind, 1 + rest -> rank (),
00125 p -> Var (wind) -> isInteger () ?
00126 exprAux::Integer : exprAux::Continuous,
00127 p -> domain ());
00128
00129 std::set <exprAux *, compExpr>::iterator i = p -> AuxSet () -> find (w);
00130
00131
00132 if (i == p -> AuxSet () -> end ()) {
00133
00134 p -> AuxSet () -> insert (w);
00135 p -> getDepGraph () -> insert (w);
00136
00137 #ifdef DEBUG
00138 printf ("now replacing x [%d] with ", wind); fflush (stdout);
00139 w -> print (); printf (" := ");
00140 w -> Image () -> print (); printf ("\n");
00141 #endif
00142
00143
00144
00145 p -> auxiliarize (w);
00146 }
00147
00148 else {
00149
00150 #ifdef DEBUG
00151 printf ("found aux occurrence of "); fflush (stdout);
00152 w -> print (); printf (" := ");
00153 w -> Image () -> print (); printf (" ... ");
00154 (*i) -> print (); printf (" := ");
00155 (*i) -> Image () -> print (); printf ("\n");
00156 #endif
00157
00158
00159
00160
00161
00162
00163
00164
00165 int xind = (*i) -> Index (), iMax, iMin;
00166
00167 if (xind < wind) {
00168 iMax = wind;
00169 iMin = xind;
00170 } else {
00171 iMax = xind;
00172 iMin = wind;
00173 }
00174
00175 replace (p, iMax, iMin);
00176
00177 p -> auxiliarize (p -> Var (iMax), p -> Var (iMin));
00178 p -> Var (iMax) -> zeroMult ();
00179 p -> auxiliarize (w);
00180 }
00181 }
00182
00183 return NULL;
00184 }
00185 }
00186
00187 #ifdef DEBUG
00188 printf ("\nnormal\n-----------------\n");
00189 #endif
00190
00191 return body_ -> standardize (p);
00192 }
00193
00194
00195
00196 void replace (CouenneProblem *p, int wind, int xind) {
00197
00198 exprVar
00199 *varLeaves = p -> Variables () [wind],
00200 *varStays = p -> Variables () [xind];
00201
00202
00203
00204 varStays -> lb () = varLeaves -> lb () = CoinMax (varStays -> lb (), varLeaves -> lb ());
00205 varStays -> ub () = varLeaves -> ub () = CoinMin (varStays -> ub (), varLeaves -> ub ());
00206
00207 if (varStays -> isInteger () ||
00208 varLeaves -> isInteger ()) {
00209
00210 varStays -> lb () = ceil (varStays -> lb ());
00211 varStays -> ub () = floor (varStays -> ub ());
00212
00213 if (varStays -> Type () == AUX)
00214 varStays -> setInteger (true);
00215 else {
00216
00217 p -> Variables () [xind] = varStays = new exprIVar (xind, p -> domain ());
00218 p -> auxiliarize (varStays);
00219
00220 }
00221 }
00222 }