00001
00002
00003 #include "angel/include/angel_types.hpp"
00004
00005 #include <iostream>
00006 #include <string>
00007 #include <string>
00008
00009 #include "angel/include/eliminations.hpp"
00010 #include "angel/include/angel_tools.hpp"
00011 #include "angel/include/angel_io.hpp"
00012
00013
00014
00015
00016
00017 namespace angel {
00018
00019 using namespace std;
00020 using namespace boost;
00021
00022 bool c_graph_t::check () const {
00023
00024
00025 vi_t vi, v_end;
00026 size_t sum_edges= 0;
00027 for (tie (vi, v_end)= vertices (*this); vi != v_end; ++vi)
00028 sum_edges+= out_degree (*vi, *this);
00029 if (sum_edges != num_edges (*this)) {
00030 write_graph ("graph with inconsistent edge number", *this);
00031 cout << "individually counted: " << sum_edges << ", num_edges: "
00032 << num_edges (*this) << std::endl;
00033 return false;}
00034
00035
00036 for (tie (vi, v_end)= vertices (*this); vi != v_end; ++vi)
00037 switch (vertex_type (*vi)) {
00038 case independent:
00039 if (in_degree (*vi, *this) > 0) {
00040 cout << *vi << " is independent with indegree > 0\n"; return false;}
00041 if (out_degree (*vi, *this) == 0) {
00042 cout << *vi << " is independent with outdegree == 0\n"; return false;}
00043 break;
00044 case dependent:
00045 if (in_degree (*vi, *this) == 0) {
00046 cout << *vi << " is dependent with indegree == 0\n"; return false;}
00047
00048
00049 default: ;
00050 }
00051
00052 return true;
00053 }
00054
00055 bool c_graph_t::check_initial () const {
00056 bool ok= check ();
00057 if (!ok) return false;
00058
00059
00060 vi_t vi, v_end;
00061 for (tie (vi, v_end)= vertices (*this); vi != v_end; ++vi)
00062 if (vertex_type (*vi) != independent && vertex_type (*vi) != dependent) {
00063 if (in_degree (*vi, *this) == 0) {
00064 cout << *vi << " is intermediate with indegree == 0\n"; return false;}
00065 if (out_degree (*vi, *this) == 0) {
00066 cout << *vi << " is intermediate with outdegree == 0\n"; return false;} }
00067
00068 return true;
00069 }
00070
00071 void c_graph_t::remove_dependents_with_successors () {
00072
00073 std::vector<vertex_t> dep;
00074 for (size_t i= 0; i < dependents.size(); i++)
00075 if (out_degree (dependents[i], *this) == 0)
00076 dep.push_back (dependents[i]);
00077 dependents.swap (dep);
00078 }
00079
00080 void c_graph_t::clear_graph () {
00081
00082 typedef c_graph_t::vertex_t v_t;
00083 typedef vector<v_t>::iterator it_t;
00084
00085 vector<bool> reachV;
00086 reachable_vertices (*this, reachV);
00087 vector<bool> relV;
00088 relevant_vertices (*this, relV);
00089
00090
00091 for (int i= reachV.size()-1; i >= 0; i--)
00092 if (!reachV[i] || !relV[i]) {
00093 v_t v= vertex (i, *this);
00094 clear_vertex (v, *this);
00095 remove_vertex (v, *this);
00096
00097 if (i < this->X)
00098 this->X--;
00099 else {
00100 it_t it= find (this->dependents.begin(), this->dependents.end(), v);
00101 if (it != this->dependents.end()) {
00102 remove (this->dependents.begin(), this->dependents.end(), v);
00103 this->dependents.resize(this->dependents.size()-1);}
00104 }
00105 for_each (this->dependents.begin(), this->dependents.end(), dec_greater<v_t> (v));
00106 }
00107 }
00108
00109
00110
00111
00112 bool operator== (const c_graph_t& g1, const c_graph_t& g2) {
00113
00114 typedef c_graph_t::vertex_t vertex_t;
00115 typedef c_graph_t::vi_t vi_t;
00116 typedef c_graph_t::edge_t edge_t;
00117 typedef c_graph_t::oei_t oei_t;
00118
00119 if (g1.v() != g2.v() || g1.x() != g2.x() || g1.y() != g2.y() || g1.z() != g2.z())
00120 return false;
00121
00122
00123 vector<vertex_t> d1 (g1.dependents), d2 (g2.dependents);
00124 sort (d1.begin(), d1.end());
00125 sort (d2.begin(), d2.end());
00126 for (size_t c= 0; c < d1.size(); c++)
00127 if (d1[c] != d2[c]) return false;
00128
00129
00130 vi_t vi1, v_end1, vi2, v_end2;
00131 tie (vi1, v_end1)= vertices (g1);
00132 tie (vi2, v_end2)= vertices (g2);
00133 edge_equal_t<c_graph_t> edge_equal (g1, g2);
00134 edge_less_t<c_graph_t> edge_less (g1, g2);
00135 for (; vi1 != v_end1; ++vi1, ++vi2) {
00136 oei_t oei1, oe_end1, oei2, oe_end2;
00137 tie (oei1, oe_end1)= out_edges (*vi1, g1);
00138 vector<edge_t> oe1 (oei1, oe_end1);
00139 sort (oe1.begin(), oe1.end(), edge_less);
00140
00141 tie (oei2, oe_end2)= out_edges (*vi2, g2);
00142 vector<edge_t> oe2 (oei2, oe_end2);
00143 sort (oe2.begin(), oe2.end(), edge_less);
00144
00145
00146 for (size_t c= 0; c < oe1.size(); c++)
00147 if (!edge_equal (oe1[c], oe2[c]))
00148 return false;
00149 }
00150
00151 return true;
00152 }
00153
00154 int overall_markowitz_degree (const c_graph_t& cg) {
00155
00156 int degree= 0;
00157 c_graph_t::vi_t vi, v_end;
00158 for (boost::tie (vi, v_end)= vertices (cg); vi != v_end; ++vi)
00159 degree+= in_degree (*vi, cg) * out_degree (*vi, cg);
00160
00161 return degree;
00162 }
00163
00164
00165
00166
00167
00168
00169
00170 line_graph_t::line_graph_t (const c_graph_t& cg) {
00171
00172 const int X1= cg.x(), X2= X1, Y1= cg.y(), Y2= Y1, Z2= num_edges (cg);
00173
00174
00175 pure_line_graph_t gtmp (X2+Y2+Z2);
00176 pure_line_graph_t::swap (gtmp);
00177 X= X2; cons_ok= false;
00178
00179 ed_t ew= get(vertex_degree, *this);
00180 evn_t evn= get(vertex_name, *this);
00181 for (int i= 0; i < X2; i++)
00182 evn[i]= make_pair (i, i), ew[i]= 0;
00183
00184
00185 property_map<c_graph_t, edge_weight_t>::const_type cg_ew= get(edge_weight, cg);
00186 c_graph_t::ei_t ei1, eend1;
00187
00188 tie(ei1, eend1)= edges(cg);
00189 for (int i= X2; i < X2+Z2; ei1++, i++) {
00190 evn[i]= make_pair (source (*ei1, cg), target (*ei1, cg));
00191 ew[i]= cg_ew[*ei1]; }
00192
00193 for (int i= X2+Z2, di= 0; i < X2+Z2+Y2; di++, i++) {
00194 evn[i]= make_pair (cg.dependents[di], cg.dependents[di]); ew[i]= 0;
00195 dependents.push_back (i); }
00196
00197
00198 c_graph_t cg_copy (cg);
00199 renumber_edges (cg_copy);
00200 property_map<c_graph_t, edge_index_t>::type eid1= get(edge_index, cg_copy);
00201
00202
00203 c_graph_t::vi_t vi1, vend1;
00204 tie(vi1, vend1) = vertices(cg_copy);
00205 for (int i= 0; i < X1; i++, ++vi1) {
00206 c_graph_t::oei_t oei1, oeend1;
00207 for (tie (oei1, oeend1)= out_edges (*vi1, cg_copy); oei1 != oeend1; ++oei1)
00208 add_edge (i, eid1[*oei1]+X1, *this);
00209 }
00210
00211 for (tie(ei1, eend1) = edges(cg_copy); ei1 != eend1; ++ei1) {
00212 int ei1_id= eid1[*ei1];
00213 c_graph_t::vertex_t vt= target(*ei1, cg_copy);
00214
00215
00216 for (size_t i= 0; i < cg_copy.dependents.size(); i++)
00217 if (vt == cg_copy.dependents[i]) {
00218 add_edge (ei1_id+X1, X2 + Z2 + i, *this);
00219 break; }
00220
00221
00222 c_graph_t::oei_t ei1i, eend1i;
00223 for (tie (ei1i, eend1i)= out_edges (vt, cg_copy); ei1i != eend1i; ++ei1i)
00224 add_edge (ei1_id+X1, eid1[*ei1i]+X1, *this);
00225 }
00226
00227 THROW_DEBUG_EXCEPT_MACRO (overall_markowitz_degree (cg) != overall_markowitz_degree (*this),
00228 consistency_exception, "Different Markowitz degree in line graph");
00229 }
00230
00231
00232 bool line_graph_t::check () const {
00233
00234
00235 ei_t ei, e_end;
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245 vector<size_t> od (v ());
00246 fi_t fi, f_end;
00247 for (tie (fi, f_end)= edges (*this); fi != f_end; ++fi)
00248 od [source(*fi,*this)]++;
00249
00250 for (tie (ei, e_end)= vertices (*this); ei != e_end; ++ei)
00251 if (out_degree (*ei, *this) != od [*ei]) {
00252 cout << "vertex " << *ei << " has inconsistent edge number ("
00253 << out_degree (*ei, *this) << " != " << od [*ei] << ")\n";
00254 return false;}
00255
00256 line_graph_t::const_evn_t evn= get(vertex_name, *this);
00257 for (tie (fi, f_end)= edges (*this); fi != f_end; ++fi) {
00258 if (evn[source(*fi,*this)].second != evn[target(*fi,*this)].first) {
00259 cout << "edge label inconsistent\n"; return false; }
00260 if (int (source(*fi,*this)) >= v()) {
00261 cout << "edge with inconsistent source ("
00262 << source(*fi,*this) << " >= " << v() << ")\n"; return false; }
00263 if (int (target (*fi,*this)) >= v()) {
00264 cout << "edge with inconsistent target ("
00265 << target (*fi,*this) << " >= " << v() << ")\n"; return false; } }
00266
00267 for (edge_t e= 0; (int) e < x(); e++)
00268 if (evn[e].first != evn[e].second) {
00269 cout << "edge label of independent edge is inconsistent\n"; return false; }
00270
00271 for (int c= 0; c < y(); c++) {
00272 edge_t e= dependents[c];
00273 if (evn[e].first != evn[e].second) {
00274 cout << "edge label of dependent edge is inconsistent\n"; return false; } }
00275
00276 return true;
00277 }
00278
00279 bool line_graph_t::is_tripartite () const {
00280 ei_t ei, e_end;
00281 for (tie (ei, e_end)= vertices (*this); ei != e_end; ei++)
00282 if (vertex_type (*ei) == intermediate) {
00283 if (in_degree (*ei, *this) != 1 || out_degree (*ei, *this) != 1) return false;
00284 pair<ifi_t, ifi_t> ifp= in_edges (*ei, *this);
00285 if (vertex_type (source (*ifp.first, *this)) != independent) return false;
00286 pair<ofi_t, ofi_t> ofp= out_edges (*ei, *this);
00287 if (vertex_type (target (*ofp.first, *this)) != dependent) return false; }
00288 return true;
00289 }
00290
00291 void line_graph_t::clear_graph () {
00292
00293 typedef line_graph_t::edge_t v_t;
00294 typedef vector<v_t>::iterator it_t;
00295
00296 vector<bool> reachV;
00297 reachable_vertices (*this, reachV);
00298 vector<bool> relV;
00299 relevant_vertices (*this, relV);
00300
00301
00302 for (int i= reachV.size()-1; i >= 0; i--)
00303 if (!reachV[i] || !relV[i]) {
00304 v_t v= vertex (i, *this);
00305 clear_vertex (v, *this);
00306 remove_vertex (v, *this);
00307
00308 if (i < this->X)
00309 this->X--;
00310 else {
00311 it_t it= find (this->dependents.begin(), this->dependents.end(), v);
00312 if (it != this->dependents.end()) {
00313 remove (this->dependents.begin(), this->dependents.end(), v);
00314 this->dependents.resize(this->dependents.size()-1);}
00315 }
00316 for_each (this->dependents.begin(), this->dependents.end(), dec_greater<v_t> (v));
00317 }
00318 }
00319
00320 bool operator== (const line_graph_t& g1, const line_graph_t& g2) {
00321
00322 using namespace std;
00323 typedef line_graph_t::edge_t edge_t;
00324 typedef line_graph_t::ei_t ei_t;
00325 typedef line_graph_t::face_t face_t;
00326 typedef line_graph_t::ofi_t ofi_t;
00327
00328 if (g1.v() != g2.v() || g1.x() != g2.x() || g1.y() != g2.y() || g1.z() != g2.z())
00329 return false;
00330
00331
00332 vector<edge_t> d1 (g1.dependents), d2 (g2.dependents);
00333 sort (d1.begin(), d1.end());
00334 sort (d2.begin(), d2.end());
00335 for (size_t c= 0; c < d1.size(); c++)
00336 if (d1[c] != d2[c]) return false;
00337
00338
00339 ei_t vi1, v_end1, vi2, v_end2;
00340 tie (vi1, v_end1)= vertices (g1);
00341 tie (vi2, v_end2)= vertices (g2);
00342 edge_equal_t<line_graph_t> edge_equal (g1, g2);
00343 edge_less_t<line_graph_t> edge_less (g1, g2);
00344 for (; vi1 != v_end1; ++vi1, ++vi2) {
00345 if (out_degree (*vi1, g1) != out_degree (*vi2, g2))
00346 return false;
00347
00348 ofi_t oei1, oe_end1, oei2, oe_end2;
00349 tie (oei1, oe_end1)= out_edges (*vi1, g1);
00350 vector<face_t> oe1 (oei1, oe_end1);
00351 sort (oe1.begin(), oe1.end(), edge_less);
00352
00353 tie (oei2, oe_end2)= out_edges (*vi2, g2);
00354 vector<face_t> oe2 (oei2, oe_end2);
00355 sort (oe2.begin(), oe2.end(), edge_less);
00356
00357
00358 for (size_t c= 0; c < oe1.size(); c++)
00359 if (!edge_equal (oe1[c], oe2[c]))
00360 return false;
00361 }
00362
00363 return true;
00364 }
00365
00366 int overall_markowitz_degree (const line_graph_t& lg) {
00367
00368 int degree= 0;
00369 line_graph_t::fi_t fi, f_end;
00370 for (boost::tie (fi, f_end)= edges (lg); fi != f_end; ++fi)
00371 degree+= vertex_type (source (*fi, lg), lg) != independent
00372 && vertex_type (target (*fi, lg), lg) != dependent;
00373
00374 return degree;
00375 }
00376
00377 int markowitz_degree (int j, const line_graph_t& lg) {
00378
00379 property_map<pure_line_graph_t, vertex_name_t>::const_type evn= get(vertex_name, lg);
00380
00381 int degree= 0;
00382
00383 line_graph_t::fi_t fi, f_end;
00384 for (boost::tie (fi, f_end)= edges (lg); fi != f_end; ++fi) {
00385 line_graph_t::edge_t ij= source (*fi, lg), jk= target (*fi, lg);
00386 THROW_DEBUG_EXCEPT_MACRO (evn[ij].second != evn[jk].first, consistency_exception,
00387 "Adjacency corrupted in line graph");
00388 if (vertex_type (ij, lg) == independent
00389 || vertex_type (jk, lg) == dependent) continue;
00390 degree+= evn[ij].second == j; }
00391
00392 return degree;
00393 }
00394
00395 void line_graph_t::copy_properties (const line_graph_t& _g) {
00396
00397 line_graph_t::evn_t evn= get(vertex_name, *this);
00398 line_graph_t::ed_t el= get(vertex_degree, *this);
00399
00400 line_graph_t::const_evn_t cevn= get(vertex_name, _g);
00401 line_graph_t::const_ed_t cel= get(vertex_degree, _g);
00402
00403 for (size_t i= 0; i < num_vertices (*this); i++) {
00404 evn[i]= cevn[i]; el[i]= cel[i]; }
00405 }
00406
00407 void accu_exp_graph_t::set_graph (line_graph_t::edge_t e_out, line_graph_t::edge_t e1,
00408 line_graph_t::edge_t e2, std::vector<int> exp_nr) {
00409 for (int c= 0; c < 5; c++) add_vertex (*this);
00410 boost::property_map<pure_accu_exp_graph_t, boost::vertex_name_t>::type vprop= get (vertex_name, *this);
00411 if (exp_nr[e1] == -1) vprop[0].set_node (e1); else vprop[0].set_exp (exp_nr[e1]);
00412 if (exp_nr[e2] == -1) vprop[1].set_node (e2); else vprop[1].set_exp (exp_nr[e2]);
00413 if (exp_nr[e_out] == -1) vprop[2].set_node (e_out); else vprop[2].set_exp (exp_nr[e_out]);
00414 vprop[3].set_op (accu_exp_t::mult); vprop[4].set_op (accu_exp_t::add);
00415 add_edge (0, 3, *this); add_edge (1, 3, *this); add_edge (2, 4, *this); add_edge (3, 4, *this);
00416 X= 3; dependents.push_back (4);
00417 }
00418
00419 void accu_exp_graph_t::set_graph (accu_exp_t::op_t op, line_graph_t::edge_t e1,
00420 line_graph_t::edge_t e2,
00421 std::vector<int> exp_nr) {
00422 for (int c= 0; c < 3; c++) add_vertex (*this);
00423 boost::property_map<pure_accu_exp_graph_t, boost::vertex_name_t>::type vprop= get (vertex_name, *this);
00424 if (exp_nr[e1] == -1) vprop[0].set_node (e1); else vprop[0].set_exp (exp_nr[e1]);
00425 if (exp_nr[e2] == -1) vprop[1].set_node (e2); else vprop[1].set_exp (exp_nr[e2]);
00426 vprop[2].set_op (op);
00427 add_edge (0, 2, *this); add_edge (1, 2, *this);
00428 X= 2; dependents.push_back (2);
00429 }
00430
00431 void accu_exp_graph_t::set_graph (line_graph_t::edge_t edge) {
00432 add_vertex (*this);
00433 boost::property_map<pure_accu_exp_graph_t, boost::vertex_name_t>::type vprop= get (vertex_name, *this);
00434 vprop[0].set_node (edge); X= 1;
00435 }
00436
00437 void accu_graph_t::set_jacobi_entries () {
00438 jacobi_entries.resize (accu_exp.size(), make_pair (0, 0));
00439 THROW_DEBUG_EXCEPT_MACRO ((int) exp_nr.size() != lg.v(), consistency_exception,
00440 "Array exp_nr has wrong size");
00441 THROW_DEBUG_EXCEPT_MACRO (!lg.check(), consistency_exception, "Line graph inconsistent");
00442 THROW_DEBUG_EXCEPT_MACRO (!lg.is_tripartite(), consistency_exception, "Line graph not tripartite");
00443 line_graph_t::const_evn_t evn= get(vertex_name, lg);
00444 line_graph_t::ei_t ei, e_end;
00445 for (tie (ei, e_end)= vertices (lg); ei != e_end; ei++) {
00446 if (lg.vertex_type (*ei) == intermediate) {
00447 if (exp_nr[*ei] == -1) {
00448 accu_exp.resize (accu_exp.size() + 1);
00449 accu_exp[accu_exp.size()-1].set_graph(*ei);
00450 jacobi_entries.push_back (evn[*ei]);
00451 } else
00452 jacobi_entries[exp_nr[*ei]]= evn[*ei];
00453 }
00454 }
00455 THROW_DEBUG_EXCEPT_MACRO (accu_exp.size() != jacobi_entries.size(), consistency_exception,
00456 "Wrong number of Jacobi entries");
00457 }
00458
00459 EdgeElim::EdgeElim() {
00460 }
00461
00462 EdgeElim::EdgeElim(const c_graph_t::edge_t& e,
00463 bool isFront,
00464 const c_graph_t& angelLCG) :
00465 myIsFrontFlag (isFront),
00466 mySource (source(e, angelLCG)),
00467 myTarget (target(e, angelLCG)) {
00468 }
00469
00470 EdgeElim::EdgeElim(const edge_bool_t& be,
00471 const c_graph_t& angelLCG) :
00472 myIsFrontFlag (be.second),
00473 mySource (source(be.first, angelLCG)),
00474 myTarget (target(be.first, angelLCG)) {
00475 }
00476
00477 EdgeElim::EdgeElim(const edge_ij_elim_t& eij) :
00478 myIsFrontFlag (eij.front),
00479 mySource (eij.i),
00480 myTarget (eij.j) {
00481 }
00482
00483 std::string EdgeElim::debug() const {
00484 std::ostringstream out;
00485 myIsFrontFlag ? out << "front"
00486 : out << "back";
00487 out << "eliminate edge (" << mySource << "," << myTarget << ")" << std::ends;
00488 return out.str();
00489 }
00490
00491 bool EdgeElim::isFront() const {
00492 return myIsFrontFlag;
00493 }
00494
00495 unsigned int EdgeElim::getSource() const {
00496 return mySource;
00497 }
00498
00499 unsigned int EdgeElim::getTarget() const {
00500 return myTarget;
00501 }
00502
00503 c_graph_t::edge_t EdgeElim::getE(const c_graph_t& angelLCG) const {
00504 return getEdge(mySource, myTarget, angelLCG);
00505 }
00506
00507 edge_bool_t EdgeElim::getBool(const c_graph_t& angelLCG) const {
00508 return make_pair(getEdge(mySource, myTarget, angelLCG), myIsFrontFlag);
00509 }
00510
00511 unsigned int EdgeElim::getCost(const c_graph_t& angelLCG) const {
00512 boost::property_map<c_graph_t, EdgeType>::const_type eType = get(EdgeType(), angelLCG);
00513 if (eType[getE(angelLCG)] == UNIT_EDGE)
00514 return 0;
00515
00516 unsigned int cost = 0;
00517 if (myIsFrontFlag) {
00518 c_graph_t::oei_t oei, oe_end;
00519 for (tie(oei, oe_end) = out_edges(myTarget, angelLCG); oei != oe_end; ++oei)
00520 if (eType[*oei] != UNIT_EDGE)
00521 cost++;
00522 }
00523 else {
00524 c_graph_t::iei_t iei, ie_end;
00525 for (tie(iei, ie_end) = in_edges(mySource, angelLCG); iei != ie_end; ++iei)
00526 if (eType[*iei] != UNIT_EDGE)
00527 cost++;
00528 }
00529 return cost;
00530 }
00531
00532 Rerouting::Rerouting() {
00533 }
00534
00535 Rerouting::Rerouting(const c_graph_t::edge_t e,
00536 const c_graph_t::edge_t pivot_e,
00537 bool isPre,
00538 const c_graph_t& angelLCG) {
00539 init(e, pivot_e, isPre, angelLCG);
00540 }
00541
00542 Rerouting::Rerouting(const edge_reroute_t& er,
00543 const c_graph_t& angelLCG) {
00544 init(er.e, er.pivot_e, er.isPre, angelLCG);
00545 }
00546
00547 std::string Rerouting::debug() const {
00548 std::ostringstream out;
00549 pre ? out << "preroute edge (" << i << "," << k << ") about pivot edge (" << j << "," << k << ")" << std::ends
00550 : out << "postroute edge (" << i << "," << k << ") about pivot edge (" << i << "," << j << ")" << std::ends;
00551 return out.str();
00552 }
00553
00554 bool Rerouting::isPre() const {
00555 return pre;
00556 }
00557
00558 c_graph_t::edge_t Rerouting::getE(const c_graph_t& angelLCG) const {
00559
00560 return getEdge(i, k, angelLCG);
00561 }
00562
00563 c_graph_t::edge_t Rerouting::getPivotE(const c_graph_t& angelLCG) const {
00564 return pre ? getEdge(j, k, angelLCG)
00565 : getEdge(i, j, angelLCG);
00566 }
00567
00568 edge_reroute_t Rerouting::getER(const c_graph_t& angelLCG) const {
00569 return edge_reroute_t (getE(angelLCG), getPivotE(angelLCG), pre);
00570 }
00571
00572 unsigned int Rerouting::getI() const {
00573 return i;
00574 }
00575
00576 unsigned int Rerouting::getJ() const {
00577 return j;
00578 }
00579
00580 unsigned int Rerouting::getK() const {
00581 return k;
00582 }
00583
00584 bool Rerouting::operator==(const Rerouting& anotherRerouting) const {
00585 if (this->isPre() == anotherRerouting.isPre()
00586 && this->getI() == anotherRerouting.getI()
00587 && this->getJ() == anotherRerouting.getJ()
00588 && this->getK() == anotherRerouting.getK())
00589 return true;
00590 else
00591 return false;
00592 }
00593
00594 void Rerouting::init(const c_graph_t::edge_t& e,
00595 const c_graph_t::edge_t& pivot_e,
00596 bool isPre,
00597 const c_graph_t& angelLCG) {
00598 if (isPre) {
00599 THROW_EXCEPT_MACRO(target(e, angelLCG) != target(pivot_e, angelLCG),
00600 consistency_exception,
00601 "edge_ijk_reroute_t: the edge and the pivot edge must have the same target for a prerouting");
00602 i = source(e, angelLCG);
00603 j = source(pivot_e, angelLCG);
00604 k = target(e, angelLCG);
00605 }
00606 else {
00607 THROW_EXCEPT_MACRO(source(e, angelLCG) != source(pivot_e, angelLCG),
00608 consistency_exception,
00609 "edge_ijk_reroute_t: the edge and the pivot edge must have the same target for a prerouting");
00610 k = target(e, angelLCG);
00611 j = target(pivot_e, angelLCG);
00612 i = source(e, angelLCG);
00613 }
00614 pre = isPre;
00615 }
00616
00617 Transformation::Transformation(const EdgeElim& anEdgeElim) :
00618 myIsReroutingFlag (false),
00619 myEdgeElim (anEdgeElim) {
00620 }
00621
00622 Transformation::Transformation(const edge_bool_t& be,
00623 const c_graph_t& angelLCG) :
00624 myIsReroutingFlag (false),
00625 myEdgeElim (be, angelLCG) {
00626 }
00627
00628 Transformation::Transformation(const edge_ij_elim_t& an_ij_elim) :
00629 myIsReroutingFlag (false),
00630 myEdgeElim (an_ij_elim) {
00631 }
00632
00633 Transformation::Transformation(const Rerouting& aRerouting) :
00634 myIsReroutingFlag (true),
00635 myRerouting (aRerouting) {
00636 }
00637
00638 Transformation::Transformation(const edge_reroute_t& aRerouteElim,
00639 const c_graph_t& angelLCG) :
00640 myIsReroutingFlag (true),
00641 myRerouting (aRerouteElim, angelLCG) {
00642 }
00643
00644 std::string Transformation::debug() const {
00645 std::ostringstream out;
00646 myIsReroutingFlag ? out << myRerouting.debug().c_str()
00647 : out << myEdgeElim.debug().c_str();
00648 return out.str();
00649 }
00650
00651 bool Transformation::isRerouting() const {
00652 return myIsReroutingFlag;
00653 }
00654
00655 const EdgeElim& Transformation::getEdgeElim() const {
00656 return myEdgeElim;
00657 }
00658
00659 const Rerouting& Transformation::getRerouting() const {
00660 return myRerouting;
00661 }
00662
00663 }
00664
00665
00666
00667