00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044 # ifndef TPL_GRAPH_UTILS_H
00045 # define TPL_GRAPH_UTILS_H
00046
00047 # include <ahPair.H>
00048 # include <tpl_graph.H>
00049 # include <tpl_dynListQueue.H>
00050
00051 using namespace Aleph;
00052
00053 namespace Aleph {
00054
00055 template <class GT> inline static bool
00056 __depth_first_traversal(GT & g,
00057 typename GT::Node * node,
00058 typename GT::Arc * arc,
00059 bool (*visit)(GT & g,
00060 typename GT::Node *,
00061 typename GT::Arc *),
00062 size_t & count);
00093 template <class GT> inline
00094 size_t depth_first_traversal(GT & g,
00095 typename GT::Node * start_node,
00096 bool (*visit)(GT & g, typename GT::Node *,
00097 typename GT::Arc *) )
00098 {
00099 g.reset_bit_nodes(Depth_First);
00100 g.reset_bit_arcs(Depth_First);
00101
00102 size_t counter = 0;
00103
00104
00105 __depth_first_traversal <GT> (g, start_node, NULL, visit, counter);
00106
00107 return counter;
00108 }
00142 template <class GT> inline
00143 size_t depth_first_traversal(GT & g,
00144 bool (*visit)(GT &, typename GT::Node *,
00145 typename GT::Arc *) )
00146 {
00147
00148 return depth_first_traversal <GT> (g, g.get_first_node(), visit);
00149 }
00150 template <class GT> inline static bool
00151 __depth_first_traversal(GT & g,
00152 typename GT::Node * node,
00153 typename GT::Arc * arc,
00154 bool (*visit)(GT & g,
00155 typename GT::Node *,
00156 typename GT::Arc *),
00157 size_t & count)
00158 {
00159 if (IS_NODE_VISITED(node, Depth_First))
00160 return false;
00161
00162 NODE_BITS(node).set_bit(Depth_First, true);
00163 count++;
00164
00165
00166
00167 if (visit != NULL)
00168 if ((*visit)(g, node, arc))
00169 return true;
00170
00171
00172
00173 for (typename GT::Node_Arc_Iterator it(node); it.has_current(); it.next())
00174 {
00175 typename GT::Arc * arc = it.get_current_arc();
00176
00177 if (IS_ARC_VISITED(arc, Depth_First))
00178 continue;
00179
00180 ARC_BITS(arc).set_bit(Depth_First, true);
00181
00182 if (__depth_first_traversal(g, it.get_tgt_node(), arc, visit, count))
00183 return true;
00184 }
00185
00186 return false;
00187 }
00220 template <class GT> inline size_t
00221 breadth_first_traversal(GT & g,
00222 typename GT::Node * start,
00223 bool (*visit)(GT &, typename GT::Node *,
00224 typename GT::Arc *) )
00225 {
00226 g.reset_bit_nodes(Breadth_First);
00227 g.reset_bit_arcs(Breadth_First);
00228
00229 DynListQueue<typename GT::Arc*> q;
00230
00231
00232 for (typename GT::Node_Arc_Iterator it(start); it.has_current(); it.next())
00233 q.put(it.get_current_arc());
00234
00235 NODE_BITS(start).set_bit(Breadth_First, true);
00236
00237 size_t node_counter = 0;
00238
00239
00240
00241 while (not q.is_empty() and node_counter < g.get_num_nodes())
00242 {
00243 typename GT::Arc * arc = q.get();
00244
00245 ARC_BITS(arc).set_bit(Breadth_First, true);
00246
00247
00248 typename GT::Node * src = g.get_src_node(arc);
00249 typename GT::Node * tgt = g.get_tgt_node(arc);
00250
00251 if (IS_NODE_VISITED(src, Breadth_First) and
00252 IS_NODE_VISITED(tgt, Breadth_First))
00253 continue;
00254
00255
00256 typename GT::Node * visit_node =
00257 IS_NODE_VISITED(src, Breadth_First) ? tgt : src;
00258
00259
00260
00261 if (visit not_eq NULL)
00262 if ((*visit)(g, visit_node, arc))
00263 break;
00264
00265
00266 NODE_BITS(visit_node).set_bit(Breadth_First, true);
00267 node_counter++;
00268
00269
00270 for (typename GT::Node_Arc_Iterator it(visit_node);
00271 it.has_current(); it.next())
00272 {
00273 typename GT::Arc * curr_arc = it.get_current_arc();
00274
00275 if (IS_ARC_VISITED(curr_arc, Breadth_First))
00276 continue;
00277
00278
00279 if (IS_NODE_VISITED(g.get_src_node(curr_arc), Breadth_First) and
00280 IS_NODE_VISITED(g.get_tgt_node(curr_arc), Breadth_First))
00281 continue;
00282
00283 q.put(curr_arc);
00284 }
00285 }
00286
00287 return node_counter;
00288 }
00324 template <class GT> inline size_t
00325 breadth_first_traversal(GT & g,
00326 bool (*visit)(GT &, typename GT::Node *,
00327 typename GT::Arc *)
00328 )
00329 {
00330 return breadth_first_traversal(g, g.get_first_node(), visit);
00331 }
00332 template <class GT> inline static
00333 void __insert_in_queue(GT & g,
00334 DynListQueue<Path<GT> *> & q,
00335 typename GT::Node * node,
00336 typename GT::Arc * arc,
00337 Path<GT> * path_ptr = NULL)
00338 {
00339 auto_ptr<Path<GT> > path_auto;
00340
00341 if (path_ptr == NULL)
00342 path_auto =
00343 auto_ptr<Path<GT> > ( new Path<GT> (g, node) );
00344 else
00345 path_auto =
00346 auto_ptr<Path<GT> > ( new Path<GT> (*path_ptr) );
00347
00348 path_auto->append(arc);
00349
00350 q.put(path_auto.get());
00351
00352 path_auto.release();
00353 }
00376 template <class GT> inline
00377 bool find_path_breadth_first(GT& g,
00378 typename GT::Node * start,
00379 typename GT::Node * end,
00380 Path<GT> & path)
00381 {
00382
00383 if (not path.inside_graph(g))
00384 throw std::invalid_argument("Path does not belong to graph");
00385
00386 path.clear_path();
00387
00388 g.reset_bit_nodes(Find_Path);
00389 g.reset_bit_arcs(Find_Path);
00390
00391 DynListQueue<Path<GT>*> q;
00392 Path<GT> * path_ptr = NULL;
00393
00394
00395 try
00396 {
00397
00398
00399 for (typename GT::Node_Arc_Iterator i(start); i.has_current(); i.next())
00400 __insert_in_queue<GT>(g, q, start, i.get_current_arc());
00401
00402 NODE_BITS(start).set_bit(Find_Path, true);
00403
00404 while (not q.is_empty())
00405 {
00406 path_ptr = q.get();
00407
00408 typename GT::Arc * arc = path_ptr->get_last_arc();
00409
00410 ARC_BITS(arc).set_bit(Find_Path, true);
00411
00412 typename GT::Node * tgt = path_ptr->get_last_node();
00413
00414 if (IS_NODE_VISITED(tgt, Find_Path))
00415 {
00416 delete path_ptr;
00417 continue;
00418 }
00419
00420 if (tgt == end)
00421 {
00422 path.swap(*path_ptr);
00423
00424 while (not q.is_empty())
00425 delete q.get();
00426
00427 delete path_ptr;
00428
00429 return true;
00430 }
00431
00432 NODE_BITS(tgt).set_bit(Find_Path, true);
00433
00434
00435 for (typename GT::Node_Arc_Iterator i(tgt); i.has_current(); i.next())
00436 {
00437 typename GT::Arc * curr_arc = i.get_current_arc();
00438
00439 if (IS_ARC_VISITED(curr_arc, Find_Path))
00440 continue;
00441
00442
00443 if (IS_NODE_VISITED(g.get_src_node(curr_arc), Find_Path) and
00444 IS_NODE_VISITED(g.get_tgt_node(curr_arc), Find_Path))
00445 continue;
00446
00447 __insert_in_queue<GT>(g, q, NULL, curr_arc, path_ptr);
00448 }
00449
00450 delete path_ptr;
00451 }
00452
00453 }
00454 catch (...)
00455 {
00456 while (not q.is_empty())
00457 delete q.get();
00458
00459 delete path_ptr;
00460
00461 throw;
00462 }
00463
00464
00465 while (not q.is_empty())
00466 delete q.get();
00467
00468 delete path_ptr;
00469
00470 return false;
00471 }
00489 template <class GT> inline
00490 bool test_connectivity(GT & g)
00491 {
00492
00493 if (not g.is_digraph() and g.get_num_arcs() < g.get_num_nodes() - 1)
00494 return false;
00495
00496 return depth_first_traversal <GT> (g, NULL) == g.get_num_nodes();
00497 }
00519 template <class GT>
00520 bool is_reachable(GT & g, typename GT::Node * src, typename GT::Node * tgt)
00521 {
00522
00523 if (not g.is_digraph())
00524 throw std::domain_error("g is not a digraph");
00525
00526 return test_path(g, src, tgt);
00527 }
00528 template <class GT> inline static
00529 bool __test_cycle(GT & g,
00530 typename GT::Node * src_node,
00531 typename GT::Node * curr_node);
00549 template <class GT> inline
00550 bool test_cycle(GT & g, typename GT::Node * src_node)
00551 {
00552 g.reset_bit_nodes(Test_Cycle);
00553 g.reset_bit_arcs(Test_Cycle);
00554
00555
00556 for (typename GT::Node_Arc_Iterator it(src_node); it.has_current(); it.next())
00557 {
00558 typename GT::Arc * arc = it.get_current_arc();
00559
00560 if (IS_ARC_VISITED(arc, Test_Cycle))
00561 continue;
00562
00563 ARC_BITS(arc).set_bit(Test_Cycle, true);
00564
00565
00566 if (__test_cycle <GT> (g, src_node, it.get_tgt_node()))
00567 return true;
00568 }
00569
00570
00571 return false;
00572 }
00573 template <class GT> inline static
00574 bool __test_cycle(GT & g,
00575 typename GT::Node * src_node,
00576 typename GT::Node * curr_node)
00577 {
00578 if (src_node == curr_node)
00579 return true;
00580
00581 if (IS_NODE_VISITED(curr_node, Test_Cycle))
00582 return false;
00583
00584 NODE_BITS(curr_node).set_bit(Test_Cycle, true);
00585
00586
00587 for (typename GT::Node_Arc_Iterator it(curr_node); it.has_current();
00588 it.next())
00589 {
00590 typename GT::Arc * arc = it.get_current_arc();
00591
00592 if (IS_ARC_VISITED(arc, Test_Cycle))
00593 continue;
00594
00595 ARC_BITS(arc).set_bit(Test_Cycle, true);
00596
00597 if (__test_cycle <GT> (g, src_node, it.get_tgt_node()))
00598 return true;
00599 }
00600
00601
00602 return false;
00603 }
00604 template <typename GT> inline static
00605 bool __is_acyclique(GT & g, typename GT::Node * curr_node)
00606 {
00607 if (IS_NODE_VISITED(curr_node, Is_Acyclique))
00608 return false;
00609
00610 NODE_BITS(curr_node).set_bit(Is_Acyclique, true);
00611
00612
00613 for (typename GT::Node_Arc_Iterator i(curr_node); i.has_current(); i.next())
00614 {
00615 typename GT::Arc * arc = i.get_current_arc();
00616
00617 if (IS_ARC_VISITED(arc, Is_Acyclique))
00618 continue;
00619
00620 ARC_BITS(arc).set_bit(Is_Acyclique, true);
00621
00622
00623 if (not __is_acyclique(g, i.get_tgt_node()))
00624 return false;
00625 }
00626
00627
00628 return true;
00629 }
00655 template <typename GT> inline
00656 bool is_acyclique(GT & g, typename GT::Node * start_node)
00657 {
00658 if (not g.is_digraph() and g.get_num_arcs() >= g.get_num_nodes())
00659 return false;
00660
00661 g.reset_bit_arcs(Is_Acyclique);
00662 g.reset_bit_nodes(Is_Acyclique);
00663
00664 return __is_acyclique(g, start_node);
00665 } template <typename GT> inline
00690 bool is_acyclique(GT & g)
00691 {
00692 if (not g.is_digraph() and g.get_num_arcs() >= g.get_num_nodes())
00693 return false;
00694
00695 g.reset_bit_arcs(Is_Acyclique);
00696 g.reset_bit_nodes(Is_Acyclique);
00697
00698
00699 for (typename GT::Node_Iterator it(g); it.has_current(); it.next())
00700 {
00701 typename GT::Node * current_node = it.get_current_node();
00702
00703 if (IS_NODE_VISITED(current_node, Is_Acyclique))
00704 continue;
00705
00706
00707 if (not __is_acyclique(g, current_node))
00708 return false;
00709 }
00710 return true;
00711 }
00735 template <typename GT> inline bool has_cycle(GT & g)
00736 {
00737 return not is_acyclique(g);
00738 }
00739 template <class GT> inline static
00740 bool __test_path(GT& g,
00741 typename GT::Node * curr_node,
00742 typename GT::Node * end_node);
00762 template <class GT> inline
00763 bool test_path(GT& g,
00764 typename GT::Node * start_node,
00765 typename GT::Node * end_node)
00766 {
00767
00768 if (not g.is_digraph() and g.get_num_arcs() >= g.get_num_nodes())
00769 return true;
00770
00771 g.reset_bit_nodes(Test_Path);
00772 g.reset_bit_arcs(Test_Path);
00773
00774
00775 for (typename GT::Node_Arc_Iterator i(start_node); i.has_current(); i.next())
00776 {
00777 typename GT::Arc * arc = i.get_current_arc();
00778
00779 ARC_BITS(arc).set_bit(Test_Path, true);
00780
00781
00782 if (__test_path(g, i.get_tgt_node(), end_node))
00783 return true;
00784 }
00785
00786
00787 return false;
00788 }
00789 template <class GT> inline static
00790 bool __test_path(GT & g,
00791 typename GT::Node * curr_node,
00792 typename GT::Node * end_node)
00793 {
00794 if (curr_node == end_node)
00795 return true;
00796
00797 if (IS_NODE_VISITED(curr_node, Test_Path))
00798 return false;
00799
00800 NODE_BITS(curr_node).set_bit(Test_Path, true);
00801
00802
00803 for (typename GT::Node_Arc_Iterator i(curr_node); i.has_current(); i.next())
00804 {
00805 typename GT::Arc * arc = i.get_current_arc();
00806
00807 if (IS_ARC_VISITED(arc, Test_Path))
00808 continue;
00809
00810 ARC_BITS(arc).set_bit(Test_Path, true);
00811
00812
00813 if (__test_path <GT> (g, i.get_tgt_node(), end_node))
00814 return true;
00815 }
00816
00817
00818 return false;
00819 }
00820 template <class GT> inline
00821 void inconnected_components(GT & g, DynDlist<GT> & list);
00822 template <class GT> inline
00823 void build_subgraph(GT & g,
00824 GT & sg,
00825 typename GT::Node * g_src,
00826 size_t & node_count);
00853 template <class GT> inline
00854 void inconnected_components(GT & g, DynDlist <GT> & list)
00855 {
00856 g.reset_nodes();
00857 g.reset_arcs();
00858
00859 size_t count = 0;
00860
00861
00862 for (typename GT::Node_Iterator i(g);
00863 count < g.get_num_nodes() and i.has_current(); i.next())
00864 {
00865 typename GT::Node * curr_node = i.get_current_node();
00866
00867 if (IS_NODE_VISITED(curr_node, Build_Subtree))
00868 continue;;
00869
00870
00871
00872 list.append(GT());
00873
00874 GT & subgraph = list.get_last();
00875
00876
00877
00878 build_subgraph(g, subgraph, curr_node, count);
00879 }
00880 }
00911 template <class GT> inline
00912 void build_subgraph(GT & g,
00913 GT & sg,
00914 typename GT::Node * g_src,
00915 size_t & node_count)
00916 {
00917
00918 if (sg.get_num_nodes() != 0)
00919 throw std::domain_error("sg is not empty");
00920
00921 if (IS_NODE_VISITED(g_src, Build_Subtree))
00922 return;
00923
00924 NODE_BITS(g_src).set_bit(Build_Subtree, true);
00925 ++node_count;
00926
00927 typename GT::Node * sg_src =
00928 static_cast<typename GT::Node *>(NODE_COOKIE(g_src));
00929
00930 if (sg_src == NULL)
00931 {
00932 sg_src = sg.insert_node(g_src->get_info());
00933 GT::map_nodes(g_src, sg_src);
00934 }
00935
00936
00937 for (typename GT::Node_Arc_Iterator i(g_src);
00938 node_count < g.get_num_nodes() and i.has_current(); i.next())
00939 {
00940 typename GT::Arc * arc = i.get_current_arc();
00941
00942 if (IS_ARC_VISITED(arc, Build_Subtree))
00943 continue;
00944
00945 ARC_BITS(arc).set_bit(Build_Subtree, true);
00946
00947
00948 typename GT::Node * g_tgt = i.get_tgt_node();
00949 typename GT::Node * sg_tgt =
00950 static_cast<typename GT::Node *>(NODE_COOKIE(g_tgt));
00951
00952 if (sg_tgt == NULL)
00953 {
00954 sg_tgt = sg.insert_node(g_tgt->get_info());
00955 GT::map_nodes(g_tgt, sg_tgt);
00956 }
00957
00958
00959 typename GT::Arc * sg_arc =
00960 sg.insert_arc(sg_src, sg_tgt, arc->get_info());
00961
00962 GT::map_arcs(arc, sg_arc);
00963
00964
00965 build_subgraph(g, sg, g_tgt, node_count);
00966 }
00967 }
00995 template <class GT> inline
00996 void strongly_connected_components(GT & g, DynDlist <GT> & list)
00997 {
00998
00999 if (not g.is_digraph())
01000 throw std::domain_error("g is not a digraph");
01001
01002 inconnected_components(g, list);
01003 }
01032 template <class GT> inline
01033 bool find_depth_first_spanning_tree(GT & g,
01034 typename GT::Node * gnode,
01035 GT & tree)
01036 {
01037 g.reset_nodes();
01038 g.reset_arcs();
01039
01040 tree.clear_graph();
01041
01042 NODE_BITS(gnode).set_bit(Spanning_Tree, true);
01043
01044
01045 typename GT::Node * tnode = tree.insert_node(gnode->get_info());
01046 GT::map_nodes(gnode, tnode);
01047 for (typename GT::Node_Arc_Iterator i(gnode); i.has_current(); i.next())
01048 {
01049 typename GT::Arc * arc = i.get_current_arc();
01050
01051 if (IS_ARC_VISITED(arc, Spanning_Tree))
01052 continue;
01053
01054 typename GT::Node * arc_tgt_node = i.get_tgt_node();
01055
01056 if (IS_NODE_VISITED(arc_tgt_node, Spanning_Tree))
01057 continue;
01058
01059 if (__find_depth_first_spanning_tree(g, arc_tgt_node, arc, tree, tnode))
01060 return false;
01061 }
01062
01063 return true;
01064 }
01091 template <class GT> inline
01092 typename GT::Node * find_depth_first_spanning_tree(GT & g, GT & tree)
01093 {
01094 typename GT::Node * start_node = g.get_first_node();
01095
01096 if (not find_depth_first_spanning_tree(g, start_node, tree))
01097 return NULL;
01098
01099 return start_node;
01100 }
01101 template <class GT> inline static
01102 bool __find_depth_first_spanning_tree(GT & g,
01103 typename GT::Node * gnode,
01104 typename GT::Arc * garc,
01105 GT & tree,
01106 typename GT::Node * tnode)
01107 {
01108 NODE_BITS(gnode).set_bit(Spanning_Tree, true);
01109 ARC_BITS(garc).set_bit(Spanning_Tree, true);
01110
01111
01112 typename GT::Node * tree_tgt_node = tree.insert_node(gnode->get_info());
01113 GT::map_nodes(gnode, tree_tgt_node);
01114
01115
01116 typename GT::Arc * tarc =
01117 tree.insert_arc(tnode, tree_tgt_node, garc->get_info());
01118 GT::map_arcs(garc, tarc);
01119
01120 tnode = tree_tgt_node;
01121
01122 if (tree.get_num_nodes() == g.get_num_nodes())
01123 return true;
01124
01125
01126 I(tree.get_num_nodes() > tree.get_num_arcs());
01127
01128 for (typename GT::Node_Arc_Iterator i(gnode); i.has_current(); i.next())
01129 {
01130 typename GT::Arc * arc = i.get_current_arc();
01131
01132 if (IS_ARC_VISITED(arc, Spanning_Tree))
01133 continue;
01134
01135 typename GT::Node * arc_tgt_node = i.get_tgt_node();
01136
01137 if (IS_NODE_VISITED(arc_tgt_node, Spanning_Tree))
01138 continue;
01139
01140 if (__find_depth_first_spanning_tree(g, arc_tgt_node, arc, tree, tnode))
01141 return false;
01142 }
01143
01144 return false;
01145 }
01175 template <class GT> inline
01176 void find_breadth_first_spanning_tree(GT & g,
01177 typename GT::Node * gnode,
01178 GT & tree)
01179 {
01180 g.reset_bit_nodes(Spanning_Tree);
01181 g.reset_bit_arcs(Spanning_Tree);
01182
01183
01184 tree.clear_graph();
01185 auto_ptr<typename GT::Node> tnode_auto (new typename GT::Node(gnode));
01186 tree.insert_node(tnode_auto.get());
01187 GT::map_nodes(gnode, tnode_auto.release());
01188
01189
01190 DynListQueue<typename GT::Arc*> q;
01191 for (typename GT::Node_Arc_Iterator i(gnode); i.has_current(); i.next())
01192 q.put(i.get_current_arc());
01193
01194 NODE_BITS(gnode).set_bit(Spanning_Tree, true);
01195
01196 while (not q.is_empty())
01197 {
01198 typename GT::Arc * garc = q.get();
01199
01200 ARC_BITS(garc).set_bit(Spanning_Tree, true);
01201
01202
01203 typename GT::Node * gsrc = g.get_src_node(garc);
01204 typename GT::Node * gtgt = g.get_tgt_node(garc);
01205
01206 if (IS_NODE_VISITED(gsrc, Spanning_Tree) and
01207 IS_NODE_VISITED(gtgt, Spanning_Tree))
01208 continue;
01209
01210
01211 if (IS_NODE_VISITED(gtgt, Spanning_Tree))
01212 Aleph::swap(gsrc, gtgt);
01213
01214 typename GT::Node * tsrc =
01215 static_cast<typename GT::Node*>(NODE_COOKIE(gsrc));
01216
01217 NODE_BITS(gtgt).set_bit(Spanning_Tree, true);
01218
01219
01220 auto_ptr<typename GT::Node> ttgt_auto (new typename GT::Node(gtgt));
01221 tree.insert_node(ttgt_auto.get());
01222 typename GT::Node * ttgt = ttgt_auto.release();
01223 GT::map_nodes(gtgt, ttgt);
01224
01225
01226 typename GT::Arc * tarc = tree.insert_arc(tsrc, ttgt, garc->get_info());
01227 GT::map_arcs(garc, tarc);
01228
01229 if (tree.get_num_nodes() == g.get_num_nodes())
01230 break;
01231
01232
01233 for (typename GT::Node_Arc_Iterator i(gtgt); i.has_current(); i.next())
01234 {
01235 typename GT::Arc * current_arc = i.get_current_arc();
01236
01237 if (IS_ARC_VISITED(current_arc, Spanning_Tree))
01238 continue;
01239
01240
01241 if (IS_NODE_VISITED(g.get_src_node(current_arc), Spanning_Tree) and
01242 IS_NODE_VISITED(g.get_tgt_node(current_arc), Spanning_Tree))
01243 continue;
01244
01245 q.put(current_arc);
01246 }
01247 }
01248 }
01249 template <class GT> inline static long & df(typename GT::Node * p)
01250
01251 {
01252 return NODE_COUNTER(p);
01253 }
01254
01255 template <class GT> inline static long & low(typename GT::Node * p)
01256
01257 {
01258 return reinterpret_cast<long&>(NODE_COOKIE(p));
01259 }
01260
01261 template <typename GT>
01262 struct Init_Low
01263 {
01264 void operator () (GT & g, typename GT::Node * node)
01265 {
01266 g.reset_counter(node);
01267 low <GT> (node) = -1;
01268 }
01269 };
01270
01271 template <typename GT> inline static
01272 void __compute_cut_nodes(GT & g,
01273 DynDlist<typename GT::Node *> & list,
01274 typename GT::Node * p,
01275 typename GT::Arc * a,
01276 long & curr_df);
01277
01311 template <typename GT>
01312 void compute_cut_nodes(GT & g,
01313 typename GT::Node * start,
01314 DynDlist<typename GT::Node *> & list)
01315 {
01316 g.template operate_on_nodes <Init_Low <GT> > ();
01317 g.reset_arcs();
01318
01319 long current_df = 0;
01320
01321 NODE_BITS(start).set_bit(Depth_First, true);
01322 df <GT> (start) = current_df++;
01323
01324 int call_counter = 0;
01325
01326 for (typename GT::Node_Arc_Iterator i(start);
01327 i.has_current() and current_df < g.get_num_nodes();
01328 i.next())
01329 {
01330 typename GT::Node * tgt = i.get_tgt_node();
01331
01332 if (IS_NODE_VISITED(tgt, Depth_First))
01333 continue;
01334
01335 typename GT::Arc * arc = i.get_current_arc();
01336
01337 if (IS_ARC_VISITED(arc, Depth_First))
01338 continue;
01339
01340 ARC_BITS(arc).set_bit(Depth_First, true);
01341
01342 __compute_cut_nodes(g, list, tgt, arc, current_df);
01343 ++call_counter;
01344 }
01345 if (call_counter > 1)
01346 {
01347 NODE_BITS(start).set_bit(Cut, true);
01348 list.append(start);
01349 }
01350 }
01351
01352 template <typename GT> inline static
01353 void __compute_cut_nodes(GT & g,
01354 DynDlist<typename GT::Node *> & list,
01355 typename GT::Node * p,
01356 typename GT::Arc * a,
01357 long & curr_df)
01358
01359 {
01360 NODE_BITS(p).set_bit(Depth_First, true);
01361 low <GT> (p) = df <GT> (p) = curr_df++;
01362
01363
01364 bool p_is_cut_node = false;
01365 for (typename GT::Node_Arc_Iterator i(p); i.has_current(); i.next())
01366 {
01367 typename GT::Arc * arc = i.get_current_arc();
01368
01369 if (arc == a)
01370 continue;
01371
01372 typename GT::Node * tgt = i.get_tgt_node();
01373
01374 if (IS_NODE_VISITED(tgt, Depth_First))
01375 {
01376 if (not IS_ARC_VISITED(arc, Depth_First))
01377 if (df <GT> (tgt) < low <GT> (p))
01378 low <GT> (p) = df <GT> (tgt);
01379
01380 continue;
01381 }
01382
01383 if (IS_ARC_VISITED(arc, Depth_First))
01384 continue;
01385
01386 ARC_BITS(arc).set_bit(Depth_First, true);
01387
01388 __compute_cut_nodes(g, list, tgt, arc, curr_df);
01389
01390 if (low <GT> (tgt) < low <GT> (p))
01391 low <GT> (p) = low <GT> (tgt);
01392
01393
01394 if (low <GT> (tgt) >= df <GT> (p) and df <GT> (tgt) != 0)
01395 p_is_cut_node = true;
01396 }
01397
01398 if (p_is_cut_node)
01399 {
01400 NODE_BITS(p).set_bit(Cut, true);
01401 list.append(p);
01402 }
01403 }
01444 template <typename GT>
01445 void compute_cut_nodes(GT & g,
01446 DynDlist<typename GT::Node *> & list)
01447 {
01448 compute_cut_nodes(g, g.get_first_node(), list);
01449 }
01450 const long Cross_Arc = -1;
01451 template <typename GT> inline static
01452 bool is_a_cross_arc(typename GT::Arc * a)
01453 {
01454 return ARC_COUNTER(a) == Cross_Arc;
01455 }
01456 template <typename GT> inline static
01457 bool is_a_cut_node(typename GT::Node * p)
01458 {
01459 return NODE_BITS(p).get_bit(Cut);
01460 }
01461
01462 template <typename GT> inline static
01463 bool is_an_cut_arc(typename GT::Arc * a)
01464 {
01465 return ARC_BITS(a).get_bit(Cut);
01466 }
01467 template <typename GT> inline static
01468 bool is_node_painted(typename GT::Node * p)
01469 {
01470 return NODE_COUNTER(p) > 0;
01471 }
01472
01473 template <typename GT> inline static
01474 bool is_arc_painted(typename GT::Arc * arc)
01475 {
01476 return ARC_COUNTER(arc) > 0;
01477 }
01478
01479 template <typename GT> inline static
01480 void paint_node(typename GT::Node * p, const long & color)
01481 {
01482 NODE_COUNTER(p) = color;
01483 }
01484
01485 template <typename GT> inline static
01486 void paint_arc(typename GT::Arc * a, const long & color)
01487 {
01488 ARC_COUNTER(a) = color;
01489 }
01490
01491 template <typename GT> inline static
01492 const long & get_color(typename GT::Node * p)
01493 {
01494 return NODE_COUNTER(p);
01495 }
01496
01497 template <typename GT> inline static
01498 const long & get_color(typename GT::Arc * a)
01499 {
01500 return ARC_COUNTER(a);
01501 }
01502 template <typename GT> inline static
01503 void __paint_subgraph(typename GT::Node * p,
01504 typename GT::Arc * a,
01505 const long & current_color)
01506 {
01507 if (is_a_cut_node <GT> (p))
01508 return;
01509
01510 paint_arc <GT> (a, current_color);
01511
01512 if (is_node_painted <GT> (p))
01513 return;
01514
01515 paint_node <GT> (p, current_color);
01516
01517
01518 for (typename GT::Node_Arc_Iterator it(p); it.has_current(); it.next())
01519 {
01520 typename GT::Arc * arc = it.get_current_arc();
01521
01522 if (is_arc_painted <GT> (arc))
01523 continue;
01524
01525 __paint_subgraph <GT> (it.get_tgt_node(), arc, current_color);
01526 }
01527 }
01528 template <typename GT> inline static
01529 void __paint_subgraph(typename GT::Node * p,
01530 const long & current_color)
01531 {
01532
01533 I(not is_a_cut_node <GT> (p) and not is_node_painted <GT> (p));
01534
01535 paint_node <GT> (p, current_color);
01536
01537 for (typename GT::Node_Arc_Iterator it(p); it.has_current(); it.next())
01538 {
01539 typename GT::Arc * arc = it.get_current_arc();
01540
01541 if (is_arc_painted <GT> (arc))
01542 continue;
01543
01544
01545 __paint_subgraph <GT> (it.get_tgt_node(), arc, current_color);
01546 }
01547 }
01548 template <typename GT> inline static
01549 void __paint_from_cut_node(typename GT::Node * p,
01550 long & current_color)
01551 {
01552
01553 I(is_a_cut_node <GT> (p));
01554
01555
01556 for (typename GT::Node_Arc_Iterator it(p); it.has_current(); it.next())
01557 {
01558 typename GT::Arc * arc = it.get_current_arc();
01559
01560
01561 I(not is_arc_painted <GT> (arc));
01562
01563 typename GT::Node * tgt_node = it.get_tgt_node();
01564
01565 if (is_a_cut_node <GT> (tgt_node))
01566 {
01567 ARC_BITS(arc).set_bit(Cut, true);
01568 continue;
01569 }
01570 else
01571 {
01572 paint_arc <GT> (arc, Cross_Arc);
01573
01574 if (is_node_painted <GT> (tgt_node))
01575 continue;
01576 }
01577
01578
01579
01580 __paint_subgraph <GT> (tgt_node, current_color);
01581
01582
01583
01584 current_color++;
01585
01586 I(not is_arc_painted <GT> (arc));
01587
01588 }
01589 }
01639 template <typename GT> inline
01640 long paint_subgraphs(GT & g,
01641 const DynDlist<typename GT::Node*> & cut_node_list)
01642 {
01643 g.reset_counter_nodes();
01644 g.reset_counter_arcs();
01645
01646 long current_color = 1;
01647
01648
01649 for (typename DynDlist<typename GT::Node*>::Iterator i(cut_node_list);
01650 i.has_current(); i.next())
01651 __paint_from_cut_node <GT> (i.get_current(), current_color);
01652
01653 return current_color;
01654 }
01655 template <typename GT> inline static
01656 void __map_subgraph(GT & g,
01657 GT & sg,
01658 typename GT::Node * gsrc,
01659 const long & color)
01660 {
01661
01662 I(get_color <GT> (gsrc) == color);
01663 I(NODE_COOKIE(gsrc) != NULL);
01664
01665 typename GT::Node * tsrc =
01666 static_cast<typename GT::Node*>(NODE_COOKIE(gsrc));
01667
01668
01669 for (typename GT::Node_Arc_Iterator i(gsrc); i.has_current(); i.next())
01670 {
01671 typename GT::Arc * garc = i.get_current_arc();
01672
01673 if (get_color <GT> (garc) != color or IS_ARC_VISITED(garc, Build_Subtree))
01674 continue;
01675
01676 ARC_BITS(garc).set_bit(Build_Subtree, true);
01677
01678 typename GT::Node * gtgt = i.get_tgt_node();
01679
01680
01681 I(get_color <GT> (gtgt) == color);
01682
01683
01684 typename GT::Node * ttgt = NULL;
01685 if (IS_NODE_VISITED(gtgt, Build_Subtree))
01686 ttgt = static_cast<typename GT::Node*>(NODE_COOKIE(gtgt));
01687 else
01688 {
01689 auto_ptr<typename GT::Node>
01690 ttgt_auto ( new typename GT::Node (gtgt) );
01691
01692 sg.insert_node(ttgt_auto.get());
01693 GT::map_nodes(gtgt, ttgt_auto.get());
01694
01695 NODE_BITS(gtgt).set_bit(Build_Subtree, true);
01696
01697 ttgt = ttgt_auto.release();
01698 }
01699
01700
01701 typename GT::Arc * tarc = sg.insert_arc(tsrc, ttgt, garc->get_info());
01702 GT::map_arcs(garc, tarc);
01703
01704 __map_subgraph(g, sg, gtgt, color);
01705 }
01706 }
01740 template <typename GT>
01741 void map_subgraph(GT & g, GT & sg, const long & color)
01742 {
01743 sg.clear_graph();
01744
01745
01746 typename GT::Node * first = NULL;
01747 for (typename GT::Node_Iterator it(g); it.has_current(); it.next())
01748 if (get_color <GT> (it.get_current_node()) == color)
01749 first = it.get_current_node();
01750
01751 if (first == NULL)
01752 throw std::domain_error("Color does not exist in the graph");
01753
01754
01755
01756 auto_ptr<typename GT::Node> auto_tsrc ( new typename GT::Node(first) );
01757 sg.insert_node(auto_tsrc.get());
01758 GT::map_nodes(first, auto_tsrc.release());
01759 NODE_BITS(first).set_bit(Build_Subtree, true);
01760
01761
01762 try
01763 {
01764
01765 __map_subgraph(g, sg, first, color);
01766
01767 }
01768 catch (...)
01769 {
01770 sg.clear_graph();
01771 }
01772
01773 }
01814 template <typename GT>
01815 void map_cut_graph(GT & g,
01816 DynDlist<typename GT::Node*> & cut_node_list,
01817 GT & cut_graph,
01818 DynDlist<typename GT::Arc*> & cross_arc_list)
01819 {
01820 cut_graph.clear_graph();
01821
01822
01823 for (typename DynDlist<typename GT::Node*>::Iterator it(cut_node_list);
01824 it.has_current(); it.next())
01825 {
01826 typename GT::Node * gp = it.get_current();
01827
01828 I (is_a_cut_node <GT> (gp));
01829
01830
01831 auto_ptr<typename GT::Node> tp_auto ( new typename GT::Node(gp) );
01832
01833 cut_graph.insert_node(tp_auto.get());
01834
01835 GT::map_nodes(gp, tp_auto.release());
01836 }
01837
01838
01839
01840
01841 for (typename GT::Arc_Iterator it(g); it.has_current(); it.next())
01842 {
01843 typename GT::Arc * garc = it.get_current_arc();
01844
01845 if (is_a_cross_arc <GT> (garc))
01846 {
01847 cross_arc_list.append(garc);
01848 continue;
01849 }
01850
01851 if (not is_an_cut_arc <GT> (garc))
01852 continue;
01853
01854 typename GT::Node * src =
01855 static_cast<typename GT::Node*>(NODE_COOKIE(g.get_src_node(garc)));
01856
01857 typename GT::Node * tgt =
01858 static_cast<typename GT::Node*>(NODE_COOKIE(g.get_tgt_node(garc)));
01859
01860
01861 I(src != NULL and tgt != NULL);
01862
01863 typename GT::Arc * cut_arc =
01864 cut_graph.insert_arc(src, tgt, garc->get_info());
01865
01866 GT::map_arcs(garc, cut_arc);
01867 }
01868 }
01869 template <class GT, class Distance, class Compare>
01870 struct Distance_Compare
01871 {
01872 bool operator () (typename GT::Arc * a1, typename GT::Arc * a2) const
01873 {
01874 return Compare () (Distance() (a1) , Distance() (a2) );
01875 }
01876 };
01877 template <class GT, class Distance, class Compare, class Plus>
01878 typename Distance::Distance_Type total_cost(GT & g)
01879 {
01880 typename Distance::Distance_Type sum = Distance::Zero_Distance;
01881
01882
01883 for (typename GT::Arc_Iterator it(g); it.has_current(); it.next())
01884 sum = Plus () (sum, Distance () (it.get_current_arc()));
01885
01886 return sum;
01887 }
01888 template <class GT, class Distance>
01889 typename Distance::Distance_Type total_cost(GT & g)
01890 {
01891 typedef Aleph::less<typename Distance::Distance_Type> Less;
01892 typedef Aleph::plus<typename Distance::Distance_Type> Plus;
01893
01894 return total_cost <GT, Distance, Less, Plus> (g);
01895 }
01896 template <class GT> static inline
01897 void __topological_sort(GT & g,
01898 typename GT::Node * curr,
01899 DynDlist<typename GT::Node*> & list)
01900 {
01901 if (IS_NODE_VISITED(curr, Depth_First))
01902 return;
01903
01904 NODE_BITS(curr).set_bit(Depth_First, 1);
01905
01906
01907 for (typename GT::Arc_Node_Iterator it(g, curr);
01908 it.has_current() and list.size() < g.get_num_nodes(); it.next())
01909 __topological_sort(g, it.get_tgt_node(), list);
01910
01911 list.insert(curr);
01912 }
01929 template <class GT> inline
01930 void topological_sort(GT & g, DynDlist<typename GT::Node*> & list)
01931 {
01932
01933 if (not g.is_digraph())
01934 throw std::domain_error("g is not a digraph");
01935
01936 g.reset_bit_nodes(Depth_First);
01937
01938 for (typename GT::Node_Iterator it(g);
01939 it.has_current() and list.size() < g.get_num_nodes(); it.next())
01940 {
01941 typename GT::Node * curr = it.get_current_node();
01942
01943 if (not IS_NODE_VISITED(curr, Depth_First))
01944 __topological_sort(g, curr, list);
01945 }
01946 }
01964 template <class GT> inline
01965 void q_topological_sort(GT & g, DynDlist<typename GT::Node*> & list)
01966 {
01967
01968 if (not g.is_digraph())
01969 throw std::domain_error("g is not a digraph");
01970
01971 g.reset_counter_nodes();
01972
01973
01974 for (typename GT::Node_Iterator it(g); it.has_current(); it.next())
01975 NODE_COUNTER(it.get_current_node())++;
01976
01977 DynListQueue<typename GT::Node*> q;
01978
01979
01980 for (typename GT::Node_Iterator it(g); it.has_current(); it.next())
01981 {
01982 typename GT::Node * p = it.get_current_node();
01983
01984 if (NODE_COUNTER(p) == 0)
01985 q.put(p);
01986 }
01987
01988 while (not q.is_empty())
01989 {
01990 typename GT::Node * p = q.get();
01991
01992 I(NODE_COUNTER(p) == 0);
01993
01994 list.append(p);
01995
01996
01997 for (typename GT::Node_Arc_Iterator it(g, p); it.has_current(); it.next())
01998 {
01999 typename GT::Node * tgt = it.get_tgt_node();
02000
02001 if (--NODE_COUNTER(tgt) == 0)
02002 q.put(tgt);
02003 }
02004 }
02005 }
02006
02007 }
02008
02009 # endif // TPL_GRAPH_UTILS_H
02010