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

subproblem.cc

00001 #include<LEDA/list.h>
00002 #include<scil/cons.h>
00003 #include<scil/cons_obj.h>
00004 #include<scil/var_obj.h>
00005 #include<scil/subproblem.h>
00006 #include<scil/aba_constraint.h>
00007 #include<scil/aba_variable.h>
00008 #include<scil/sym_constraint.h>
00009 #include<scil/ilp_problem.h>
00010 #include<scil/primal_heur.h>
00011 #include<scil/row.h>
00012 #include<scil/solution.h>
00013 
00014 using namespace SCIL;
00015 using namespace LEDA;
00016 
00017 void subproblem::add_sym_constraint (sym_constraint * c)
00018 {
00019   sym_constraints.append (c);
00020 }
00021 
00022 const
00023 LEDA::string& subproblem::configuration(const LEDA::string& s) const {
00024   return GM.configuration(s);
00025 };
00026 
00027 LEDA::string& subproblem::configuration(const LEDA::string& s) {
00028   return GM.configuration(s);
00029 };
00030 
00031 cons
00032 subproblem::add_basic_constraint (cons_obj * c, Activation a)
00033 {
00034   c->init (*this, GM.number_of_constraints(), a);
00035   GM.nconss++;
00036   ABA_BUFFER< ABA_CONSTRAINT * > constraint (master_, 1);
00037   constraint.push(c->Acons());
00038   addCons(constraint);
00039   return c;
00040 };
00041 
00042 cons
00043 subproblem::add_basic_constraint (cons_sense s, double rhs,
00044                                   Activation a)
00045 {
00046   cons_obj *
00047     c = new cons_obj (s, rhs);
00048   add_basic_constraint (c, a);
00049   return c;
00050 };
00051 
00052 var
00053 subproblem::add_variable (double obj,
00054                           double lBound, double uBound,
00055                           Vartype t, Activation a)
00056 {
00057   ABA_VARTYPE::TYPE type = ABA_VARTYPE::Continuous;
00058   if (t == Vartype_Integer)
00059     {
00060       if ((lBound == 0) && (uBound == 1))
00061         type = ABA_VARTYPE::Binary;
00062       else
00063         type = ABA_VARTYPE::Integer;
00064     }
00065 
00066   var
00067     v;
00068 
00069   if (initpricing == false)
00070     {
00071 
00072       v = new var_obj (obj, lBound, uBound, t);
00073       add_variable (v, a);
00074 
00075     }
00076   else
00077     {
00078       if (newvarbuffer->size () == newvarbuffer->number ())
00079         newvarbuffer->realloc (newvarbuffer->size () * 2);
00080       v = new var_obj (obj, lBound, uBound, t);
00081       v.var_pointer ()->init (*this, GM.nvars, a);
00082       newvarbuffer->push (v.Avar_pointer ());
00083       GM.nvars++;
00084     }
00085   return v;
00086 };
00087 
00088 void
00089 subproblem::add_variable (var v, Activation a)
00090 {
00091   v.var_pointer ()->init (*this, GM.nvars, a);
00092   if (v.var_pointer () != nil)
00093     {
00094       GM.nvars++;  // function machen und friend entfernen?
00095       ABA_BUFFER < ABA_VARIABLE * >p (master_, 1);
00096       p.push (v.Avar_pointer ());
00097       if (addVars (p) == 0)
00098         cout << "Variable not added\n";
00099     }
00100 }
00101 
00102 subproblem::subproblem (ABA_MASTER * master):ABA_SUB (master, 0, 0, 0),
00103 GM (*(ILP_Problem *) master_)
00104 {
00105   initpricing = false;
00106   newvarbuffer= new ABA_BUFFER < ABA_VARIABLE * >(master_,8);
00107 };
00108 
00109 subproblem::subproblem (ABA_MASTER * master, ABA_SUB * father,
00110 ABA_BRANCHRULE * branchRule):ABA_SUB (master, father, branchRule),
00111 GM (*(ILP_Problem *) master_)
00112 {
00113   initpricing = false;
00114   newvarbuffer=new ABA_BUFFER < ABA_VARIABLE * >(master_,8);
00115 };
00116 
00117 bool
00118 subproblem::feasible ()
00119 {
00120   //cout << master_->nLp () << " LPs\n";
00121   if (master_->nLp () == 1)
00122     return false;
00123 
00124   //  if(!integerFeasible()) return false;
00125   solution S;
00126   S.save_solution(*this);
00127   for (int i = 0; i < nVar (); i++)
00128     if (get_var (i).Avar_pointer ()->varType () != ABA_VARTYPE::Continuous)
00129       {
00130         if (fabs (xVal (i) - floor (xVal (i) + 0.5)) > 0.001)
00131           {
00132             //cout << xVal (i) << "\n";
00133             return false;
00134           }
00135         S.round_to_integer(get_var(i));
00136       };
00137   cout << "integer Feasible\n";
00138 
00139   update_indices ();
00140   if (!feasible (*this, S))
00141     return false;
00142 
00143   GM.updateBestSolution (S);
00144 
00145   return true;
00146 }
00147 
00148 bool
00149 subproblem::feasible (subproblem & S, solution& Sol)
00150 {
00151 
00152   sym_constraint * s;
00153   forall (s, sym_constraints)
00154   {
00155     if (s->feasible (Sol) == sym_constraint::infeasible_solution)
00156       return false;
00157   }
00158 
00159   if (father () != 0)
00160     {
00161       if (!((subproblem *) father ())->feasible (S, Sol))
00162         return false;
00163     }
00164 
00165   return true;
00166 };
00167 
00168 void
00169 subproblem::update_indices ()
00170 {
00171   //if(updateLP==nLP()) return;
00172 
00173   //updateLP=nLp();
00174 
00175   for (int i = 0; i < nVar (); i++)
00176     {
00177       get_var (i).var_pointer ()->vi = i;
00178     }
00179 
00180   for (int i = 0; i < nCon (); i++)
00181     {
00182       ((ABA_Constraint *) constraint (i))->ii = i;
00183     }
00184 };
00185 
00186 int
00187 subproblem::separate ()
00188 {
00189   if (master_->nLp () == 1)
00190     {
00191       sym_constraint *
00192         c;
00193       forall (c, sym_constraints) c->init (*this);
00194 
00195       add_basic_constraint((row) 0 <= 0);
00196 
00197       return 1;
00198     }
00199 
00200   update_indices ();
00201   return separate (*this);
00202 };
00203 
00204 int
00205 subproblem::separate (subproblem & S)
00206 {
00207   //int
00208   t = 0;
00209 
00210   sym_constraint * s;
00211   sym_constraint::status rs;
00212   forall (s, sym_constraints) if(t!=-1)
00213   {
00214     rs=s->separate(S);
00215     if (rs == sym_constraint::constraint_found) t++;
00216     if (rs == sym_constraint::fathom) t=-1;
00217   };
00218 
00219   int l;
00220   if ((father () != 0) && (t!=-1))
00221     {
00222       l = ((subproblem *) father ())->separate (S);
00223       if(l==-1) return -1; else t+=l;
00224     }
00225 
00226   if(t==-1) {
00227     t=1; add_basic_constraint((row) get_var(0) <= -1);
00228   };
00229   //cout<<t<<" Cosntraints\n";
00230   return t;
00231 };
00232 
00233 int
00234 subproblem::pricing ()
00235 {
00236   update_indices ();
00237   int
00238     i;
00239   if (lp ()->infeasible ())
00240     {
00241       i = mf_pricing (*this);
00242     }
00243   else
00244     {
00245       i = pricing (*this);
00246     }
00247   cout << i << " Vars added\n";
00248   return i;
00249 };
00250 
00251 int
00252 subproblem::mf_pricing (subproblem & S)
00253 {
00254   int
00255     counter = 0;
00256 
00257   sym_constraint *
00258     p;
00259   forall (p, sym_constraints)
00260   {
00261     if (p->mf_pricing (S) == sym_constraint::variable_found)
00262       counter++;
00263   }
00264 
00265   if (father () != 0)
00266     {
00267       counter += ((subproblem *) father ())->mf_pricing (S);
00268     }
00269   //cout<<counter<<" Vars added"<<endl;
00270   return counter;
00271 };
00272 
00273 int
00274 subproblem::pricing (subproblem & S)
00275 {
00276   int
00277     counter = 0;
00278 
00279   sym_constraint *
00280     p;
00281   forall (p, sym_constraints)
00282   {
00283     if (p->LP_pricing (S) == sym_constraint::variable_found)
00284       counter++;
00285   }
00286 
00287   if (father () != 0)
00288     {
00289       counter += ((subproblem *) father ())->pricing (S);
00290     }
00291   //cout<<counter<<" Vars added"<<endl;
00292   return counter;
00293 };
00294 
00295 
00296 void subproblem::remove_variable (var V)
00297 {
00298   /*{\Mop removes a variable for the linear program of the 
00299     current node.} */
00300     removeVar (V.var_pointer ()->index ());
00301 };
00302 
00303 
00304 double subproblem::get_coeff (var v, cons i)
00305 {
00306   return v.var_pointer ()->coeff (i.cons_pointer ()->Acons ()) +
00307     i.cons_pointer ()->coeff (v.var_pointer ());
00308     // This is unsymmetric, since set_coefficient is stored in both
00309 }
00310 
00311 
00312 void subproblem::set_coefficient (var v, cons i, double d)
00313 {
00314   /*{\Mop sets the coefficient for variable $v$ and basic constraint $i$
00315     to $d$ in the LP-Matrix.} */
00316     v.var_pointer ()->set (i.cons_pointer (), d);
00317     i.cons_pointer ()->set (v.var_pointer (), d);
00318 };
00319 
00320 
00321 
00322 var subproblem::get_var (int i)
00323 {
00324   /*{\Mop {\bf better give the possibility to iterate over the variables!}} */
00325   if(i>=nVar()) return nil;
00326   return var (((ABA_Variable *) ABA_SUB::variable (i))->SVar ());
00327 };
00328 
00329 int subproblem::nVar () const
00330 {
00331   /*{\Mop returns the number of active variables in the current node.} */
00332   return ABA_SUB::nVar ();
00333 };
00334 
00335 cons subproblem::get_cons (int i)
00336 {
00337   /*{\Mop {\bf better give the possibility to iterate over the basic
00338     constraints!}} */
00339   if(i>=nCon()) return nil;
00340   return cons (((ABA_Constraint *) ABA_SUB::constraint (i))->Scons ());
00341 };
00342 
00343 int subproblem::ncons ()
00344 {
00345   /*{\Mop returns the number of active basic constraints in the current 
00346     node.} */
00347   return ABA_SUB::nCon ();
00348 };
00349 
00350 
00351 double subproblem::value (var v)
00352 {
00353   /*{\Mop returns the value of |v| of the last solved LP.} */
00354   if(v==nil) return 1;
00355   return xVal (v.var_pointer ()->index ());
00356 };
00357 
00358 double subproblem::value(row& r) {
00359   row_entry re;
00360   double d=0;
00361   forall(re, r) d+=re.coeff*value(re.Var);
00362   return d;
00363   };
00364 
00365 double subproblem::lower_bound (var v)
00366 {
00367   /*{\Mop returns the lower bound of the variable in the current node.} */
00368   if (fsVarStat (v.var_pointer ()->index ())->status () !=
00369       ABA_FSVARSTAT::Free)
00370     {
00371       return myvalue (v.var_pointer ()->index ());
00372     }
00373   return lBound (v.var_pointer ()->index ());
00374 }
00375 
00376 
00377 double subproblem::upper_bound (var v)
00378 {
00379   /*{\Mop returns the upper bound of the variable in the current node.} */
00380   if (fsVarStat (v.var_pointer ()->index ())->fixedOrSet ())
00381     {
00382       return myvalue (v.var_pointer ()->index ());
00383     }
00384   return uBound (v.var_pointer ()->index ());
00385 }
00386 
00387 double subproblem::value (cons i, as_what as) {
00388   /*{\Mop returns the value of |i| of the last solved LP.} */
00389   if (i.cons_pointer () == nil)
00390     {
00391       cout << "nil basic constraint\n"; return 0;}
00392   double d = yVal (i.cons_pointer ()->Acons ()->index ());
00393   if (as == as_is) return d;
00394   if ((as == as_max) && (GM.opt_sense () == Optsense_Max)) return d;
00395   if ((as == as_min) && (GM.opt_sense () == Optsense_Min)) return d;
00396   return -d;
00397 }
00398 
00399 
00400 
00401 //int subproblem::separate (subproblem &); 
00402 
00403 void subproblem::activate (subproblem & S)
00404 {
00405   sym_constraint * s; 
00406   
00407   forall (s, sym_constraints) 
00408     {
00409       s->open_subproblem (S);
00410     }
00411   
00412   if (father () != 0)
00413     {
00414       ((subproblem *) father ())->activate (S);
00415     }
00416 }
00417 
00418 void subproblem::activate ()
00419 {
00420   activate (*this);
00421 }; 
00422 
00423 
00424 void subproblem::deactivate (subproblem & S)
00425 {
00426   sym_constraint * s; 
00427   forall (s, sym_constraints)
00428     {
00429       s->close_subproblem (S);
00430     }; 
00431   if (father () != 0)
00432         {
00433           ((subproblem *) father ())->deactivate (S);
00434   }
00435 }; 
00436 
00437 
00438 void subproblem::save_solution(solution& s) {
00439   GM.save_solution(s);
00440 };
00441 
00442 void subproblem::deactivate ()
00443 {
00444   deactivate (*this);
00445 
00446   
00447 
00448   // TODO why is primal_heur not= 0 ???
00449   //cout<<&GM<<" "<<GM.primal_heur<<" master and heur\n";
00450   //if (GM.primal_heur != nil)
00451   //  GM.primal_heur->heuristic (*this);
00452 }; 
00453 
00454 double subproblem::myvalue (int i)
00455 {
00456   if (fsVarStat (i)->status () == ABA_FSVARSTAT::FixedToLowerBound)
00457     return lBound (i);
00458   if (fsVarStat (i)->status () == ABA_FSVARSTAT::SetToLowerBound)
00459     return lBound (i);
00460   if (fsVarStat (i)->status () == ABA_FSVARSTAT::FixedToUpperBound)
00461     return uBound (i);
00462   if (fsVarStat (i)->status () == ABA_FSVARSTAT::SetToUpperBound)
00463     return uBound (i); 
00464   return fsVarStat (i)->value ();
00465 }
00466 
00467 //int subproblem::mf_pricing (subproblem &); 
00468 
00469 double* subproblem::MxVal ()
00470 {
00471   return xVal_;
00472 }; 
00473 
00474 ABA_SUB * subproblem::generateSon (ABA_BRANCHRULE * rule)
00475 {
00476   return new subproblem (master_, this, rule);
00477 };
00478 /*{\op Diese Funktion erzeugt ein neues Unterproblem. } */
00479 
00480 double subproblem::red_cost(var v) {
00481   /*{\Mop returns the value of |v| of the last solved LP.}*/
00482   return lp()->reco(v.var_pointer()->index());
00483 };
00484 
00485 list_item subproblem::first_sym_constraint_item() const { 
00486   if(sym_constraints.size()==0) return nil;
00487   return GM.myroot->sym_constraints.first(); }
00488 
00489 list_item subproblem::next_sym_constraint_item(list_item i) const {
00490   return GM.myroot->sym_constraints.succ(i);
00491 };
00492 
00493 sym_constraint* subproblem::get_sym_cons(list_item i) {
00494   if(i==nil) return nil;
00495   return GM.myroot->sym_constraints[i];
00496 };
00497 
00498 subproblem::~subproblem() {
00499   delete newvarbuffer;
00500 };

Generated on Tue Nov 16 15:18:22 2004 for SCIL by doxygen1.2.16