FLOPC++
|
00001 // ******************** FlopCpp ********************************************** 00002 // File: MP_expression.cpp 00003 // $Id$ 00004 // Author: Tim Helge Hultberg (thh@mat.ua.pt) 00005 // Copyright (C) 2003 Tim Helge Hultberg 00006 // All Rights Reserved. 00007 //**************************************************************************** 00008 00009 #include <sstream> 00010 #include "MP_expression.hpp" 00011 #include "MP_constant.hpp" 00012 #include "MP_boolean.hpp" 00013 #include "MP_constraint.hpp" 00014 #include "MP_set.hpp" 00015 #include "MP_variable.hpp" 00016 #include "MP_model.hpp" 00017 #include <OsiSolverInterface.hpp> 00018 00019 namespace flopc { 00020 00021 VariableRef::VariableRef(MP_variable* v, 00022 const MP_index_exp& i1, 00023 const MP_index_exp& i2, 00024 const MP_index_exp& i3, 00025 const MP_index_exp& i4, 00026 const MP_index_exp& i5) : 00027 V(v),I1(i1),I2(i2),I3(i3),I4(i4),I5(i5) { 00028 offset = v->offset; 00029 } 00030 00031 double VariableRef::level() const { 00032 return V->M->Solver->getColSolution()[V->offset + 00033 V->f(V->S1->evaluate(), 00034 V->S2->evaluate(), 00035 V->S3->evaluate(), 00036 V->S4->evaluate(), 00037 V->S5->evaluate())]; 00038 } 00039 00040 int VariableRef::getColumn() const { 00041 int i1 = V->S1->check(I1->evaluate()); 00042 int i2 = V->S2->check(I2->evaluate()); 00043 int i3 = V->S3->check(I3->evaluate()); 00044 int i4 = V->S4->check(I4->evaluate()); 00045 int i5 = V->S5->check(I5->evaluate()); 00046 00047 if (i1==outOfBound || i2==outOfBound || i3==outOfBound || 00048 i4==outOfBound || i5==outOfBound) { 00049 return outOfBound; 00050 } else { 00051 return V->offset + V->f(i1,i2,i3,i4,i5); 00052 } 00053 } 00054 00055 void VariableRef::generate(const MP_domain& domain, 00056 vector<Constant > multiplicators, 00057 MP::GenerateFunctor& f, 00058 double m) const { 00059 f.setMultiplicator(multiplicators,m); 00060 f.setTerminalExpression(this); 00061 domain.forall(&f); 00062 } 00063 00064 class Expression_constant : public TerminalExpression, public MP { 00065 friend class MP_expression; 00066 private: 00067 Expression_constant(const Constant& c) : C(c) {} 00068 double level() const { 00069 return C->evaluate(); 00070 } 00071 double getValue() const { 00072 return C->evaluate(); 00073 } 00074 int getColumn() const { 00075 return -1; 00076 } 00077 int getStage() const { 00078 return C->getStage(); //NB to be changed 00079 } 00080 void generate(const MP_domain& domain, 00081 vector<Constant> multiplicators, 00082 MP::GenerateFunctor& f, 00083 double m) const { 00084 f.setMultiplicator(multiplicators,m); 00085 f.setTerminalExpression(this); 00086 domain.forall(&f); 00087 } 00088 void insertVariables(set<MP_variable*>& v) const {} 00089 00090 Constant C; 00091 }; 00092 00093 00094 class Expression_operator : public MP_expression_base, public MP { 00095 protected: 00096 Expression_operator(const MP_expression& e1, const MP_expression& e2) : 00097 left(e1),right(e2) {} 00098 00099 void insertVariables(set<MP_variable*>& v) const { 00100 left->insertVariables(v); 00101 right->insertVariables(v); 00102 } 00103 00104 MP_expression left,right; 00105 }; 00106 00107 class Expression_plus : public Expression_operator { 00108 friend MP_expression operator+(const MP_expression& e1, const MP_expression& e2); 00109 friend MP_expression operator+(const MP_expression& e1, const Constant& e2); 00110 friend MP_expression operator+(const Constant& e1, const MP_expression& e2); 00111 private: 00112 Expression_plus(const MP_expression& e1, const MP_expression& e2) : 00113 Expression_operator(e1,e2) {} 00114 double level() const { 00115 return left->level()+right->level(); 00116 } 00117 void generate(const MP_domain& domain, 00118 vector<Constant> multiplicators, 00119 MP::GenerateFunctor& f, 00120 double m) const { 00121 left->generate(domain, multiplicators, f, m); 00122 right->generate(domain, multiplicators, f, m); 00123 } 00124 }; 00125 00126 class Expression_minus : public Expression_operator { 00127 friend MP_expression operator-(const MP_expression& e1, const MP_expression& e2); 00128 friend MP_expression operator-(const MP_expression& e1, const Constant& e2); 00129 friend MP_expression operator-(const Constant& e1, const MP_expression& e2); 00130 private: 00131 Expression_minus(const MP_expression& e1, const MP_expression& e2) : 00132 Expression_operator(e1,e2) {} 00133 double level() const { 00134 return left->level()-right->level(); 00135 } 00136 void generate(const MP_domain& domain, 00137 vector<Constant> multiplicators, 00138 MP::GenerateFunctor& f, 00139 double m) const { 00140 left->generate(domain, multiplicators, f, m); 00141 right->generate(domain, multiplicators, f, -m); 00142 } 00143 }; 00144 00145 class Expression_mult : public MP_expression_base, MP { 00146 friend MP_expression operator*(const Constant& e1, const MP_expression& e2); 00147 friend MP_expression operator*(const MP_expression& e1, const Constant& e2); 00148 00149 private: 00150 Expression_mult(const Constant& e1, const MP_expression& e2) : 00151 left(e1), right(e2) {} 00152 double level() const { 00153 return left->evaluate()*right->level(); 00154 } 00155 void generate(const MP_domain& domain, 00156 vector<Constant> multiplicators, 00157 MP::GenerateFunctor& f, 00158 double m) const { 00159 multiplicators.push_back(left); 00160 right->generate(domain, multiplicators, f, m); 00161 } 00162 void insertVariables(set<MP_variable*>& v) const { 00163 right->insertVariables(v); 00164 } 00165 Constant left; 00166 MP_expression right; 00167 }; 00168 00169 class Expression_div : public MP_expression_base, MP { 00170 friend MP_expression operator/(const MP_expression& e1, const Constant& e2); 00171 private: 00172 Expression_div(const MP_expression& e, const Constant& c) : 00173 left(e), right(c) {} 00174 double level() const { 00175 return left->level()/right->evaluate(); 00176 } 00177 void generate(const MP_domain& domain, 00178 vector<Constant> multiplicators, 00179 MP::GenerateFunctor& f, 00180 double m) const { 00181 multiplicators.push_back(1/right); 00182 left->generate(domain, multiplicators, f, m); 00183 } 00184 void insertVariables(set<MP_variable*>& v) const { 00185 left->insertVariables(v); 00186 } 00187 MP_expression left; 00188 Constant right; 00189 }; 00190 00191 class Expression_sum : public MP_expression_base, public MP { 00192 friend MP_expression sum(const MP_domain& d, const MP_expression& e); 00193 private: 00194 Expression_sum(const MP_domain& d, const MP_expression& e) : D(d), exp(e) {} 00195 00196 double level() const { 00197 SumFunctor SF(exp); 00198 D.forall(SF); 00199 return SF.the_sum; 00200 } 00201 void generate(const MP_domain& domain, 00202 vector<Constant> multiplicators, 00203 MP::GenerateFunctor& f, 00204 double m) const { 00205 // The order, D*domain (NOT domain*D), is important for efficiency! 00206 exp->generate(D*domain, multiplicators, f, m); 00207 } 00208 void insertVariables(set<MP_variable*>& v) const { 00209 exp->insertVariables(v); 00210 } 00211 00212 class SumFunctor : public Functor { 00213 public: 00214 SumFunctor(MP_expression exp) : E(exp), the_sum(0) {} 00215 void operator()() const { 00216 the_sum += E->level(); 00217 } 00218 MP_expression E; 00219 mutable double the_sum; 00220 }; 00221 00222 MP_domain D; 00223 MP_expression exp; 00224 }; 00225 00226 00227 MP_expression operator+(const MP_expression& e1, const MP_expression& e2) { 00228 return new Expression_plus(e1, e2); 00229 } 00230 MP_expression operator+(const MP_expression& e1, const Constant& e2) { 00231 return new Expression_plus(e1, e2); 00232 } 00233 MP_expression operator+(const Constant& e1, const MP_expression& e2) { 00234 return new Expression_plus(e1, e2); 00235 } 00236 00237 MP_expression operator-(const MP_expression& e1, const MP_expression& e2) { 00238 return new Expression_minus(e1, e2); 00239 } 00240 MP_expression operator-(const MP_expression& e1, const Constant& e2) { 00241 return new Expression_minus(e1, e2); 00242 } 00243 MP_expression operator-(const Constant& e1, const MP_expression& e2) { 00244 return new Expression_minus(e1, e2); 00245 } 00246 00247 MP_expression operator*(const Constant& e1, const MP_expression& e2) { 00248 return new Expression_mult(e1, e2); 00249 } 00250 MP_expression operator*(const MP_expression& e1, const Constant& e2) { 00251 return new Expression_mult(e2, e1); 00252 } 00253 00254 MP_expression operator/(const MP_expression& e1, const Constant& e2) { 00255 return new Expression_div(e1, e2); 00256 } 00257 00258 MP_expression sum(const MP_domain& d, const MP_expression& e) { 00259 return new Expression_sum(d, e); 00260 } 00261 00262 } // End of namespace flopc 00263 00264 using namespace flopc; 00265 00266 00267 MP_expression::MP_expression(const Constant &c) : 00268 Handle<MP_expression_base*>(new Expression_constant(c)) {} 00269 00270 MP_expression::MP_expression(const VariableRef &v) : 00271 Handle<MP_expression_base*>(const_cast<VariableRef*>(&v)) {} 00272 00273 00274 bool MP::CoefLess::operator() (const MP::Coef& a, const MP::Coef& b) const { 00275 if (a.col < b.col) { 00276 return true; 00277 } else if (a.col == b.col && a.row < b.row) { 00278 return true; 00279 } else { 00280 return false; 00281 } 00282 } 00283 00284 void MP::GenerateFunctor::operator()() const { 00285 double multiplicator = M; 00286 int stage = 0; 00287 for (unsigned int i=0; i<multiplicators.size(); i++) { 00288 multiplicator *= multiplicators[i]->evaluate(); 00289 if (multiplicators[i]->getStage() > stage) { 00290 stage = multiplicators[i]->getStage(); 00291 } 00292 } 00293 int rowNumber = -1; 00294 if (R != 0) { 00295 rowNumber = R->row_number(); 00296 } 00297 if (rowNumber != outOfBound) { 00298 int colNumber = C->getColumn(); 00299 if ( colNumber != outOfBound ) { 00300 double val = multiplicator*C->getValue(); 00301 int tstage = C->getStage(); 00302 if (tstage > stage) { 00303 stage = tstage; 00304 } 00305 // if (val != 0) { 00306 Coefs.push_back(MP::Coef(colNumber, rowNumber, val, stage)); 00307 //} 00308 } 00309 } 00310 }