angel_tools.hpp

Go to the documentation of this file.
00001 // $Id: angel_tools.hpp,v 1.10 2004/02/22 18:44:46 gottschling Exp $
00002 
00003 #ifndef         _angel_tools_include_
00004 #define         _angel_tools_include_
00005 
00006 
00007 //
00008 //
00009 //
00010 
00011 #include <cstdlib>
00012 #include <string>
00013 #include <vector>
00014 #include <queue>
00015 #include <algorithm>
00016 #include <cmath>
00017 #include <numeric>
00018 #include <iostream>
00019 #include <deque>
00020 
00021 #include "angel_exceptions.hpp"
00022 #include "angel_types.hpp"
00023 
00024 namespace angel {
00025 
00026   using std::vector;
00027   using boost::tie;
00028   using boost::get;
00029   using boost::graph_traits;
00030 
00031 //                       some Operators
00032 // ===========================================================
00033 
00034 class write_vertex_op_t {
00035   const c_graph_t& cg;
00036 public:
00037   write_vertex_op_t (const c_graph_t& _cg) : cg (_cg) {}
00038   std::ostream& operator() (std::ostream& stream, c_graph_t::vertex_t v) {
00039     stream << v;
00040     return stream;
00041   }
00042 };
00043 
00044 class write_edge_op_t {
00045   const c_graph_t& cg;
00046 public:
00047   write_edge_op_t (const c_graph_t& _cg) : cg (_cg) {}
00048   std::ostream& operator() (std::ostream& stream, c_graph_t::edge_t e) {
00049     stream << "(" << source (e, cg) << ", " << target (e, cg) << ")";
00050     return stream;
00051   }
00052 };
00053 
00054 class write_edge_bool_op_t {
00055   const c_graph_t& cg;
00056 public:
00057   write_edge_bool_op_t (const c_graph_t& _cg) : cg (_cg) {}
00058   std::ostream& operator() (std::ostream& stream, std::pair<c_graph_t::edge_t,bool> eb) {
00059     c_graph_t::edge_t e= eb.first;
00060     stream << "((" << source (e, cg) << ", " << target (e, cg) << "), "
00061            << (eb.second ? "forward)" : "reverse)");
00062     return stream;
00063   }
00064 };
00065 
00066 class write_edge_name_op_t {
00067   const line_graph_t& lg;
00068   line_graph_t::const_evn_t  evn;
00069 public:
00070   write_edge_name_op_t (const line_graph_t& _lg) : lg (_lg) {
00071     evn= get(boost::vertex_name, lg); }
00072   std::ostream& operator() (std::ostream& stream, line_graph_t::edge_t e) {
00073     stream << '(' << evn[e].first << ", " << evn[e].second << ')';
00074     return stream;
00075   }
00076 };
00077 
00078 class write_face_op_t {
00079   const line_graph_t& lg;
00080   line_graph_t::const_evn_t  evn; 
00081 public:
00082   write_face_op_t (const line_graph_t& _lg) : lg (_lg) {
00083     evn= get(boost::vertex_name, lg); }
00084   std::ostream& operator() (std::ostream& stream, line_graph_t::face_t f) {
00085     line_graph_t::edge_t   ij= source (f, lg), jk= target (f, lg);
00086     int i= evn[ij].first, j= evn[ij].second, k= evn[jk].second;
00087     THROW_DEBUG_EXCEPT_MACRO (j != evn[jk].first, consistency_exception, "Adjacency corrupted in line graph"); 
00088     stream << '(' << i << ", " << j << ", " << k << ')';
00089     return stream;
00090   }
00091 };
00092 
00093 
00094 class write_face_number_op_t {
00095   const line_graph_t& lg;
00096 public:
00097   write_face_number_op_t (const line_graph_t& _lg) : lg (_lg) {}
00098   std::ostream& operator() (std::ostream& stream, line_graph_t::face_t f) {
00099     line_graph_t::edge_t   ij= source (f, lg), jk= target (f, lg);
00100     stream << '(' << ij << ", " << jk << ')';
00101     return stream;
00102   }
00103 };
00104 
00105 
00106 //                        Iterations
00107 // ===========================================================
00108 
00110 template <typename Ad_graph_t, typename Op_t>
00111 inline void for_all_edges (Ad_graph_t& adg, const Op_t& op) {
00112   typename graph_traits<Ad_graph_t>::edge_iterator  ei, e_end;
00113   for (tie (ei, e_end)= edges (adg); ei != e_end; ++ei)
00114     op (*ei, adg);
00115 }
00116 
00118 template <typename Ad_graph_t, typename Op_t>
00119 inline void for_all_edges (const Ad_graph_t& adg, Op_t& op) {
00120   typename graph_traits<Ad_graph_t>::edge_iterator  ei, e_end;
00121   for (tie (ei, e_end)= edges (adg); ei != e_end; ++ei)
00122     op (*ei, adg);
00123 }
00124 
00126 template <typename Ad_graph_t, typename Op_t>
00127 inline void for_all_in_edges (typename Ad_graph_t::vertex_descriptor v, 
00128                               Ad_graph_t& adg, const Op_t& op) {
00129   typename graph_traits<Ad_graph_t>::in_edge_iterator  iei, ie_end;
00130   for (tie (iei, ie_end)= in_edges (v, adg); iei != ie_end; ++iei)
00131     op (*iei, adg);
00132 }
00133 
00135 template <typename Ad_graph_t, typename Op_t>
00136 inline void for_all_out_edges (typename Ad_graph_t::vertex_descriptor v, 
00137                                Ad_graph_t& adg, const Op_t& op) {
00138   typename graph_traits<Ad_graph_t>::out_edge_iterator  oei, oe_end;
00139   for (tie (oei, oe_end)= out_edges (v, adg); oei != oe_end; ++oei)
00140     op (*oei, adg);
00141 }
00142 
00144 template <typename Ad_graph_t, typename Op_t>
00145 inline int sum_over_all_in_edges (typename Ad_graph_t::vertex_descriptor v, 
00146                                   Ad_graph_t& adg, const Op_t& op) {
00147   int value= 0;
00148   typename graph_traits<Ad_graph_t>::in_edge_iterator  iei, ie_end;
00149   for (tie (iei, ie_end)= in_edges (v, adg); iei != ie_end; ++iei)
00150     value+= op (*iei, adg);
00151   return value;
00152 }
00153 
00155 template <typename Ad_graph_t, typename Op_t>
00156 inline int sum_over_all_out_edges (typename Ad_graph_t::vertex_descriptor v, 
00157                                    const Ad_graph_t& adg, const Op_t& op) {
00158   int value= 0;
00159   typename graph_traits<Ad_graph_t>::out_edge_iterator  oei, oe_end;
00160   for (tie (oei, oe_end)= out_edges (v, adg); oei != oe_end; ++oei)
00161     value+= op (*oei, adg);
00162   return value;
00163 }
00164 
00166 template <typename Ad_graph_t>
00167 inline void successor_set (typename Ad_graph_t::vertex_descriptor v, 
00168                            const Ad_graph_t& adg, 
00169                            typename std::vector<typename Ad_graph_t::vertex_descriptor>& vec) {
00170   vec.resize (0); vec.reserve (out_degree (v, adg));
00171   typename graph_traits<Ad_graph_t>::out_edge_iterator  oei, oe_end;
00172   for (tie (oei, oe_end)= out_edges (v, adg); oei != oe_end; ++oei)
00173     vec.push_back (target (*oei, adg));
00174 }
00175 
00177 template <typename Ad_graph_t>
00178 inline void sorted_successor_set (typename Ad_graph_t::vertex_descriptor v, 
00179                                   const Ad_graph_t& adg, 
00180                                   typename std::vector<typename Ad_graph_t::vertex_descriptor>& vec) {
00181   successor_set (v, adg, vec);
00182   std::sort (vec.begin(), vec.end());
00183 }
00184 
00186 template <typename Ad_graph_t>
00187 inline void predecessor_set (typename Ad_graph_t::vertex_descriptor v, 
00188                              const Ad_graph_t& adg, 
00189                              typename std::vector<typename Ad_graph_t::vertex_descriptor>& vec) {
00190   vec.resize (0); vec.reserve (out_degree (v, adg));
00191   typename graph_traits<Ad_graph_t>::in_edge_iterator  iei, ie_end;
00192   for (tie (iei, ie_end)= in_edges (v, adg); iei != ie_end; ++iei)
00193     vec.push_back (source (*iei, adg));
00194 }
00195 
00197 template <typename Ad_graph_t>
00198 inline void sorted_predecessor_set (typename Ad_graph_t::vertex_descriptor v, 
00199                                     const Ad_graph_t& adg, 
00200                                     typename std::vector<typename Ad_graph_t::vertex_descriptor>& vec) {
00201   predecessor_set (v, adg, vec);
00202   std::sort (vec.begin(), vec.end());
00203 }
00204 
00206 bool reachable (const c_graph_t::vertex_t src,
00207                 const c_graph_t::vertex_t tgt,
00208                 c_graph_t& angelLCG);
00209 
00211 void vertex_upset (const c_graph_t::vertex_t v,
00212                    const c_graph_t& angelLCG,
00213                    vertex_set_t& upset);
00214 
00216 void vertex_downset (const c_graph_t::vertex_t v,
00217                      const c_graph_t& angelLCG,
00218                      vertex_set_t& downset);
00219 
00221 template <typename El_t>
00222 void unique_vector (std::vector<El_t>& v) {
00223   std::sort (v.begin(), v.end());
00224   typename vector<El_t>::iterator it= unique (v.begin(), v.end());
00225   v.resize (it-v.begin());
00226 }
00227 
00228 
00230 template <typename Ad_graph_t>
00231 inline void common_successors (typename Ad_graph_t::vertex_descriptor v, 
00232                                const Ad_graph_t& adg, 
00233                                typename std::vector<typename Ad_graph_t::vertex_descriptor>& vec) {
00234   typename graph_traits<Ad_graph_t>::out_edge_iterator  oei, oe_end;
00235   typename graph_traits<Ad_graph_t>::in_edge_iterator   iei, ie_end;
00236   for (tie (oei, oe_end)= out_edges (v, adg); oei != oe_end; ++oei)
00237     for (tie (iei, ie_end)= in_edges (target (*oei, adg), adg); iei != ie_end; ++iei)
00238       if (source (*iei, adg) != v)
00239         vec.push_back (source (*iei, adg));
00240   unique_vector (vec);
00241 }
00242 
00244 template <typename Ad_graph_t>
00245 inline void same_successors (typename Ad_graph_t::vertex_descriptor v, 
00246                              const Ad_graph_t& adg, 
00247                              typename std::vector<typename Ad_graph_t::vertex_descriptor>& vec) {
00248   typename graph_traits<Ad_graph_t>::out_edge_iterator      oei, oe_end;
00249   typename graph_traits<Ad_graph_t>::in_edge_iterator       iei, ie_end;
00250   typename std::vector<typename Ad_graph_t::vertex_descriptor>   sv, s;
00251  
00252   sorted_successor_set (v, adg, sv);
00253   for (tie (oei, oe_end)= out_edges (v, adg); oei != oe_end; ++oei)
00254     for (tie (iei, ie_end)= in_edges (target (*oei, adg), adg); iei != ie_end; ++iei)
00255       if (source (*iei, adg) != v) {
00256         sorted_successor_set (source (*iei, adg), adg, s);
00257         if (s == sv) vec.push_back (source (*iei, adg)); }
00258   unique_vector (vec);
00259 }
00260 
00262 template <typename Ad_graph_t>
00263 inline void common_predecessor (typename Ad_graph_t::vertex_descriptor v, 
00264                                 const Ad_graph_t& adg, 
00265                                 typename std::vector<typename Ad_graph_t::vertex_descriptor>& vec) {
00266   typename graph_traits<Ad_graph_t>::out_edge_iterator  oei, oe_end;
00267   typename graph_traits<Ad_graph_t>::in_edge_iterator   iei, ie_end;
00268   for (tie (iei, ie_end)= in_edges (v, adg); iei != ie_end; ++iei)
00269     for (tie (oei, oe_end)= out_edges (source (*iei, adg), adg); oei != oe_end; ++oei)
00270       if (target (*oei, adg) != v)
00271         vec.push_back (target (*oei, adg));
00272   unique_vector (vec);
00273 }
00274 
00276 template <typename Ad_graph_t>
00277 inline void same_predecessors (typename Ad_graph_t::vertex_descriptor v, 
00278                                const Ad_graph_t& adg, 
00279                                typename std::vector<typename Ad_graph_t::vertex_descriptor>& vec) {
00280   typename graph_traits<Ad_graph_t>::out_edge_iterator      oei, oe_end;
00281   typename graph_traits<Ad_graph_t>::in_edge_iterator       iei, ie_end;
00282   typename std::vector<typename Ad_graph_t::vertex_descriptor>   pv, p;
00283  
00284   sorted_predecessor_set (v, adg, pv);
00285   for (tie (iei, ie_end)= in_edges (v, adg); iei != ie_end; ++iei) 
00286     for (tie (oei, oe_end)= out_edges (source (*iei, adg), adg); oei != oe_end; ++oei) 
00287       if (target (*oei, adg) != v) {
00288         sorted_predecessor_set (target (*oei, adg), adg, p);
00289         if (p == pv) vec.push_back (target (*oei, adg)); }
00290   unique_vector (vec);
00291 }
00292 
00294 template <typename Ad_graph_t>
00295 inline void same_neighbors (typename Ad_graph_t::vertex_descriptor v, 
00296                             const Ad_graph_t& adg, 
00297                             typename std::vector<typename Ad_graph_t::vertex_descriptor>& vec) {
00298   typename std::vector<typename Ad_graph_t::vertex_descriptor> same_p, same_s;
00299   same_predecessors (v, adg, same_p); // same pred. as i
00300   same_successors (v, adg, same_s);
00301   vec.resize (std::max (same_p.size(), same_s.size()));
00302   typename std::vector<typename Ad_graph_t::vertex_descriptor>::iterator vend;
00303   vend= std::set_intersection (same_p.begin(), same_p.end(), same_s.begin(), same_s.end(), vec.begin());
00304   vec.resize (vend-vec.begin());
00305 }
00306 
00307 //                        Iterations
00308 // ===========================================================
00309 
00310 template<typename It_t, typename Op_t>
00311 std::ostream& write_iterators (std::ostream& stream, const std::string& s, 
00312                                It_t begin, It_t end, Op_t op) {
00313   stream << s << " = {";
00314   if (begin != end) op (stream, *begin++); 
00315   for (; begin != end; ++begin)
00316     stream << ", ", op (stream, *begin);
00317   stream << '}' << std::endl;
00318   return stream;
00319 }  
00320 
00321 //                      Others
00322 // ===========================================================
00323 
00324 // e is an edge of g1, same_egde return a pointer to 
00325 // the same edge (equal source and equal target) in g2 (or e_end)
00331 template <typename Ad_graph_t>
00332 inline typename graph_traits<Ad_graph_t>::edge_iterator
00333 same_edge (typename Ad_graph_t::edge_descriptor e,
00334            const Ad_graph_t& g1, const Ad_graph_t& g2) {
00335   typename graph_traits<Ad_graph_t>::edge_iterator ei, e_end;
00336   typename Ad_graph_t::vertex_descriptor s= source (e, g1), 
00337                                          t= target (e, g1);
00338   for (tie (ei, e_end)= edges (g2); ei != e_end; ++ei)
00339     if (source (*ei, g2) == s && target (*ei, g2) == t)
00340       return ei;
00341   return e_end; // not found
00342 }
00343 
00344 
00346 template <typename Ad_graph_t> 
00347 vertex_type_t vertex_type (typename Ad_graph_t::vertex_descriptor v, 
00348                            const Ad_graph_t& adg) {
00349   return adg.vertex_type (v); 
00350 }
00351 
00353 template <typename Ad_graph_t> 
00354 struct edge_equal_t : public std::binary_function<typename Ad_graph_t::edge_descriptor,
00355                                                   typename Ad_graph_t::edge_descriptor,bool> {
00356   const Ad_graph_t& g1;
00357   const Ad_graph_t& g2;
00359   edge_equal_t (const Ad_graph_t& _g1, const Ad_graph_t& _g2) : 
00360     g1 (_g1), g2 (_g2) {}
00362   bool operator() (typename Ad_graph_t::edge_descriptor e1,
00363                    typename Ad_graph_t::edge_descriptor e2) {
00364     typename Ad_graph_t::vertex_descriptor s1= source (e1, g1), s2= source (e2, g2);
00365     return s1 == s2 && target (e1, g1) == target (e2, g2);}
00366 };
00367 
00369 template <typename Ad_graph_t> 
00370 struct edge_less_t : public std::binary_function<typename Ad_graph_t::edge_descriptor,
00371                                             typename Ad_graph_t::edge_descriptor,bool> {
00372   const Ad_graph_t& g1;
00373   const Ad_graph_t& g2;
00375   edge_less_t (const Ad_graph_t& _g1, const Ad_graph_t& _g2) : 
00376     g1 (_g1), g2 (_g2) {}
00378   bool operator() (typename Ad_graph_t::edge_descriptor e1,
00379                    typename Ad_graph_t::edge_descriptor e2) {
00380     typename Ad_graph_t::vertex_descriptor s1= source (e1, g1), s2= source (e2, g2);
00381     return s1 < s2 || (s1 == s2 && target (e1, g1) < target (e2, g2));}
00382 };
00383 
00384 template <typename Ad_graph_t> 
00385 inline int count_parallel_edges (typename Ad_graph_t::edge_descriptor e, 
00386                                  const Ad_graph_t& g) {
00387   typename Ad_graph_t::vertex_descriptor s= source (e, g), t= target (e, g);
00388   typename graph_traits<Ad_graph_t>::out_edge_iterator oei, oe_end;
00389   int pe= 0;
00390   for (tie (oei, oe_end)= out_edges (s, g); oei != oe_end; oei++)
00391     if (target (*oei, g) == t) pe++;
00392   return pe;
00393 }
00394 
00396 c_graph_t::edge_t getEdge(unsigned int i,
00397                           unsigned int j,
00398                           const c_graph_t& angelLCG);
00399 
00400 // =====================================================
00401 // comparisons
00402 // =====================================================
00403 
00405 inline bool lex_greater (c_graph_t::edge_t e1, c_graph_t::edge_t e2,
00406                          const c_graph_t& cg) {
00407 
00408   c_graph_t::vertex_t s1= source (e1, cg), s2= source (e2, cg);
00409 
00410   return s1 > s2 || (s1 == s2 && target (e1, cg) >= target (e2, cg));
00411 
00412 }
00413 
00415 inline bool lex_less (c_graph_t::edge_t e1, c_graph_t::edge_t e2,
00416                       const c_graph_t& cg) {
00417 
00418   c_graph_t::vertex_t s1= source (e1, cg), s2= source (e2, cg);
00419 
00420   return s1 < s2 || (s1 == s2 && target (e1, cg) <= target (e2, cg));
00421 
00422 }
00423 
00425 inline bool inv_lex_greater (c_graph_t::edge_t e1, c_graph_t::edge_t e2,
00426                              const c_graph_t& cg) {
00427 
00428   c_graph_t::vertex_t s1= source (e1, cg), s2= source (e2, cg),
00429                       t1= target (e1, cg), t2= target (e2, cg); 
00430   return t1 > t2 || (t1 == t2 && s1 >= s2);
00431 }
00432 
00434 inline bool inv_lex_less (c_graph_t::edge_t e1, c_graph_t::edge_t e2,
00435                           const c_graph_t& cg) {
00436 
00437   c_graph_t::vertex_t s1= source (e1, cg), s2= source (e2, cg),
00438                       t1= target (e1, cg), t2= target (e2, cg);
00439   return t1 < t2 || (t1 == t2 && s1 <= s2); 
00440 }
00441 
00442 inline bool lex_greater (edge_bool_t eb1, edge_bool_t eb2, const c_graph_t& cg) {
00443 
00444   c_graph_t::edge_t   e1= eb1.first, e2= eb2.first;
00445   c_graph_t::vertex_t s1= source (e1, cg), s2= source (e2, cg), 
00446                        t1= target (e1, cg), t2= target (e2, cg); 
00447   bool                 f1= eb1.second, f2= eb2.second;
00448   c_graph_t::vertex_t j1= f1 ? t1 : s1, j2= f2 ? t2 : s2;
00449 
00450   // e1 is eliminated during vertex elimination of j1 (e2 resp.)
00451   if (j1 > j2) return true; else if (j1 < j2) return false;
00452 
00453   // prefer front elimination, rm 1
00454   if (f1 && !f2) return true; else if (!f1 && f2) return false;
00455   
00456   // f1==f2, start with front elimination
00457   if (f1) return s1 > s2; else return t1 > t2;
00458 }
00459 
00460 inline bool lex_less (edge_bool_t eb1, edge_bool_t eb2, const c_graph_t& cg) {
00461 
00462   c_graph_t::edge_t   e1= eb1.first, e2= eb2.first;
00463   c_graph_t::vertex_t s1= source (e1, cg), s2= source (e2, cg), 
00464                        t1= target (e1, cg), t2= target (e2, cg); 
00465   bool                 f1= eb1.second, f2= eb2.second;
00466   c_graph_t::vertex_t j1= f1 ? t1 : s1, j2= f2 ? t2 : s2;
00467 
00468   // e1 is eliminated during vertex elimination of j1 (e2 resp.)
00469   if (j1 < j2) return true; else if (j1 > j2) return false;
00470 
00471   // prefer front elimination, rm 1
00472   if (f1 && !f2) return true; else if (!f1 && f2) return false;
00473   
00474   // f1==f2, start with front elimination
00475   if (f1) return s1 < s2; else return t1 < t2;
00476 }
00477 
00478 bool lex_less_face (line_graph_t::face_t e1, line_graph_t::face_t e2,
00479                     const line_graph_t& lg);
00480 
00481 // to use lex_less_face with std::sort, see face_elimination_heuristic.cpp for an example
00482 class lex_less_face_line_t {
00483   const line_graph_t& lg;
00484 
00485 public:
00486   lex_less_face_line_t (const line_graph_t& g) : lg (g) {}
00487 
00488   bool operator() (const line_graph_t::face_t& e1,
00489                    const line_graph_t::face_t& e2) {
00490     return lex_less_face (e1, e2, lg); }
00491 };
00492 
00493 // same as lex_less_face_line_t, but for decreasing order in std::sort
00494 // it is supposed that faces do not occur twice, 
00495 // i.e. e1 != e2 iff (i,j,k)_1 != (i,j,k)_2,
00496 // so e1 > e2 iff not e1 < e2 
00497 class not_lex_less_face_line_t {
00498   const line_graph_t& lg;
00499 
00500 public:
00501   not_lex_less_face_line_t (const line_graph_t& g) : lg (g) {}
00502 
00503   bool operator() (const line_graph_t::face_t& e1,
00504                    const line_graph_t::face_t& e2) {
00505     return !lex_less_face (e1, e2, lg); }
00506 };
00507 
00508 // =====================================================
00509 // random number generators
00510 // =====================================================
00511 
00513 inline int random (int min, int max) {  
00514   return min + int (double (max-min+1)*rand() / (RAND_MAX+1.0)); }
00515 
00517 inline double random (double n) {
00518   return n*rand() / (RAND_MAX+1.0); }
00519 
00521 inline int random (int n) {
00522   return int (double (n)*rand() / (RAND_MAX+1.0)); }
00523 
00525 inline int random_high (int n, int exp= 2) {
00526   double tmp= rand() / (RAND_MAX+1.0);
00527   return int (double (n) * (1 - pow (tmp, exp))); }
00528 
00536 inline int random (const std::vector<double>& p) {
00537   size_t ps= p.size();
00538 #ifndef NDEBUG
00539   for (size_t j= 0; j < ps; j++)
00540     // assert (p[j] > 0.0 && p[j] <= 1.0);
00541     THROW_EXCEPT_MACRO (p[j] < 0.0 || p[j] > 1.0, consistency_exception, "p[i] not between 0 and 1");
00542   for (size_t j= 1; j < ps; j++)
00543     // assert (p[j-1] <= p[j]);
00544     THROW_EXCEPT_MACRO (p[j-1] > p[j], consistency_exception, "p[i] > p[i-1]");
00545   // assert (p[ps-1] == 1.0);
00546   THROW_EXCEPT_MACRO (p[ps-1] != 1.0, consistency_exception, "Last value must be 1");
00547 #endif
00548   double r= random (1.0);
00549   for (size_t j= 0; j < ps; j++)
00550     if (r < p[j]) return int (j);
00551   return int (ps);
00552 }
00553 
00554 
00555 // =====================================================
00556 // path lengths
00557 // =====================================================
00558 
00567 void in_out_path_lengths (const c_graph_t& cg,
00568                           std::vector<int>& vni, std::vector<int>& vli, 
00569                           std::vector<int>& vno, std::vector<int>& vlo);
00570 
00571 // =====================================================
00572 // find nodes in line graph that correspond to edge (i,j) in c-graph
00573 // =====================================================
00574 
00576 inline bool find_edge (int s, int t, const line_graph_t& lg, 
00577                        std::vector<line_graph_t::edge_t>& ev) {
00578   ev.resize (0);
00579   line_graph_t::const_evn_t evn= get(boost::vertex_name, lg);
00580   line_graph_t::ei_t        ei, eend;
00581   for (tie (ei, eend)= vertices (lg); ei != eend; ++ei) 
00582     if (evn[*ei].first == s && evn[*ei].second == t) ev.push_back (*ei);
00583   return !ev.empty();
00584 }
00585 
00586 // =====================================================
00587 // test whether c-/line graph is bi-/tri-partite
00588 // =====================================================
00589 
00591 inline bool is_bipartite (const c_graph_t& cg) {
00592   c_graph_t::ei_t     ei, e_end;
00593   for (tie(ei, e_end) = edges (cg); ei != e_end; ++ei)
00594     if (vertex_type (source (*ei, cg), cg) != independent 
00595         || vertex_type (target (*ei, cg), cg) != dependent)
00596       return false;
00597   return true;
00598 }
00599 
00601 inline bool is_tripartite (const line_graph_t& lg) {
00602   line_graph_t::fi_t     fi, f_end;
00603   for (tie(fi, f_end) = edges (lg); fi != f_end; ++fi)
00604     if (vertex_type (source (*fi, lg), lg) != independent 
00605         && vertex_type (target (*fi, lg), lg) != dependent)
00606       return false;
00607   return true;
00608 }
00609 
00610 // =====================================================
00611 // vertex properties
00612 // =====================================================
00613 
00615 void number_dependent_vertices (const c_graph_t& cg, std::vector<int>& v);
00616 
00618 void number_independent_vertices (const c_graph_t& cg, std::vector<int>& v);
00619 
00625 template <typename Ad_graph_t> 
00626 void reachable_vertices (const Ad_graph_t& adg, std::vector<bool>& rv) {
00627 
00628   typedef typename Ad_graph_t::vertex_descriptor                         vertex_t;
00629   typedef typename graph_traits<Ad_graph_t>::vertex_iterator      vi_t;
00630   typedef typename graph_traits<Ad_graph_t>::adjacency_iterator   ai_t;
00631 
00632   rv.resize (num_vertices (adg));
00633   std::fill (rv.begin(), rv.end(), false);
00634 
00635   typename std::queue<vertex_t> q;
00636   vi_t                          vi, v_end;
00637   int                           c;
00638   // all independent vertices are reachable and inserted into the queue
00639   for (tie(vi, v_end)= vertices(adg), c= 0; c < adg.x() && vi != v_end; ++c, ++vi) {
00640     rv[*vi]= true; q.push (*vi); }
00641 
00642   // search for reachable (intermediate and dependent) vertices
00643   while (!q.empty()) {
00644     vertex_t v= q.front();
00645     ai_t ai, a_end;
00646     for (tie(ai, a_end)= adjacent_vertices(v, adg); ai != a_end; ++ai)
00647       if (!rv[*ai]) {
00648         rv[*ai]= true; q.push (*ai); }
00649     q.pop(); }
00650 }       
00651 
00657 template <typename Ad_graph_t> 
00658 void relevant_vertices (const Ad_graph_t& adg, std::vector<bool>& rv) {
00659 
00660   typedef typename Ad_graph_t::vertex_descriptor               vertex_t;
00661   typedef typename graph_traits<Ad_graph_t>::vertex_iterator   vi_t;
00662   typedef typename graph_traits<Ad_graph_t>::in_edge_iterator  ie_t;
00663 
00664   rv.resize (num_vertices (adg));
00665   std::fill (rv.begin(), rv.end(), false);
00666 
00667   typename std::queue<vertex_t> q;
00668   // all dependent vertices are relevant and inserted into the queue
00669   for (size_t i= 0; i < adg.dependents.size(); i++) {
00670     vertex_t v= adg.dependents[i];
00671     rv[v]= true; q.push (v); }
00672 
00673   // search for relevant (intermediate and independent) vertices
00674   while (!q.empty()) {
00675     vertex_t v= q.front();
00676     ie_t     iei, ie_end;
00677     for (tie(iei, ie_end)= in_edges(v, adg); iei != ie_end; ++iei) {
00678       vertex_t vin= source (*iei, adg);
00679       if (!rv[vin]) {
00680         rv[vin]= true; q.push (vin); } }
00681     q.pop();  }
00682 }
00683 
00684 template <typename Neighbor_t>
00685 bool search_path (const std::vector<c_graph_t::vertex_t>& from, 
00686                   const std::vector<c_graph_t::vertex_t>& to, const Neighbor_t& n,
00687                   std::vector<c_graph_t::vertex_t>& path,
00688                   bool breadth_first= false);
00689 
00690 template <typename Neighbor_t>
00691 int maximal_paths (c_graph_t::vertex_t v, const Neighbor_t& nin, 
00692                    std::vector<std::vector<c_graph_t::vertex_t> >& paths);
00693 
00694 template <typename Neighbor_t>
00695 inline int minimal_in_out_degree (c_graph_t::vertex_t v, const Neighbor_t& nin) {
00696   std::vector<std::vector<c_graph_t::vertex_t> >    all_paths;
00697   return maximal_paths (v, nin, all_paths);
00698 }
00699 
00701 inline void minimal_markowitz_degree (const c_graph_t& cg, std::vector<int>& v) {
00702   v.resize (cg.v());
00703   predecessor_t<c_graph_t> pred (cg);
00704   successor_t<c_graph_t>   succ (cg);
00705   c_graph_t::vi_t          vi, v_end;
00706   for (tie (vi, v_end)= vertices (cg); vi != v_end; ++vi) {
00707     if (vertex_type (*vi, cg) == intermediate)
00708       v[*vi]= minimal_in_out_degree (*vi, pred) * minimal_in_out_degree (*vi, succ); }
00709 }
00710 
00712 inline int overall_minimal_markowitz_degree (const c_graph_t& cg) {
00713   std::vector<int> v;
00714   minimal_markowitz_degree (cg, v);
00715   return std::accumulate (v.begin(), v.end(), 0);
00716 }  
00717 
00718 
00719 // =====================================================
00720 // graph transformations
00721 // =====================================================
00722 
00724 void permutate_vertices (const c_graph_t& gin, const std::vector<c_graph_t::vertex_t>& p,
00725                          c_graph_t& gout);
00726 
00728 void independent_vertices_to_front (const c_graph_t& gin, 
00729                                     const std::vector<c_graph_t::vertex_t>& indeps,
00730                                     c_graph_t& gout);
00731 
00733 inline void put_unit_vertex_weight (line_graph_t& lg) {
00734   line_graph_t::ed_t  ed= get(boost::vertex_degree, lg);
00735   line_graph_t::ei_t  ei, eend;
00736   for (tie(ei, eend) = vertices (lg); ei != eend; ++ei) ed[*ei]= 1;
00737 }
00738 
00740 inline void put_unit_edge_weight (c_graph_t& cg) {
00741   c_graph_t::ew_t     ew= get(boost::edge_weight, cg);
00742   c_graph_t::ei_t     ei, eend;
00743   for (tie(ei, eend) = edges (cg); ei != eend; ++ei) ew[*ei]= 1;
00744 }
00745 
00747 int renumber_edges (c_graph_t& cg);
00748 
00749 // v2 take over the successors of v1
00750 // - v1 is a vertex of g1 and v2 is a vertex of g2
00751 // - each successor of v1 has an equivalent in g2
00752 //   such that the indices of both vertices differ by offset
00753 // - edge_number is read and updated
00754 // - useful to compose graphs, e.g. in stats2block
00755 //
00756 void take_over_successors (c_graph_t::vertex_t v1, c_graph_t::vertex_t v2, 
00757                            int offset, const c_graph_t& g1,  
00758                            int& edge_number, c_graph_t& g2);
00759 
00760 
00761 // -----------------------------------------------------
00762 // remove irrelevant and unreachable edges
00763 // -----------------------------------------------------
00764 //
00765 // remove_irrelevant_edges removes all in-edges of vertix 'i' if 'i' has no out-edges
00766 //   and continues, in this case, recursively with the predecessors of 'i'
00767 // remove_unreachable_edges removes all out-edges of vertix 'i' if 'i' has no in-edges
00768 //   and continues, in this case, recursively with the successors of 'i'
00769 // remove_edges does both
00770 // all functions return the number of removed edges
00771 // the set of removed edges is not complete, e.g. 'i' may have out-edges but no path to 
00772 //   dependent nodes
00773 //
00774 
00780 template <typename Ad_graph_t>
00781 int remove_irrelevant_edges (typename Ad_graph_t::vertex_descriptor i, 
00782                              Ad_graph_t& adg, bool fast= false) {
00783   typedef typename Ad_graph_t::vertex_descriptor               vertex_t;
00784   typedef typename graph_traits<Ad_graph_t>::in_edge_iterator  iei_t;
00785 
00786   if (fast) {
00787     int e= in_degree (i, adg);
00788     if (out_degree (i, adg) == 0) {
00789       clear_vertex (i, adg);
00790       return e; }
00791     else return 0; }
00792 
00793   int nre= 0; // number of removed edges
00794   typename std::queue<vertex_t> q;
00795   q.push (i);
00796 
00797   while (!q.empty()) {
00798     vertex_t v= q.front();
00799     if (out_degree (v, adg) == 0) {
00800       iei_t iei, ie_end;
00801       for (tie (iei, ie_end)= in_edges (v, adg); iei != ie_end; ) {
00802         q.push (source (*iei, adg));
00803         remove_edge (*iei, adg); 
00804         nre++;
00805         tie (iei, ie_end)= in_edges (v, adg); // now without first in-edge
00806       }
00807     }
00808     q.pop(); }
00809   return nre;
00810 }
00811 
00817 template <typename Ad_graph_t>
00818 int remove_unreachable_edges (typename Ad_graph_t::vertex_descriptor i, 
00819                               Ad_graph_t& adg, bool fast= false) {
00820   typedef typename Ad_graph_t::vertex_descriptor                  vertex_t;
00821   typedef typename graph_traits<Ad_graph_t>::out_edge_iterator    oei_t;
00822 
00823   if (fast) {
00824     int e= out_degree (i, adg);
00825     if (in_degree (i, adg) == 0) {
00826       clear_vertex (i, adg);
00827       return e; }
00828     else return 0; }
00829 
00830   int nre= 0; // number of removed edges
00831   typename std::queue<vertex_t> q;
00832   q.push (i);
00833 
00834   while (!q.empty()) {
00835     vertex_t v= q.front();
00836     if (in_degree (v, adg) == 0) {
00837       oei_t oei, oe_end;
00838       for (tie (oei, oe_end)= out_edges (v, adg); oei != oe_end; ) {
00839         q.push (target (*oei, adg));
00840         remove_edge (oei, adg); // iterator is faster than edge itself
00841         nre++;
00842         tie (oei, oe_end)= out_edges (v, adg); // now without first out-edge
00843       }
00844     }
00845     q.pop(); }
00846   return nre;
00847 }
00848 
00850 template <typename Ad_graph_t>
00851 inline int remove_edges (typename Ad_graph_t::vertex_descriptor i, 
00852                          Ad_graph_t& adg) {
00853   return remove_irrelevant_edges (i, adg)
00854          + remove_unreachable_edges (i, adg);
00855 }
00856 
00857 // -----------------------------------------------------
00858 // clear graph
00859 // -----------------------------------------------------
00860 
00861 template <typename vertex_t>
00862 struct dec_greater : public std::unary_function<vertex_t, void> {
00863   vertex_t vc;
00864   dec_greater (vertex_t _vc) : vc (_vc) {}
00865   void operator() (vertex_t& v) {if (v > vc) v--;}
00866 };
00867 
00868 // clear_graph is member function of c_graph_t and line_graph_t either
00869 
00870 // -----------------------------------------------------
00871 // some preprocessing removals
00872 // -----------------------------------------------------
00873 
00875 int remove_hoisting_vertices (c_graph_t& cg);
00876 
00883 void remove_parallel_edges (c_graph_t& cg);
00884 
00886 void remove_trivial_edges (c_graph_t& cg);
00887 
00889 template <class operand_t>
00890 struct empty_operator_t {
00891   void operator() (const operand_t&) {}
00892   void operator() (operand_t&) {}
00893 };
00894 
00896 inline size_t block_begin (size_t i, size_t p, size_t n) {
00897   return i * (n/p) + std::min (i, n%p); }
00898 
00899 // =====================================================
00900 // Functions for simulated annealing for partial accumulation (scarcity exploitation)
00901 // =====================================================
00902 
00906 double gen_prob();
00907 
00912 unsigned int chooseTarget_sa(std::vector<double>& deltaE);
00913 
00914 int chooseEdgeElimRandomly(std::vector<double>& deltaE);
00915 int chooseEdgeElimRandomlyGreedy(std::vector<double>& deltaE);
00916 
00917 } // namespace angel
00918 
00919 
00920 #endif  // _angel_tools_include_
00921 

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