00001
00002 #include<scil/variable.h>
00003 #include<scil/global.h>
00004 #include<scil/var_obj.h>
00005 #include<scil/cons_obj.h>
00006 #include<scil/aba_variable.h>
00007 #include<scil/aba_constraint.h>
00008 #include<scil/subproblem.h>
00009 #include<scil/ilp_problem.h>
00010 #include<scil/row.h>
00011 #include<scil/primal_heur.h>
00012 #include<scil/constraints/quadref.h>
00013 #include<scil/core/polynomial.h>
00014 #include<scil/core/monomial_inst.h>
00015 #include<scil/core/bool_inst.h>
00016 #include<scil/core/boolfunction.h>
00017 #include <tr1/tuple>
00018 #include<iostream>
00019
00020 using namespace SCIL;
00021
00022 ABA_SUB* ILP_Problem::firstSub() {
00023 myroot=new subproblem(this);
00024
00025 std::list<Coefficient>::const_iterator co;
00026 foreach( co, coeff_list ){
00027 myroot->set_coefficient( tr1::get<0>(*co), tr1::get<1>(*co), tr1::get<2>(*co) );
00028 }
00029
00030 std::list<sym_constraint*>::const_iterator c;
00031 foreach( c, sym_constraints ) {
00032 myroot->add_sym_constraint(*c);
00033 }
00034 return myroot;
00035 };
00036
00037
00038 const
00039 std::string ILP_Problem::configuration(const std::string& s) const {
00040 std::map<std::string,std::string>::const_iterator it = ConfMap.find( s );
00041
00042 if( it==ConfMap.end() )
00043 return "undef";
00044 else
00045 return it->second;
00046 };
00047
00048 void ILP_Problem::configuration(const std::string& s1, const std::string& s2) {
00049 ConfMap[s1] = s2;
00050 return;
00051 };
00052
00053 void ILP_Problem::read_configuration_file(const char* s) {
00054 ifstream ifs(s);
00055 std::cerr << "reading configuration file " << s << endl;
00056
00057 while(ifs.good()) {
00058 std::string s1, s2;
00059 if(ifs.peek()=='#') std::getline(ifs,s2);
00060 else {
00061 if( !ifs.good() )
00062 return;
00063 ifs >> s1;
00064 ifs >> s2;
00065 if( s1.length() > 0 && s2.length() > 0 )
00066 configuration(s1, s2);
00067 }
00068 }
00069 };
00070
00072
00077 ILP_Problem::ILP_Problem (Optsense optSense, bool price, int _numcon, const char* problemName) :
00078 ABA_MASTER (problemName, true, price, (optSense == Optsense_Min ? ABA_OPTSENSE::Min : ABA_OPTSENSE::Max)),numcon(_numcon)
00079 {
00080 ConfMap["undef"] = "undef";
00081
00082 os = optSense;
00083 ABA_BUFFER < ABA_VARIABLE * >variables (this, 0);
00084 ABA_BUFFER < ABA_CONSTRAINT * >temp (this, 0);
00085 ABA_BUFFER < ABA_CONSTRAINT * >constraints (this, 0);
00086 initializePools (constraints, temp, variables,
00087 minimal_size, minimal_size, true);
00088 conPool ()->increase (minimal_size);
00089 cutPool ()->increase (minimal_size);
00090 nvars = 0;
00091 nconss = 0;
00092 primal_heur = NULL;
00093 implic = NULL;
00094 objint = 1;
00095 spb = false;
00096 monomialinstance = NULL;
00097 boolinstance = NULL;
00098 mon_splitstrat = NULL;
00099 bool_splitstrat = NULL;
00100 qr = new QuadRef(*this);
00101 qr_on_separate = true;
00102 qrType = SQK2_SQK3;
00103 };
00104
00105
00107
00109 ILP_Problem::~ILP_Problem () {
00110 if( primal_heur != NULL )
00111 delete primal_heur;
00112 if( implic != NULL ) {
00113 delete implic;
00114 implic = NULL;
00115 }
00116 for (std::list<sym_constraint*>::iterator sc = sym_constraints.begin(); sc != sym_constraints.end(); sc++)
00117 delete *sc;
00118 std::list<boolfunction*>::iterator it;
00119 for (it = bf_list.begin(); it != bf_list.end(); it++)
00120 delete *it;
00121 for (it = bf_toDelete.begin(); it != bf_toDelete.end(); it++)
00122 delete *it;
00123 };
00124
00125
00126 void ILP_Problem::initializeOptimization ()
00127 {
00128 if(objint) objInteger(1);
00129 if(numcon >= 0) {
00130 maxConAdd(numcon);
00131 maxConBuffered(numcon);
00132 }
00133 if( spb )
00134 primalBound(pb);
00135 };
00136
00137
00138 void ILP_Problem::initializeParameters ()
00139 {
00140
00141
00142
00143
00144 };
00145
00146 var ILP_Problem::add_binary_variable(double obj, Activation a)
00147 {
00148 return add_variable(obj, 0, 1, Vartype_Binary, a);
00149 }
00150
00151 var ILP_Problem::add_variable (double obj, double lBound, double uBound,
00152 Vartype t, Activation a)
00153 {
00154 if (nvars == varPool ()->size ())
00155 varPool ()->increase (2 * nvars);
00156
00157 var_obj * v = new var_obj (obj, lBound, uBound, t);
00158 return add_variable (v, a);
00159 };
00160
00161
00162 var ILP_Problem::add_variable (var_obj * v, Activation a)
00163 {
00164 v->init (*this, nvars, a);
00165 varPool ()->insert (v->AVar ());
00166 nvars++;
00167 if(!isInteger(v->obj()) || v->vt != Vartype_Integer) objint = 0;
00168 return v;
00169 };
00170
00171 void ILP_Problem::updateBestSolution (solution& Sol_)
00172 {
00173 Sol=Sol_;
00174 }
00175
00176 cons
00177 ILP_Problem::add_basic_constraint (cons_obj * c, Activation a, quadRefStatus qrStatus)
00178 {
00179 c->init (*this, nconss, a);
00180 if(qrStatus != CHECK)
00181 c->set_qrStatus(qrStatus);
00182 qr->addCons(c);
00183 nconss++;
00184 if (conPool ()->number () == conPool ()->size ())
00185 conPool ()->increase (2 * conPool ()->size ());
00186 conPool ()->insert (c->Acons ());
00187 return c;
00188 };
00189
00190
00191 cons ILP_Problem::add_basic_constraint(cons_sense s, double r, Activation a) {
00192
00193
00194
00195 cons_obj* I=new cons_obj();
00196 I->set_sense(s);
00197 I->set_rhs(r);
00198 add_basic_constraint(I, a);
00199 return I;
00200 }
00201
00202 void ILP_Problem::add_sym_constraint(sym_constraint* c) {
00203
00204 sym_constraints.push_back(c);
00205 return;
00206 }
00207
00208 void ILP_Problem::add_pol_constraint(pol_constraint c) {
00209 polynomial pol = c.p;
00210 std::list<monomial> mons = pol.get_p();
00211 row r;
00212 std::list<monomial>::iterator pos;
00213 std::list<monomial>::const_iterator mo;
00214 foreach(mo, mons) {
00215 pos = lower_bound(monomials.begin(), monomials.end(), *mo);
00216
00217 if(pos != monomials.end() && *pos == *mo )
00218 r += pos->get_L() * mo->get_coeff();
00219 else
00220 r += add_polynomial(*mo, false);
00221 }
00222 if( c.s == Less )
00223 add_basic_constraint(r<=c.rhs);
00224 else if( c.s == Greater )
00225 add_basic_constraint(r>=c.rhs);
00226 else
00227 add_basic_constraint(r==c.rhs);
00228 return;
00229 }
00230
00231 row ILP_Problem::add_polynomial(polynomial p, bool update) {
00232 p.normalize();
00233 row r;
00234 std::list<monomial> mons = p.get_p();
00235 std::list<monomial>::iterator mon;
00236 std::list<monomial>::iterator pos;
00237 std::vector<var>::iterator varit;
00238 std::vector<var> varlist;
00239 foreach(mon, mons) {
00240 varlist = mon->get_A();
00241 foreach(varit, varlist){
00242 if(!(varit->type()==Vartype_Binary)){
00243 cerr<<"All variables in a polynomial have to be binary!"<<endl;
00244 exit(Fatal);
00245 }
00246 }
00247 if( mon->size() == 1 ) {
00248
00249 if(update)
00250 set_obj_coefficient((mon->get_A())[0], get_obj_coefficient((mon->get_A())[0]) + mon->get_coeff());
00251 r += mon->get_coeff() * (mon->get_A())[0];
00252 continue;
00253 }
00254 if( monomials.size() > 0 ) {
00255
00256 pos = lower_bound(monomials.begin(), monomials.end(), *mon);
00257 if(pos!=monomials.end() && *mon == *pos) {
00258 r+=mon->get_coeff() * pos->get_L();
00259 if(update){
00260
00261 pos->set_coeff(pos->get_coeff() + mon->get_coeff());
00262 set_obj_coefficient(pos->get_L(), pos->get_coeff());
00263 }
00264 }else {
00265
00266 double coeff = mon->get_coeff();
00267 if(!update)
00268 mon->set_coeff(0);
00269 mon->linearize(*this);
00270 r+=coeff * mon->get_L();
00271 monomials.insert(pos, *mon);
00272
00273 if(mon->size() == 2){
00274 qr->hashPair((mon->get_A())[0], (mon->get_A())[1], (mon->get_L()));
00275 }
00276 }
00277 }else{
00278
00279 double coeff = mon->get_coeff();
00280 if(!update)
00281 mon->set_coeff(0);
00282 mon->linearize(*this);
00283 r+=coeff * mon->get_L();
00284 monomials.push_back(*mon);
00285
00286 if(mon->size() == 2){
00287 qr->hashPair((mon->get_A())[0], (mon->get_A())[1], (mon->get_L()));
00288 }
00289
00290 }
00291 }
00292 return r;
00293 }
00294
00295 row ILP_Problem::add_polynomial(monomial m, bool update) {
00296 return add_polynomial(polynomial(m), update);
00297 }
00298
00299 var ILP_Problem::add_boolfunction(boolfunction* bf, double c) {
00300 var linVar;
00301 std::list<boolfunction*>::iterator pos;
00302 if(bf->get_op() == BASIC){
00303 if(bf->is_negated()){
00304 linVar = add_binary_variable(c);
00305 add_basic_constraint(linVar + bf->get_v() == 1, Static);
00306 } else {
00307 set_obj_coefficient(bf->get_v(), get_obj_coefficient(bf->get_v()) + c);
00308 linVar = bf->get_v();
00309 }
00310 bf_toDelete.push_back(bf);
00311 } else {
00312 bf->simplify();
00313 pos = lower_bound(bf_list.begin(), bf_list.end(), bf, bfcompare_less);
00314 if(pos!=bf_list.end() && bfcompare_equal(*pos, bf)) {
00315 linVar = (*pos)->get_rLinear().begin()->Var;
00316 set_obj_coefficient(linVar, get_obj_coefficient(linVar) + c);
00317 bf_toDelete.push_back(bf);
00318 } else {
00319 linVar = bf->linearize(*this);
00320 set_obj_coefficient(linVar, c);
00321 bf_list.insert(pos, bf);
00322 }
00323 }
00324 return linVar;
00325 }
00326
00327 void ILP_Problem::add_bool_constraint(boolfunction* bf, bool_cons_type bct){
00328 std::list<boolfunction*> bfl;
00329 bfl.push_back(bf);
00330 add_bool_constraint(bfl, bct);
00331 }
00332
00333 void ILP_Problem::add_bool_constraint(std::list<boolfunction*>& bfl, bool_cons_type bct){
00334 var v;
00335 row r;
00336 boolfunction* bf;
00337 switch(bct) {
00338 case C0:
00339 for(std::list<boolfunction*>::iterator it = bfl.begin(); it != bfl.end(); it++){
00340 v = add_boolfunction(*it, .0);
00341 add_basic_constraint(row(v) == 0, Static);
00342 }
00343 break;
00344 case C1:
00345 for(std::list<boolfunction*>::iterator it = bfl.begin(); it != bfl.end(); it++){
00346 v = add_boolfunction(*it, .0);
00347 add_basic_constraint(row(v) == 1, Static);
00348 }
00349 break;
00350 case CS:
00351 case CE:
00352 std::list<boolfunction*>::iterator it = bfl.begin();
00353 bf = (*it)->copy();
00354 r = 0;
00355 r += add_boolfunction(*it, .0);
00356 it++;
00357 for(;it != bfl.end(); it++){
00358 r += add_boolfunction(*it, .0);
00359 bf->add(OR, *it);
00360 }
00361 v = add_boolfunction(bf, .0);
00362 add_basic_constraint(r == v, Static);
00363 if(bct == CE)
00364 add_basic_constraint(row(v) == 1, Static);
00365 break;
00366 }
00367 }
00368
00369 void ILP_Problem::extendSolution(solution& S) {
00370 for( std::list<monomial>::iterator it = monomials.begin(); it != monomials.end(); it++ ) {
00371 std::vector<var> a = it->get_A();
00372
00373 if(a.size()<2)
00374 continue;
00375 S.set_value(it->get_L(), 1.);
00376 for( unsigned int i = 0; i < a.size(); i++ ) {
00377 if( S.value(a[i]) < 1e-6 ) {
00378 S.set_value(it->get_L(), 0.);
00379 break;
00380 }
00381 }
00382 }
00383 for( std::list<boolfunction*>::iterator bfit = bf_list.begin(); bfit != bf_list.end(); bfit++) {
00384 if ((*bfit)->get_op() == BASIC || (*bfit)->get_rLinear().size() > 1 || (*bfit)->get_rLinear().begin()->coeff != 1)
00385 continue;
00386 if ((*bfit)->evaluate(S))
00387 S.set_value((*bfit)->get_rLinear().begin()->Var,1.);
00388 else
00389 S.set_value((*bfit)->get_rLinear().begin()->Var,0.);
00390 }
00391 }
00392
00393 void ILP_Problem::set_coefficient(var v, cons i, double d) {
00394
00395
00396 coeff_list.push_back(Coefficient(v,i,d));
00397 };
00398
00399 void ILP_Problem::set_obj_coefficient(var v, double d) {
00400 (v.Avar_pointer())->obj_ = d;
00401 (v.var_pointer())->obj_ = d;
00402 return;
00403 }
00404
00405 double ILP_Problem::get_obj_coefficient(var v) const {
00406 return (v.Avar_pointer())->obj_;
00407 }
00408
00409 void ILP_Problem::set_primal_heuristic(primal_heuristic* P) {
00410
00411 primal_heur=P;
00412 };
00413
00414 void ILP_Problem::set_implicator(implicator* P) {
00415 implic = P;
00416 }
00417
00418 void ILP_Problem::set_monomial_split_strategy(mon_split_strategy* spst) {
00419 mon_splitstrat=spst;
00420 }
00421
00422 void ILP_Problem::set_bool_split_strategy(bool_split_strategy* spst) {
00423 bool_splitstrat=spst;
00424 }
00425
00426 void ILP_Problem::set_qr_on_separate(bool qr){
00427 qr_on_separate = qr;
00428 }
00429
00430 bool ILP_Problem::get_qr_on_separate() {
00431 return qr_on_separate;
00432 }
00433
00434 void ILP_Problem::set_qrType(quadRefStatus qt) {
00435 qrType = qt;
00436 }
00437
00438 quadRefStatus ILP_Problem::get_qrType(){
00439 return qrType;
00440 }
00441
00442 #if 0
00443 void ILP_Problem::set_branching(Branching* B) {
00444 bran = B;
00445 cerr << "Branching set to " << bran << endl;
00446 return;
00447 }
00448 #endif
00449
00450 void ILP_Problem::optimize() {
00451
00452
00453 add_sym_constraint(qr);
00454
00455 qr->reformulate_forced_constraints();
00456
00457 if(monomials.size() > 0){
00458
00459 monomialinstance = new monomial_inst(monomials, *this, mon_splitstrat);
00460 add_sym_constraint(monomialinstance);
00461 qr->check_and_reformulate();
00462 }
00463
00464 if(bf_list.size() > 0) {
00465 boolinstance = new bool_inst(bf_list, *this, bool_splitstrat);
00466 add_sym_constraint(boolinstance);
00467 }
00468
00469 ABA_MASTER::optimize();
00470 };
00471
00472
00473 double ILP_Problem::get_solution(var v) {
00474
00475 return Sol.value(v);
00476 }
00477
00478 double ILP_Problem::get_solution(row& r) {
00479 row_entry::list_constiterator re;
00480 double d=0;
00481 foreach(re, r) d+=re->coeff*get_solution(re->Var);
00482 return d;
00483 }
00484
00485 solution ILP_Problem::get_solution() {
00486 return Sol;
00487 }
00488
00489 double ILP_Problem::get_optimum() {
00490
00491 return primalBound();
00492
00493
00494
00495
00496
00497
00498 }