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++;
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
00121 if (master_->nLp () == 1)
00122 return false;
00123
00124
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
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
00172
00173
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
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
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
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
00292 return counter;
00293 };
00294
00295
00296 void subproblem::remove_variable (var V)
00297 {
00298
00299
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
00309 }
00310
00311
00312 void subproblem::set_coefficient (var v, cons i, double d)
00313 {
00314
00315
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
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
00332 return ABA_SUB::nVar ();
00333 };
00334
00335 cons subproblem::get_cons (int i)
00336 {
00337
00338
00339 if(i>=nCon()) return nil;
00340 return cons (((ABA_Constraint *) ABA_SUB::constraint (i))->Scons ());
00341 };
00342
00343 int subproblem::ncons ()
00344 {
00345
00346
00347 return ABA_SUB::nCon ();
00348 };
00349
00350
00351 double subproblem::value (var v)
00352 {
00353
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
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
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
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
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
00449
00450
00451
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
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
00479
00480 double subproblem::red_cost(var v) {
00481
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 };