Main Page   Class Hierarchy   Compound List   File List   Contact   Download   Symbolic Constraints   Examples  

ilp_problem.cc

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) //, bran(NULL)
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   //if(exists(".abacus")) {
00141     //readParameters (".abacus");
00142     //}
00143     //Parameters are read from $ABACUS_DIR/.abacus only!
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   /*{\Mop adds a primitive basic constraint to the root of the 
00193     BCP-tree. |s| specifies the sense (one of |Less|, |Equal|, or 
00194     |Greater|) and |r| the right-hand-side of the constraint.}*/
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   /*{\Mop adds the symbolic constraint |c| to the model.}*/
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       //construct constraint using linearization variable and monomial coeff
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          //monomial is linear
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          //search for the monomial in global monomial list
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                //if monomial exists the coefficient is updated
00261                pos->set_coeff(pos->get_coeff() + mon->get_coeff());
00262                set_obj_coefficient(pos->get_L(), pos->get_coeff());
00263             } 
00264          }else {
00265             //add monomial to global list and create linearization variable
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             //if the monomial consists of two variables add it to QuadRef
00273             if(mon->size() == 2){
00274                qr->hashPair((mon->get_A())[0], (mon->get_A())[1], (mon->get_L()));
00275             }
00276          }
00277       }else{
00278          //add monomial to global list and create linearization variable
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          //if the monomial consists of two variables add it to QuadRef
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       //avoid monomials with only one variable
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   /*{\Mop sets the coefficient for variable $v$ and ineqality $i$
00395     to $d$ in the LP-Matrix.}*/
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   /*{\Mop adds a primal heuristic to the model.}*/
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   /*{\Mop Computes the optimal solution for the current model.}*/
00452 
00453    add_sym_constraint(qr);
00454    //new monomials may be added by this method
00455    qr->reformulate_forced_constraints();
00456 
00457    if(monomials.size() > 0){
00458       //decompose all monomials to reduce polynomial instance to quadratic instance
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   /*{\Mop returns the value of $v$ in the best found solution.}*/
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    //FIXME
00491    return primalBound();
00492   /*
00493   var v;
00494   double d=0.;
00495   forall_variables(v, *myroot) d+=get_solution(v)*v.obj();
00496   return d;
00497   */
00498 }
Generated on Mon Mar 28 22:03:48 2011 for SCIL by  doxygen 1.6.3