angel_types.cpp

Go to the documentation of this file.
00001 // $Id: angel_types.cpp,v 1.14 2008/02/28 14:57:33 gottschling Exp $ 
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 // c-graph
00015 // =====================================================
00016 
00017 namespace angel {
00018 
00019 using namespace std;
00020 using namespace boost;
00021 
00022 bool c_graph_t::check () const {
00023 
00024   // inconsistent edges, test not complete, tests only the number
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   // test vertex type
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           // (out_degree (*vi, *this) > 0) {
00048           //cout << *vi << " is dependent with outdegree > 0\n"; return false;}
00049         default:    ;    // not yet used in this graph type
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   // test intermediate vertices
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   // better reverse loop since removing vertices invalidates higher indices 
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   // compare dependents (as sorted copies)
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   // compare the out_edges for each pair of vertices
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     // now we can compare the sorted out_edges
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 // line graph
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   // V2= X2+Y2+Z2;
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);    // edge weights in line graph
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   // edge weights in c-graph
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   // edges must be numbered correctly to avoid quadratic complexity
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   // insert E~2
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     // look for dependent nodes (may not be on the end)
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); // mapping of Y from cg to lg numbering
00219         break; }
00220 
00221     // look for successors (even if vt is dependent)
00222     c_graph_t::oei_t ei1i, eend1i; // incident edges
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   // inconsistent edges, test not complete, tests only the number
00235   ei_t ei, e_end;
00236   /*size_t sum_faces= 0;
00237   for (tie (ei, e_end)= vertices (*this); ei != e_end; ++ei)
00238     sum_faces+= out_degree (*ei, *this);
00239   if (sum_faces != num_edges (*this)) {
00240     write_graph ("graph with inconsistent edge number", *this);
00241     cout << "individually counted: " << sum_faces << ", num_edges: "
00242          << num_edges (*this) << std::endl;
00243          return false;} */
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   // better reverse loop since removing vertices invalidates higher indices 
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   // compare dependents (as sorted copies)
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   // compare the out_edges for each pair of vertices
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     // now we can compare the sorted out_edges
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);  // edge label
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);  // edge label
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   } // end EdgeElim::debug()
00490 
00491   bool EdgeElim::isFront() const {
00492     return myIsFrontFlag;
00493   } // end EdgeElim::isFront()
00494 
00495   unsigned int EdgeElim::getSource() const {
00496     return mySource;
00497   } // end EdgeElim::getSource()
00498 
00499   unsigned int EdgeElim::getTarget() const {
00500     return myTarget;
00501   } // end EdgeElim::getTarget()
00502 
00503   c_graph_t::edge_t EdgeElim::getE(const c_graph_t& angelLCG) const {
00504     return getEdge(mySource, myTarget, angelLCG);
00505   } // end EdgeElim::getE()
00506 
00507   edge_bool_t EdgeElim::getBool(const c_graph_t& angelLCG) const {
00508     return make_pair(getEdge(mySource, myTarget, angelLCG), myIsFrontFlag);
00509   } // end EdgeElim::getBool()
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     // this edge is nonunit => cost unless the other edge is unit
00516     unsigned int cost = 0;
00517     if (myIsFrontFlag) { // front elimination
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 { // back elimination
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   } // end EdgeElim::getCost()
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   } // end Rerouting::debug()
00553 
00554   bool Rerouting::isPre() const {
00555     return pre;
00556   } // end Rerouting::isPre()
00557   
00558   c_graph_t::edge_t Rerouting::getE(const c_graph_t& angelLCG) const {
00559     // e goes from i to k, regardless of whether it's a prerouting or a postrouting
00560     return getEdge(i, k, angelLCG);
00561   } // end Rerouting::getE()
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   } // end Rerouting::getPivotE()
00567 
00568   edge_reroute_t Rerouting::getER(const c_graph_t& angelLCG) const {
00569     return edge_reroute_t (getE(angelLCG), getPivotE(angelLCG), pre);
00570   } // end Rerouting::getER()
00571 
00572   unsigned int Rerouting::getI() const {
00573     return i;
00574   } // end Rerouting::getI()
00575 
00576   unsigned int Rerouting::getJ() const {
00577     return j;
00578   } // end Rerouting::getJ()
00579 
00580   unsigned int Rerouting::getK() const {
00581     return k;
00582   } // end Rerouting::getK()
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   } // end Rerouting::operator==()
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   } // end Rerouting::init()
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   } // end Transformation::debug()
00650 
00651   bool Transformation::isRerouting() const {
00652     return myIsReroutingFlag;
00653   } // end Transformation::isRerouting()
00654 
00655   const EdgeElim& Transformation::getEdgeElim() const {
00656     return myEdgeElim;
00657   } // end Transformation::getEdgeElim()
00658 
00659   const Rerouting& Transformation::getRerouting() const {
00660     return myRerouting;
00661   } // end Transformation::getRerouting()
00662 
00663 } // namespace angel
00664 
00665 
00666 // =========================== doxygen input for whole lib
00667 

Generated on Wed Mar 11 10:33:11 2009 for angel by  doxygen 1.5.3