00001
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
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
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);
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
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
00322
00323
00324
00325
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;
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
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
00451 if (j1 > j2) return true; else if (j1 < j2) return false;
00452
00453
00454 if (f1 && !f2) return true; else if (!f1 && f2) return false;
00455
00456
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
00469 if (j1 < j2) return true; else if (j1 > j2) return false;
00470
00471
00472 if (f1 && !f2) return true; else if (!f1 && f2) return false;
00473
00474
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
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
00494
00495
00496
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
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
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
00544 THROW_EXCEPT_MACRO (p[j-1] > p[j], consistency_exception, "p[i] > p[i-1]");
00545
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
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
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
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
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
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
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
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
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
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
00750
00751
00752
00753
00754
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
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772
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;
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);
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;
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);
00841 nre++;
00842 tie (oei, oe_end)= out_edges (v, adg);
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
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
00869
00870
00871
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
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 }
00918
00919
00920 #endif // _angel_tools_include_
00921