00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "CouenneCutGenerator.hpp"
00012 #include "CouenneProblem.hpp"
00013
00014 #include "CouenneTypes.hpp"
00015 #include "expression.hpp"
00016 #include "exprClone.hpp"
00017 #include "exprAux.hpp"
00018 #include "exprOp.hpp"
00019 #include "exprUnary.hpp"
00020 #include "exprStore.hpp"
00021
00022
00023
00024 expression *expression::differentiate (int)
00025 {return new exprConst (0.);}
00026
00027
00028
00029 void expression::getBounds (expression *&lb, expression *&ub) {
00030
00031 lb = new exprConst (- COIN_DBL_MAX);
00032 ub = new exprConst ( COIN_DBL_MAX);
00033 }
00034
00035
00037 void expression::getBounds (CouNumber &lb, CouNumber &ub) {
00038
00039 expression *le, *ue;
00040 getBounds (le, ue);
00041
00042 lb = (*le) ();
00043 ub = (*ue) ();
00044
00045 delete le;
00046 delete ue;
00047 }
00048
00049
00050
00051 void exprConst::generateCuts (expression *w,
00052 OsiCuts &cs, const CouenneCutGenerator *cg,
00053 t_chg_bounds *chg, int,
00054 CouNumber, CouNumber) {
00055 if (cg -> isFirst ())
00056 cg -> createCut (cs, value_, 0, w -> Index (), 1.);
00057 }
00058
00059
00061 int expression::compare (expression &e1) {
00062
00063 register int c0 = code (),
00064 c1 = e1. code ();
00065
00066 if (c0 < c1) return -1;
00067 else if (c0 > c1) return 1;
00068
00069
00070
00071 if (c0 >= COU_EXPRUNARY) {
00072
00073 exprUnary *ne0 = dynamic_cast <exprUnary *> (this);
00074 exprUnary *ne1 = dynamic_cast <exprUnary *> (&e1);
00075
00076 return ne0 -> compare (*ne1);
00077 }
00078
00079 if (c0 >= COU_EXPROP) {
00080
00081 exprOp *ne0 = dynamic_cast <exprOp *> (this);
00082 exprOp *ne1 = dynamic_cast <exprOp *> (&e1);
00083
00084 return ne0 -> compare (*ne1);
00085 }
00086
00087
00088
00089 {
00090 register int
00091 i0 = Index (),
00092 i1 = e1. Index ();
00093
00094 if (i0 < i1) return -1;
00095 if (i0 > i1) return 1;
00096 if (i0 >= 0) return 0;
00097 }
00098
00099
00100 {
00101 register CouNumber
00102 v0 = Value (),
00103 v1 = e1. Value ();
00104
00105 if (v0 < v1) return -1;
00106 if (v0 > v1) return 1;
00107 }
00108
00109 return 0;
00110 }
00111
00112
00114 exprCopy::exprCopy (const exprCopy &e, Domain *d) {
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127 copy_ = e.copy_ -> Original () -> clone (d);
00128
00129
00130 value_ = e.value_;
00131 }
00132
00133
00135 int expression::compare (exprCopy &c)
00136 {return compare (const_cast <expression &> (*(c. Original ())));}
00137
00138
00140 void exprCopy::replace (exprVar *orig, exprVar *aux) {
00141
00142 if (!aux)
00143 aux = orig;
00144
00145 enum nodeType copyType = copy_ -> Type ();
00146
00147 if ((copyType == VAR) ||
00148 (copyType == AUX)) {
00149
00150 if (copy_ -> Index () == orig -> Index ()) {
00151 if (copy_ -> isaCopy ())
00152 delete copy_;
00153 copy_ = aux;
00154 }
00155
00156 } else copy_ -> replace (orig, aux);
00157
00158
00159
00160
00161
00162
00163
00164 }
00165
00166
00169 int expression::dependsOn (int *ind, int n, enum dig_type type) {
00170
00171 std::set <int>
00172 indlist (ind, ind + n),
00173 deplist,
00174 intersectn;
00175
00176
00177
00178
00179
00180
00181 DepList (deplist, type);
00182
00183
00184
00185
00186
00187 std::set_intersection (indlist .begin (), indlist .end (),
00188 deplist .begin (), deplist .end (),
00189 std::inserter (intersectn, intersectn.begin ()));
00190
00191
00192
00193
00194
00195 return intersectn.size();
00196 }
00197
00198
00200 void exprCopy::realign (const CouenneProblem *p) {
00201
00202 if (((copy_ -> Type () == VAR) ||
00203 (copy_ -> Type () == AUX)) &&
00204 (copy_ -> Original () != p -> Var (copy_ -> Index ()))) {
00205
00206
00207
00208
00209
00210
00211 expression *trash = copy_;
00212
00213 copy_ = p -> Var (copy_ -> Index ());
00214 delete trash;
00215 }
00216 }
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00236 void expression::closestFeasible (expression *varind, expression *vardep,
00237 CouNumber& left, CouNumber& right) const
00238 {
00239 assert(isBijective());
00240 CouNumber inv = inverse(vardep);
00241 CouNumber curr = (*varind) ();
00242 if (curr > inv) {
00243 left = inv;
00244 right = curr;
00245 }
00246 else {
00247 left = curr;
00248 right = inv;
00249 }
00250 }