Aleph-w  1.9
General library for algorithms and data structures
tpl_graph_utils.H
1 
2 /* Aleph-w
3 
4  / \ | | ___ _ __ | |__ __ __
5  / _ \ | |/ _ \ '_ \| '_ \ ____\ \ /\ / / Data structures & Algorithms
6  / ___ \| | __/ |_) | | | |_____\ V V / version 1.9b
7  /_/ \_\_|\___| .__/|_| |_| \_/\_/ https://github.com/lrleon/Aleph-w
8  |_|
9 
10  This file is part of Aleph-w library
11 
12  Copyright (c) 2002-2018 Leandro Rabindranath Leon & Alejandro Mujica
13 
14  This program is free software: you can redistribute it and/or modify
15  it under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  This program is distributed in the hope that it will be useful, but
20  WITHOUT ANY WARRANTY; without even the implied warranty of
21  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22  General Public License for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with this program. If not, see <https://www.gnu.org/licenses/>.
26 */
27 # ifndef TPL_GRAPH_UTILS_H
28 # define TPL_GRAPH_UTILS_H
29 
30 
31 # include <limits>
32 # include <tpl_agraph.H>
33 # include <tpl_dynListQueue.H>
34 
35 using namespace Aleph;
36 
37 namespace Aleph {
38 
39  template <class GT> inline static bool
40 __depth_first_traversal(const GT & g, typename GT::Node * node,
41  typename GT::Arc * arc,
42  bool (*visit)(const GT & g, typename GT::Node *,
43  typename GT::Arc *),
44  size_t & count);
45 
68  template <class GT> inline size_t
69 depth_first_traversal(const GT & g, typename GT::Node * start_node,
70  bool (*visit)(const GT & g, typename GT::Node *,
71  typename GT::Arc *))
72 {
73  g.reset_bit_nodes(Depth_First); // reiniciar Depth_First de nodos
74  g.reset_bit_arcs(Depth_First); // reiniciar Depth_First de arcos
75  size_t counter = 0; // inicialmente no se ha visitado ningún nodo
76 
77  __depth_first_traversal(g, start_node, nullptr, visit, counter);
78 
79  return counter;
80 }
81 
83  template <class GT> inline
84 size_t depth_first_traversal(const GT & g,
85  bool (*visit)(const GT &, typename GT::Node *,
86  typename GT::Arc *))
87 {
88  return depth_first_traversal(g, g.get_first_node(), visit);
89 }
90 
95  template <class GT>
97 {
98  bool operator () (const GT &, typename GT::Node *, typename GT::Arc *)
99  {
100  return false;
101  }
102 };
103 
135  template <class GT,
136  class Operation = Default_Visit_Op<GT>,
137  class SA = Dft_Show_Arc<GT>>
139 {
140  Operation * op_ptr = nullptr;
141  SA sa;
142  size_t count = 0;
143  const GT * g_ptr = nullptr;
144 
145 private:
146 
147  bool __dft(typename GT::Node * node, typename GT::Arc * arc = nullptr)
148  {
149  if (IS_NODE_VISITED(node, Depth_First))
150  return false;
151 
152  NODE_BITS(node).set_bit(Depth_First, true); // marca nodo visitado
153  count++;
154 
155  if ((*op_ptr)(*g_ptr, node, arc))
156  return true; // sí, invóquela
157 
158  if (count == g_ptr->get_num_nodes()) // ¿se visitaron todos lo nodos?
159  return true;
160 
161  // recorrer recursivamente arcos de node
162  for (Node_Arc_Iterator<GT, SA> it(node, sa); it.has_curr(); it.next_ne())
163  {
164  auto arc = it.get_current_arc_ne();
165  if (IS_ARC_VISITED(arc, Depth_First))
166  continue;
167 
168  ARC_BITS(arc).set_bit(Depth_First, true); // visitado
169  if (__dft (it.get_tgt_node_ne(), arc))
170  return true; // ya se exploró cabalmente it.get_tgt_node()
171  }
172 
173  return false; // retorne y siga explorando
174  }
175 
176  size_t dft(const GT & g, typename GT::Node * start_node, Operation & __op)
177  {
178  op_ptr = &__op;
179  g_ptr = &g;
180 
181  g_ptr->reset_bit_nodes(Depth_First); // reiniciar Depth_First de nodos
182  g_ptr->reset_bit_arcs(Depth_First); // reiniciar Depth_First de arcos
183 
184  count = 0;
185 
186  __dft(start_node);
187 
188  return count;
189  }
190 
191 public:
192 
195  Depth_First_Traversal(SA __sa = SA()) : sa(__sa) { /* empty */ }
196 
203  size_t operator () (const GT & g, Operation op = Operation())
204  {
205  return dft(g, g.get_first_node(), op);
206  }
207 
215  size_t operator () (const GT & g, typename GT::Node * sn,
216  Operation op = Operation())
217  {
218  return dft(g, sn, op);
219  }
220 };
221 
222 
223  template <class GT> inline static bool
224 __depth_first_traversal(const GT & g, typename GT::Node * node,
225  typename GT::Arc * arc,
226  bool (*visit)(const GT & g, typename GT::Node *,
227  typename GT::Arc *),
228  size_t & count)
229 {
230  if (IS_NODE_VISITED(node, Depth_First))
231  return false;
232 
233  NODE_BITS(node).set_bit(Depth_First, true); // marca nodo visitado
234  count++;
235 
236  if (visit != nullptr) // verifique si hay función de visita
237  if ((*visit)(g, node, arc))
238  return true;
239 
240  if (count == g.get_num_nodes()) // ¿se visitaron todos lo nodos?
241  return true;
242 
243  for (auto it = g.get_arc_it(node); it.has_curr(); it.next_ne())
244  {
245  auto arc = it.get_current_arc_ne();
246  if (IS_ARC_VISITED(arc, Depth_First))
247  continue;
248 
249  ARC_BITS(arc).set_bit(Depth_First, true); // visitado
250  if (__depth_first_traversal(g, it.get_tgt_node_ne(), arc, visit, count))
251  return true; // ya se exploró cabalmente it.get_tgt_node()
252  }
253 
254  return false; // retorne y siga explorando
255 }
256 
257  template <class GT> inline size_t
280 breadth_first_traversal(const GT & g, typename GT::Node * start,
281  bool (*visit)(const GT &, typename GT::Node *,
282  typename GT::Arc *) )
283 {
284  g.reset_bit_nodes(Breadth_First);
285  g.reset_bit_arcs(Breadth_First);
287 
288  for (auto it = g.get_arc_it(start); it.has_curr(); it.next_ne())
289  q.put(it.get_current_arc_ne());
290 
291  NODE_BITS(start).set_bit(Breadth_First, true);
292  size_t node_counter = 1; // count the visited nodes
293 
294  if (visit != nullptr)
295  if ((*visit)(g, start, nullptr))
296  return 1;
297 
298  while (not q.is_empty() and node_counter < g.get_num_nodes())
299  {
300  auto arc = q.get();// saque de cola más cercano
301  ARC_BITS(arc).set_bit(Breadth_First, true);
302 
303  auto src = g.get_src_node(arc);
304  auto tgt = g.get_tgt_node(arc);
305  if (IS_NODE_VISITED(src, Breadth_First) and
306  IS_NODE_VISITED(tgt, Breadth_First))
307  continue;
308 
309  auto visit_node = IS_NODE_VISITED(src, Breadth_First) ? tgt : src;
310  if (visit != nullptr)
311  if ((*visit)(g, visit_node, arc))
312  break;
313 
314  NODE_BITS(visit_node).set_bit(Breadth_First, true);
315  node_counter++;
316 
317  for (auto it = g.get_arc_it(visit_node); it.has_curr(); it.next_ne())
318  {
319  auto curr_arc = it.get_current_arc_ne();
320  if (IS_ARC_VISITED(curr_arc, Breadth_First))
321  continue;
322 
323  if (IS_NODE_VISITED(g.get_src_node(curr_arc), Breadth_First) and
324  IS_NODE_VISITED(g.get_tgt_node(curr_arc), Breadth_First))
325  continue; // nodos ya visitados
326 
327  q.put(curr_arc);
328  }
329  }
330 
331  return node_counter;
332  }
333 
335  template <class GT> inline size_t
337  bool (*visit)(const GT &, typename GT::Node *,
338  typename GT::Arc *))
339 {
340  return breadth_first_traversal(g, g.get_first_node(), visit);
341 }
342 
343 
375  template <class GT,
376  class Operation = Default_Visit_Op<GT>,
377  class SA = Dft_Show_Arc<GT>>
379 {
380  SA sa;
381  size_t count = 0;
382 
383  size_t bft(const GT & g, typename GT::Node * start, Operation & op)
384  {
385  g.reset_bit_nodes(Breadth_First);
386  g.reset_bit_arcs(Breadth_First);
387  DynListQueue<typename GT::Arc*> q; // cola de arcos pendientes
388 
389  for (Node_Arc_Iterator<GT, SA> it(start); it.has_curr(); it.next_ne())
390  q.put(it.get_current_arc_ne());
391 
392  NODE_BITS(start).set_bit(Breadth_First, true);
393  count = 1; // contador de nodos visitados
394 
395  if (op (g, start, nullptr))
396  return 1;
397 
398  while (not q.is_empty() and count < g.get_num_nodes())
399  {
400  auto arc = q.get(); // saque de cola más cercano
401  ARC_BITS(arc).set_bit(Breadth_First, true);
402 
403  auto src = g.get_src_node(arc);
404  auto tgt = g.get_tgt_node(arc);
405 
406  if (IS_NODE_VISITED(src, Breadth_First) and
407  IS_NODE_VISITED(tgt, Breadth_First))
408  continue;
409 
410  auto curr = IS_NODE_VISITED(src, Breadth_First) ? tgt : src;
411  if (op (g, curr, arc))
412  break;
413 
414  NODE_BITS(curr).set_bit(Breadth_First, true);
415  count++;
416 
417  for (Node_Arc_Iterator<GT, SA> it(curr); it.has_curr(); it.next_ne())
418  {
419  auto curr_arc = it.get_current_arc_ne();
420  if (IS_ARC_VISITED(curr_arc, Breadth_First))
421  continue;
422 
423  if (IS_NODE_VISITED(g.get_src_node(curr_arc), Breadth_First) and
424  IS_NODE_VISITED(g.get_tgt_node(curr_arc), Breadth_First))
425  continue; // nodos ya visitados
426 
427  q.put(curr_arc);
428  }
429  }
430 
431  return count;
432  }
433 
434 public:
435 
438  Breadth_First_Traversal(SA __sa = SA()) : sa(__sa) { /* empty */ }
439 
447  size_t operator () (const GT & g, Operation op)
448  {
449  return bft (g, g.get_first_node(), op);
450  }
451 
460  size_t operator () (const GT & g, typename GT::Node * p,
461  Operation && op = Operation())
462  {
463  return bft(g, p, op);
464  }
465 
466  size_t operator () (const GT & g, typename GT::Node * p, Operation & op)
467  {
468  return bft(g, p, op);
469  }
470 };
471 
486  template <class GT> inline
487 Path<GT> find_path_breadth_first(const GT & g, typename GT::Node * start,
488  typename GT::Node * end)
489 {
490  g.reset_nodes();
491  g.reset_arcs();
492 
494 
495  for (auto it = g.get_arc_it(start); it.has_curr(); it.next_ne())
496  q.put(it.get_current_arc_ne());
497 
498  NODE_BITS(start).set_bit(Find_Path, true);
499 
500  bool path_found = false;
501 
502  while (not q.is_empty())
503  {
504  auto arc = q.get();
505  auto src = g.get_src_node(arc);
506  auto tgt = g.get_tgt_node(arc);
507 
508  if (IS_NODE_VISITED(src, Find_Path) and IS_NODE_VISITED(tgt, Find_Path))
509  continue;
510 
511  if (IS_NODE_VISITED(tgt, Find_Path))
512  std::swap(src, tgt);
513 
514  ARC_BITS(arc).set_bit(Find_Path, true);
515  NODE_BITS(tgt).set_bit(Find_Path, true);
516  NODE_COOKIE(tgt) = src;
517 
518  if (tgt == end)
519  {
520  path_found = true;
521  break;
522  }
523 
524  for (auto it = g.get_arc_it(tgt); it.has_curr(); it.next_ne())
525  {
526  auto a = it.get_current_arc_ne();
527  if (IS_ARC_VISITED(a, Find_Path))
528  continue;
529 
530  if (IS_NODE_VISITED(g.get_src_node(a), Find_Path) and
531  IS_NODE_VISITED(g.get_tgt_node(a), Find_Path))
532  continue;
533 
534  q.put(a);
535  }
536  }
537 
538  if (not path_found)
539  return Path<GT>();
540 
541  q.empty(); // free queue memory for eventually saving the required for path
542 
543  Path<GT> path(g, end);
544  auto p = end;
545  while (p != start)
546  {
547  p = (typename GT::Node *) NODE_COOKIE(p);
548  path.insert(p);
549  }
550 
551  return path;
552 }
553 
554 
564  template <class GT> inline
565 bool test_connectivity(const GT & g)
566 {
567  if (g.is_digraph()) // only valid for non directed
568  throw std::domain_error("test_connectivity() does not work on digraphs");
569 
570  if (g.get_num_arcs() < g.get_num_nodes() - 1)
571  return false;
572 
573  return depth_first_traversal<GT>(g, nullptr) == g.get_num_nodes();
574 }
575 
576 
577 template <class GT, class SA> inline static
578 bool __test_cycle(const GT & g, typename GT::Node *, typename GT::Node *);
579 
580 
602  template <class GT> inline
603 bool test_for_cycle(const GT & g, typename GT::Node * src)
604 {
605  g.reset_bit_nodes(Test_Cycle);
606  g.reset_bit_arcs(Test_Cycle);
607  for (auto it = g.get_arc_it(src); it.has_curr(); it.next_ne())
608  {
609  auto arc = it.get_curr_ne();
610  if (IS_ARC_VISITED(arc, Test_Cycle))
611  continue;
612 
613  ARC_BITS(arc).set_bit(Test_Cycle, true);
614  if (__test_cycle(g, src, it.get_tgt_node_ne()))
615  return true;
616  }
617 
618  return false;
619 }
620 
621 
622  template <class GT> inline static bool
623 __test_cycle(const GT & g, typename GT::Node * src, typename GT::Node * curr)
624 {
625  if (src == curr)
626  return true; // detected cycle
627 
628  if (IS_NODE_VISITED(curr, Test_Cycle))
629  return false;
630 
631  NODE_BITS(curr).set_bit(Test_Cycle, true);
632 
633  for (auto it = g.get_arc_it(curr); it.has_curr(); it.next_ne())
634  {
635  auto arc = it.get_curr_ne();
636  if (IS_ARC_VISITED(arc, Test_Cycle))
637  continue;
638 
639  ARC_BITS(arc).set_bit(Test_Cycle, true);
640  if (__test_cycle(g, src, it.get_tgt_node_ne()))
641  return true;
642  }
643 
644  return false;
645 }
646 
647  template <class GT> inline static
648 bool __is_graph_acyclique(const GT & g, typename GT::Node * curr_node)
649  {
650  if (IS_NODE_VISITED(curr_node, Test_Cycle))
651  return false;
652 
653  NODE_BITS(curr_node).set_bit(Test_Cycle, true); // marcar nodo
654 
655  for (auto it = g.get_arc_it(curr_node); it.has_curr(); it.next_ne())
656  {
657  auto arc = it.get_current_arc_ne();
658  if (IS_ARC_VISITED(arc, Test_Cycle))
659  continue;
660 
661  ARC_BITS(arc).set_bit(Test_Cycle, true);
662 
663  if (not __is_graph_acyclique(g, it.get_tgt_node_ne()))
664  return false;
665  }
666  // todos los arcos recorridos sin encontrar ciclo ==>
667  // el grafo es acíclico pasando por curr_node
668  return true;
669  }
670 
671 
680  template <class GT> inline
681 bool is_graph_acyclique(const GT & g, typename GT::Node * start_node)
682 {
683  if (g.is_digraph())
684  throw std::domain_error("is_graph_acyclique() does not work for digraps");
685 
686  if (g.get_num_arcs() >= g.get_num_nodes())
687  return false;
688 
689  g.reset_bit_arcs(Test_Cycle);
690  g.reset_bit_nodes(Test_Cycle);
691 
692  return __is_graph_acyclique(g, start_node);
693 }
694 
702  template <class GT> inline
703 bool is_graph_acyclique(const GT & g)
704 {
705  if (g.is_digraph())
706  throw std::domain_error("is_graph_acyclique() does not work for digraps");
707 
708  if (g.get_num_arcs() >= g.get_num_nodes())
709  return false;
710 
711  g.reset_bit_arcs(Test_Cycle);
712  g.reset_bit_nodes(Test_Cycle);
713 
714  for (auto it = g.get_node_it(); it.has_curr(); it.next_ne())
715  {
716  auto current_node = it.get_current_node_ne();
717  if (IS_NODE_VISITED(current_node, Test_Cycle))
718  continue;
719 
720  if (not __is_graph_acyclique(g, current_node))
721  return false;
722  }
723 
724  return true;
725 }
726 
727 
735  template <class GT>
736 inline bool has_cycle(const GT & g)
737 {
738  return not is_graph_acyclique(g);
739 }
740 
741 
755  template <class GT> inline
756 bool test_for_path(const GT & g, typename GT::Node * start_node,
757  typename GT::Node * end_node)
758 {
759  if (not g.is_digraph() and g.get_num_arcs() >= g.get_num_nodes())
760  return true;
761 
762  g.reset_bit_nodes(Find_Path);
763  g.reset_bit_arcs(Find_Path);
764 
765  for (auto it = g.get_arc_it(start_node); it.has_curr(); it.next_ne())
766  {
767  auto arc = it.get_current_arc_ne();
768  ARC_BITS(arc).set_bit(Find_Path, true); // marcar arco
769  if (__test_for_path(g, it.get_tgt_node_ne(), end_node))
770  return true;
771  }
772 
773  return false;
774 }
775 
776 
777  template <class GT> inline static
778 bool __test_for_path(const GT & g, typename GT::Node * curr_node,
779  typename GT::Node * end_node)
780 {
781  if (curr_node == end_node)
782  return true;
783 
784  if (IS_NODE_VISITED(curr_node, Find_Path)) // ¿se visitó curr_node?
785  return false; // sí, no explore
786 
787  NODE_BITS(curr_node).set_bit(Find_Path, true);
788 
789  for (auto it = g.get_arc_it(curr_node); it.has_curr(); it.next_ne())
790  {
791  auto arc = it.get_current_arc_ne();
792  if (IS_ARC_VISITED(arc, Find_Path))
793  continue;
794 
795  ARC_BITS(arc).set_bit(Find_Path, true);
796  if (__test_for_path(g, it.get_tgt_node_ne(), end_node))
797  return true;
798  }
799 
800  return false;
801 }
802 
803 template <class GT> inline
804 DynList<GT> inconnected_components(const GT & g);
805 
806 template <class GT> inline
807 void build_subgraph(const GT & g, GT & sg,
808  typename GT::Node * g_src, size_t & node_count);
809 
810 
829  template <class GT> inline
831 {
832  g.reset_nodes();
833  g.reset_arcs();
834 
836  size_t count = 0; // counter of visited nodes
837  for (auto it = g.get_node_it(); count < g.get_num_nodes() and it.has_curr();
838  it.next_ne())
839  {
840  auto curr = it.get_current_node_ne();
841  if (IS_NODE_VISITED(curr, Build_Subtree))
842  continue;
843 
844  list.append(GT()); // crea subgrafo y lo inserta en lista
845  GT & subgraph = list.get_last(); // grafo insertado en list
846  build_subgraph(g, subgraph, curr, count);
847  }
848 
849  return list;
850 }
851 
852 
877  template <class GT> inline
878 void build_subgraph(const GT & g, GT & sg,
879  typename GT::Node * g_src, size_t & node_count)
880 {
881  if (IS_NODE_VISITED(g_src, Build_Subtree))
882  return;
883 
884  NODE_BITS(g_src).set_bit(Build_Subtree, true); // mark g_src as visited
885  ++node_count;
886 
887  auto sg_src = mapped_node<GT>(g_src);
888  if (sg_src == nullptr) // sg_src already mapped
889  {
890  sg_src = sg.insert_node(g_src->get_info());
891  GT::map_nodes(g_src, sg_src);
892  }
893 
894  for (auto it = g.get_arc_it(g_src);
895  node_count < g.get_num_nodes() and it.has_curr(); it.next_ne())
896  {
897  auto arc = it.get_current_arc_ne();
898  if (IS_ARC_VISITED(arc, Build_Subtree))
899  continue;
900 
901  ARC_BITS(arc).set_bit(Build_Subtree, true);
902  auto g_tgt = it.get_tgt_node_ne();
903  auto sg_tgt = mapped_node<GT>(g_tgt);
904  if (sg_tgt == nullptr) // sg_tgt mapped in sg?
905  {
906  sg_tgt = sg.insert_node(g_tgt->get_info());
907  GT::map_nodes(g_tgt, sg_tgt);
908  }
909 
910  auto sg_arc = sg.insert_arc(sg_src, sg_tgt, arc->get_info());
911  GT::map_arcs(arc, sg_arc);
912 
913  build_subgraph(g, sg, g_tgt, node_count);
914  }
915 }
916 
917 
918  template <class GT> inline static
919 bool __find_depth_first_spanning_tree(const GT & g,
920  typename GT::Node * gnode,
921  typename GT::Arc * garc,
922  GT & tree,
923  typename GT::Node * tnode);
924 
942 template <class GT> inline
943 GT find_depth_first_spanning_tree(const GT & g, typename GT::Node * gnode)
944 {
945  g.reset_nodes();
946  g.reset_arcs();
947 
948  GT tree;
949 
950  NODE_BITS(gnode).set_bit(Spanning_Tree, true); // marcar gnode
951 
952  auto tnode = tree.insert_node(gnode->get_info());
953  GT::map_nodes(gnode, tnode);
954 
955  for (auto it = g.get_arc_it(gnode); it.has_curr(); it.next_ne())
956  {
957  auto arc = it.get_current_arc_ne();
958  if (IS_ARC_VISITED(arc, Spanning_Tree))
959  continue;
960 
961  auto arc_tgt_node = it.get_tgt_node_ne();
962  if (IS_NODE_VISITED(arc_tgt_node, Spanning_Tree))
963  continue; // destino ya visitado desde otro arco
964 
965  if (__find_depth_first_spanning_tree(g, arc_tgt_node, arc, tree, tnode))
966  return tree;
967  }
968 
969  return tree;
970 }
971 
973  template <class GT> inline
974 GT find_depth_first_spanning_tree(const GT & g)
975 {
976  return find_depth_first_spanning_tree(g, g.get_node());
977 }
978 
979 
980  template <class GT> inline static
981 bool __find_depth_first_spanning_tree(const GT & g, typename GT::Node * gnode,
982  typename GT::Arc * garc,
983  GT & tree, typename GT::Node * tnode)
984 {
985  NODE_BITS(gnode).set_bit(Spanning_Tree, true); // marcar nodo
986  ARC_BITS(garc).set_bit(Spanning_Tree, true); // marcar arco
987 
988  auto tree_tgt_node = tree.insert_node(gnode->get_info());
989  GT::map_nodes(gnode, tree_tgt_node);
990 
991  auto tarc = tree.insert_arc(tnode, tree_tgt_node, garc->get_info());
992  GT::map_arcs(garc, tarc);
993 
994  tnode = tree_tgt_node;
995  if (tree.get_num_nodes() == g.get_num_nodes()) // ¿grafo abarcado?
996  return true; // tree ya contiene el árbol abarcador
997 
998  assert(tree.get_num_nodes() > tree.get_num_arcs()); // debe ser acíclico
999 
1000  for (auto it = g.get_arc_it(gnode); it.has_curr(); it.next_ne())
1001  {
1002  auto arc = it.get_current_arc_ne();
1003  if (IS_ARC_VISITED(arc, Spanning_Tree))
1004  continue;
1005 
1006  auto arc_tgt_node = it.get_tgt_node_ne();
1007  if (IS_NODE_VISITED(arc_tgt_node, Spanning_Tree))
1008  continue; // destino ya visitado desde otro arco
1009 
1010  if (__find_depth_first_spanning_tree(g, arc_tgt_node, arc, tree, tnode))
1011  return false; // ya el árbol está calculado
1012  }
1013 
1014  return false;
1015 }
1016 
1034  template <class GT> inline
1035 GT find_breadth_first_spanning_tree(GT & g, typename GT::Node * gp)
1036 {
1037  g.reset_bit_nodes(Spanning_Tree);
1038  g.reset_bit_arcs(Spanning_Tree);
1039 
1040  GT tree;
1041 
1042  unique_ptr<typename GT::Node> tp_auto(new typename GT::Node(gp));
1043  tree.insert_node(tp_auto.get());
1044  GT::map_nodes(gp, tp_auto.release());
1045  NODE_BITS(gp).set_bit(Spanning_Tree, true); // mark gp as visited
1046 
1047  DynListQueue<typename GT::Arc*> q; // queue of arcs
1048  for (auto it = g.get_arc_it(gp); it.has_curr(); it.next_ne())
1049  q.put(it.get_curr_ne());
1050 
1051  while (not q.is_empty())
1052  {
1053  auto garc = q.get();
1054  ARC_BITS(garc).set_bit(Spanning_Tree, true); // mark the arc as visited
1055  auto gsrc = g.get_src_node(garc);
1056  auto gtgt = g.get_tgt_node(garc);
1057 
1058  if (IS_NODE_VISITED(gsrc, Spanning_Tree) and
1059  IS_NODE_VISITED(gtgt, Spanning_Tree))
1060  continue; // los dos nodos de garc ya fueron visitados
1061 
1062  if (IS_NODE_VISITED(gtgt, Spanning_Tree)) // gtgt visited?
1063  std::swap(gsrc, gtgt); // the non visited is gsrc
1064 
1065  auto tsrc = mapped_node<GT>(gsrc);
1066  NODE_BITS(gtgt).set_bit(Spanning_Tree, true); // mark gtgt visited
1067 
1068  // crear copia de gtgt, insertarlo en tree y mapearlo
1069  unique_ptr<typename GT::Node> ttgt_auto(new typename GT::Node(gtgt));
1070  tree.insert_node(ttgt_auto.get());
1071  auto ttgt = ttgt_auto.release();
1072  GT::map_nodes(gtgt, ttgt);
1073 
1074  // insertar nuevo arco en tree y mapearlo
1075  auto tarc = tree.insert_arc(tsrc, ttgt, garc->get_info());
1076  GT::map_arcs(garc, tarc);
1077  if (tree.get_num_nodes() == g.get_num_nodes()) // ¿abarca a g?
1078  break;
1079 
1080  // insertar en cola arcos de gtgt
1081  for (auto it = g.get_arc_it(gtgt); it.has_curr(); it.next_ne())
1082  {
1083  auto current_arc = it.get_current_arc_ne();
1084  if (IS_ARC_VISITED(current_arc, Spanning_Tree))
1085  continue;
1086 
1087  // revise nodos de arcos para ver si han sido visitados
1088  if (IS_NODE_VISITED(g.get_src_node(current_arc),Spanning_Tree) and
1089  IS_NODE_VISITED(g.get_tgt_node(current_arc),Spanning_Tree))
1090  continue; // nodos ya visitados ==> no meter arco
1091  q.put(current_arc);
1092  }
1093  }
1094 
1095  return tree;
1096 }
1097 
1114 template <class GT>
1116 {
1117  using Node = typename GT::Node;
1118  using Arc = typename GT::Arc;
1119 
1120  GT ret;
1122  arcs.for_each([&table, &ret] (Arc * ga)
1123  {
1124  if (ga == nullptr)
1125  return;
1126 
1127  Node * gsrc = (Node*) ga->src_node;
1128  Node * gtgt = (Node*) ga->tgt_node;
1129 
1130  Node * tsrc;
1131  auto * pair_ptr = table.search(gsrc);
1132  if (pair_ptr)
1133  tsrc = pair_ptr->second;
1134  else
1135  {
1136  tsrc = ret.insert_node(gsrc->get_info()); // borrar get_info()
1137  table.insert(gsrc, tsrc);
1138  NODE_COOKIE(tsrc) = gsrc;
1139  }
1140 
1141  Node * ttgt;
1142  pair_ptr = table.search(gtgt);
1143  if (pair_ptr)
1144  ttgt = pair_ptr->second;
1145  else
1146  {
1147  ttgt = ret.insert_node(gtgt->get_info());
1148  table.insert(gtgt, ttgt);
1149  NODE_COOKIE(ttgt) = gtgt;
1150  }
1151 
1152  Arc * ta = ret.insert_arc(tsrc, ttgt);
1153  *ta = *ga;
1154  ARC_COOKIE(ta) = ga;
1155  });
1156 
1157  return ret;
1158 }
1159 
1160  template <class GT> inline static
1161 long & df(typename GT::Node * p)
1162 {
1163  return NODE_COUNTER(p);
1164 }
1165 
1166  template <class GT> inline static
1167 long & low(typename GT::Node * p)
1168 {
1169  return reinterpret_cast<long&>(NODE_COOKIE(p));
1170 }
1171 
1172  template <class GT> inline static
1173 void __compute_cut_nodes(const GT & g, DynList<typename GT::Node *> & list,
1174  typename GT::Node * p, typename GT::Arc * a,
1175  long & curr_df);
1176 
1197  template <class GT>
1199 compute_cut_nodes(const GT & g, typename GT::Node * start)
1200 {
1202 
1203  g.for_each_node([] (auto p) // init the nodes
1204  {
1205  NODE_COUNTER(p) = 0;
1206  NODE_BITS(p).reset();
1207  low<GT>(p) = -1;
1208  });
1209  g.reset_arcs();
1210  long current_df = 0; // contador global de visitas
1211  NODE_BITS(start).set_bit(Depth_First, true); // marcar start
1212  df<GT>(start) = current_df++;
1213  int call_counter = 0; // contador llamadas recursivas
1214 
1215  // Recorra los arcos de start mientras g no haya sido abarcado
1216  for (auto it = g.get_arc_it(start);
1217  it.has_curr() and current_df < g.get_num_nodes(); it.next_ne())
1218  {
1219  auto tgt = it.get_tgt_node_ne();
1220  if (IS_NODE_VISITED(tgt, Depth_First))
1221  continue;
1222 
1223  auto arc = it.get_current_arc_ne();
1224  if (IS_ARC_VISITED(arc, Depth_First))
1225  continue;
1226 
1227  ARC_BITS(arc).set_bit(Depth_First, true);
1228  __compute_cut_nodes(g, list, tgt, arc, current_df);
1229  ++call_counter;
1230  }
1231 
1232  if (call_counter > 1) // ¿es la raíz un punto de articulación?
1233  {
1234  NODE_BITS(start).set_bit(Cut, true);
1235  list.append(start);
1236  }
1237 
1238  return list;
1239 }
1240 
1242  template <class GT>
1244 {
1245  return compute_cut_nodes(g, g.get_node());
1246 }
1247 
1248  template <class GT> inline static
1249 void __compute_cut_nodes(const GT & g, DynList<typename GT::Node *> & list,
1250  typename GT::Node * p, typename GT::Arc * a,
1251  long & curr_df)
1252 {
1253  NODE_BITS(p).set_bit(Depth_First, true); // pinte p visitado
1254  low <GT> (p) = df <GT> (p) = curr_df++; // asígnele df
1255 
1256  // recorrer arcos de p mientras no se abarque a g
1257  bool p_is_cut_node = false;
1258  for (auto it = g.get_arc_it(p); it.has_curr(); it.next_ne())
1259  {
1260  auto arc = it.get_current_arc_ne();
1261  if (arc == a)
1262  continue; // a es el padre de arc ==> ignorarlo
1263 
1264  auto tgt = it.get_tgt_node_ne();
1265  if (IS_NODE_VISITED(tgt, Depth_First))
1266  {
1267  if (not IS_ARC_VISITED(arc, Depth_First)) // no abarcador?
1268  if (df<GT>(tgt) < low<GT>(p)) // sí, verificar valor low
1269  low<GT>(p) = df<GT>(tgt); // actualizar low(p)
1270 
1271  continue;
1272  }
1273 
1274  if (IS_ARC_VISITED(arc, Depth_First))
1275  continue;
1276 
1277  ARC_BITS(arc).set_bit(Depth_First, true); // marque arco
1278 
1279  __compute_cut_nodes(g, list, tgt, arc, curr_df);
1280 
1281  if (low<GT>(tgt) < low<GT>(p))
1282  low<GT>(p) = low<GT>(tgt); // actualizar low(p)
1283 
1284  if (low<GT>(tgt) >= df<GT>(p) and df<GT>(tgt) != 0) // ¿de corte?
1285  p_is_cut_node = true;
1286  }
1287 
1288  // aquí, p ya fue explorado recursivamente
1289  if (p_is_cut_node)
1290  {
1291  NODE_BITS(p).set_bit(Cut, true);
1292  list.append(p);
1293  }
1294 }
1295 
1296 const long Cross_Arc = -1;
1297 
1298  template <class GT> inline static
1299 bool is_a_cross_arc(typename GT::Arc * a)
1300 {
1301  return ARC_COUNTER(a) == Cross_Arc;
1302 }
1303 
1304  template <class GT> inline static
1305 bool is_a_cut_node(typename GT::Node * p)
1306 {
1307  return NODE_BITS(p).get_bit(Cut);
1308 }
1309 
1310  template <class GT> inline static
1311 bool is_an_cut_arc(typename GT::Arc * a)
1312 {
1313  return ARC_BITS(a).get_bit(Cut);
1314 }
1315  template <class GT> inline static
1316 bool is_node_painted(typename GT::Node * p)
1317 {
1318  return NODE_COUNTER(p) > 0;
1319 }
1320 
1321  template <class GT> inline static
1322 bool is_arc_painted(typename GT::Arc * arc)
1323 {
1324  return ARC_COUNTER(arc) > 0;
1325 }
1326 
1327  template <class GT> inline static
1328 void paint_node(typename GT::Node * p, const long & color)
1329 {
1330  NODE_COUNTER(p) = color;
1331 }
1332 
1333  template <class GT> inline static
1334 void paint_arc(typename GT::Arc * a, const long & color)
1335 {
1336  ARC_COUNTER(a) = color;
1337 }
1338 
1339  template <class GT> inline static
1340 const long & get_color(typename GT::Node * p)
1341 {
1342  return NODE_COUNTER(p);
1343 }
1344 
1345  template <class GT> inline static
1346 const long & get_color(typename GT::Arc * a)
1347 {
1348  return ARC_COUNTER(a);
1349 }
1350 
1351 
1352  template <class GT> inline static
1353 void __paint_subgraph(const GT & g, typename GT::Node * p, long current_color)
1354 {
1355  assert(not is_a_cut_node <GT> (p));
1356 
1357  if (is_node_painted <GT> (p))
1358  return;
1359 
1360  paint_node <GT> (p, current_color);
1361 
1362  for (auto it = g.get_arc_it(p); it.has_curr(); it.next_ne())
1363  {
1364  auto arc = it.get_current_arc_ne();
1365  if (is_arc_painted <GT> (arc))
1366  continue;
1367 
1368  auto tgt = it.get_tgt_node_ne();
1369  if (is_a_cut_node <GT> (tgt))
1370  continue;
1371 
1372  paint_arc <GT> (arc, current_color);
1373 
1374  __paint_subgraph(g, tgt, current_color);
1375  }
1376 }
1377 
1378 template <class GT> inline static
1379 void
1380 __paint_from_cut_node(const GT & g, typename GT::Node * p, long & current_color)
1381 {
1382  assert(is_a_cut_node <GT> (p));
1383 
1384  // pintar recursivamente con dif colores bloques conectados a p
1385  for (auto it = g.get_arc_it(p); it.has_curr(); it.next_ne())
1386  {
1387  auto arc = it.get_current_arc_ne();
1388 
1389  assert(not is_arc_painted <GT> (arc));
1390 
1391  auto tgt_node = it.get_tgt_node_ne();
1392  if (is_a_cut_node <GT> (tgt_node)) // ¿ es un arco de corte?
1393  {
1394  ARC_BITS(arc).set_bit(Cut, true); // marque como de corte
1395  continue; // avance a próximo arco
1396  }
1397  else
1398  {
1399  paint_arc <GT> (arc, Cross_Arc); // marque como de cruce
1400  if (is_node_painted <GT> (tgt_node))
1401  continue;
1402  }
1403 
1404  // pintar recursivamente nodo conectado a arc
1405  __paint_subgraph(g, tgt_node, current_color);
1406 
1407  current_color++; // cambiar color (sig arco en otro bloque)
1408 
1409  assert(not is_arc_painted <GT> (arc));
1410  }
1411 }
1412 
1446  template <class GT> inline long
1447 paint_subgraphs(const GT & g, const DynList<typename GT::Node*> & cut_node_list)
1448 {
1449  g.reset_counter_nodes();
1450  g.reset_counter_arcs();
1451  long current_color = 1;
1452 
1453  // Recorrer cada nodo de corte y pintar sus bloques
1454  for (auto it = cut_node_list.get_it(); it.has_curr(); it.next_ne())
1455  __paint_from_cut_node(g, it.get_curr_ne(), current_color);
1456 
1457  return current_color;
1458 }
1459 
1460 
1461  template <class GT> inline static
1462 void __map_subgraph(const GT & g, GT & sg, typename GT::Node * gsrc,
1463  const long color)
1464 {
1465  assert(get_color <GT> (gsrc) == color);
1466 
1467  auto tsrc = mapped_node<GT>(gsrc); // gsrc en sg
1468 
1469  // recorrer arcos de gsrc y añadir a sg los del color de interés
1470  for (auto it = g.get_arc_it(gsrc); it.has_curr(); it.next_ne())
1471  {
1472  auto garc = it.get_current_arc_ne();
1473  if (get_color<GT>(garc) != color or IS_ARC_VISITED(garc, Build_Subtree))
1474  continue; // arco es de otro color o ya está visitado
1475 
1476  ARC_BITS(garc).set_bit(Build_Subtree, true);
1477 
1478  auto gtgt = it.get_tgt_node_ne();
1479 
1480  assert(get_color <GT> (gtgt) == color);
1481 
1482  auto ttgt = nullptr; // imagen gtgt en sg
1483  if (IS_NODE_VISITED(gtgt, Build_Subtree)) // ¿gtgt en sg?
1484  ttgt = mapped_node<GT> (gtgt);
1485  else
1486  { // gtgt no está en sg ==> copiarlo y mapearlo
1487  unique_ptr<typename GT::Node> ttgt_auto(new typename GT::Node(gtgt));
1488  sg.insert_node(ttgt_auto.get());
1489  GT::map_nodes(gtgt, ttgt_auto.get());
1490  NODE_BITS(gtgt).set_bit(Build_Subtree, true);
1491  ttgt = ttgt_auto.release();
1492  }
1493 
1494  auto tarc = sg.insert_arc(tsrc, ttgt, garc->get_info());
1495  GT::map_arcs(garc, tarc);
1496 
1497  __map_subgraph(g, sg, gtgt, color);
1498  }
1499 }
1500 
1520  template <class GT>
1521 GT map_subgraph(const GT & g, const long color)
1522 {
1523  typename GT::Node * first = nullptr; // busque primer nodo con color
1524  for (auto it = g.get_node_it(); it.has_curr(); it.next_ne())
1525  if (get_color <GT> (it.get_current_node_ne()) == color)
1526  first = it.get_current_node_ne();
1527 
1528  if (first == nullptr) // Encontró el color?
1529  throw std::domain_error("Color does not exist in the graph");
1530 
1531  GT sg;
1532  unique_ptr<typename GT::Node> auto_tsrc(new typename GT::Node(first));
1533  sg.insert_node(auto_tsrc.get());
1534  GT::map_nodes(first, auto_tsrc.release());
1535  NODE_BITS(first).set_bit(Build_Subtree, true);
1536 
1537  __map_subgraph(g, sg, first, color); // mapee first
1538 
1539  return sg;
1540 }
1541 
1567  template <class GT>
1568  std::tuple<GT, DynList<typename GT::Arc*>>
1569 map_cut_graph(const GT & g, const DynList<typename GT::Node*> & cut_node_list)
1570 {
1571  GT cut_graph;
1572  DynList<typename GT::Arc*> cross_arc_list;
1573 
1574  for (auto it = cut_node_list.get_it(); it.has_curr(); it.next_ne())
1575  {
1576  auto gp = it.get_curr_ne();
1577 
1578  assert(is_a_cut_node <GT> (gp));
1579 
1580  unique_ptr<typename GT::Node> tp_auto(new typename GT::Node(gp));
1581  cut_graph.insert_node(tp_auto.get());
1582  GT::map_nodes(gp, tp_auto.release());
1583  }
1584 
1585  // cut_graph = {not cut arcs} U cross_arc_list = {cross arcs}
1586  for (auto it = g.get_arc_it(); it.has_curr(); it.next_ne())
1587  {
1588  auto garc = it.get_current_arc_ne();
1589  if (is_a_cross_arc <GT> (garc))
1590  {
1591  cross_arc_list.append(garc);
1592  continue;
1593  }
1594 
1595  if (not is_an_cut_arc <GT> (garc))
1596  continue;
1597 
1598  auto src = mapped_node<GT>(g.get_src_node(garc));
1599  auto tgt = mapped_node<GT>(g.get_tgt_node(garc));
1600 
1601  assert(src != nullptr and tgt != nullptr);
1602 
1603  auto arc = cut_graph.insert_arc(src, tgt, garc->get_info());
1604  GT::map_arcs(garc, arc);
1605  }
1606 
1607  return { cut_graph, cross_arc_list };
1608 }
1609 
1610 
1617  template <class GT, class Distance>
1619 {
1620  Distance dist;
1621 
1622  Distance_Compare(Distance __dist = Distance()) : dist(__dist) { /* empty */ }
1623 
1624  bool operator () (typename GT::Arc * a1, typename GT::Arc * a2) const
1625  {
1626  return dist(a1) < dist(a2);
1627  }
1628 };
1629 
1630 
1641  template <class GT>
1642 GT invert_digraph(const GT & g)
1643 {
1644  g.reset_nodes();
1645  GT gi;
1646 
1647  for (auto it = g.get_arc_it(); it.has_curr(); it.next_ne())
1648  {
1649  auto arc = it.get_curr_ne();
1650 
1651  auto ssrc = g.get_src_node(arc);
1652  auto rsrc = mapped_node<GT> (ssrc);
1653  if (rsrc == nullptr) // ¿ya está creado ssrc en gi?
1654  { // no == crearlo, insertarlo y mapearlo
1655  unique_ptr<typename GT::Node> rsrc_auto(new typename GT::Node(ssrc));
1656  gi.insert_node(rsrc_auto.get());
1657  GT::map_nodes(ssrc, rsrc_auto.get());
1658  rsrc = rsrc_auto.release();
1659  }
1660 
1661  auto stgt = g.get_tgt_node(arc);
1662  auto rtgt = mapped_node<GT> (stgt);
1663  if (rtgt == nullptr) // ¿ya está creado ssrc en gi?
1664  { // no == crearlo, insertarlo y mapearlo
1665  unique_ptr<typename GT::Node> rtgt_auto(new typename GT::Node(stgt));
1666  gi.insert_node(rtgt_auto.get());
1667  GT::map_nodes(stgt, rtgt_auto.get());
1668  rtgt = rtgt_auto.release();
1669  }
1670 
1671  typename GT::Arc * ai = gi.insert_arc(rtgt, rsrc, arc->get_info());
1672  GT::map_arcs(arc, ai);
1673  }
1674 
1675  assert(g.get_num_arcs() == gi.get_num_arcs() and
1676  g.get_num_nodes() == gi.get_num_nodes());
1677 
1678  return gi;
1679 }
1680 
1681 
1686  template <class GT, class SA = Dft_Show_Arc<GT>>
1688 {
1689  SA sa;
1690 
1691 public:
1692 
1694  Invert_Digraph(SA __sa) : sa(__sa) { /* empty */ }
1695 
1705  GT operator () (const GT & g) const
1706  {
1707  g.reset_nodes();
1708  GT gi;
1709 
1710  for (Arc_Iterator<GT, SA> it(g, sa); it.has_curr(); it.next_ne())
1711  {
1712  auto arc = it.get_curr_ne();
1713 
1714  auto ssrc = g.get_src_node(arc);
1715  auto rsrc = mapped_node<GT> (ssrc);
1716  if (rsrc == nullptr) // ¿ya está creado ssrc en gi?
1717  { // no == crearlo, insertarlo y mapearlo
1718  unique_ptr<typename GT::Node> rsrc_auto(new typename GT::Node(ssrc));
1719  gi.insert_node(rsrc_auto.get());
1720  GT::map_nodes(ssrc, rsrc_auto.get());
1721  rsrc = rsrc_auto.release();
1722  }
1723 
1724  auto stgt = g.get_tgt_node(arc);
1725  auto rtgt = mapped_node<GT> (stgt);
1726  if (rtgt == nullptr) // ¿ya está creado ssrc en gi?
1727  { // no == crearlo, insertarlo y mapearlo
1728  unique_ptr<typename GT::Node> rtgt_auto(new typename GT::Node(stgt));
1729  gi.insert_node(rtgt_auto.get());
1730  GT::map_nodes(stgt, rtgt_auto.get());
1731  rtgt = rtgt_auto.release();
1732  }
1733 
1734  typename GT::Arc * ai = gi.insert_arc(rtgt, rsrc, arc->get_info());
1735  GT::map_arcs(arc, ai);
1736  }
1737 
1738  assert(g.get_num_arcs() == gi.get_num_arcs() and
1739  g.get_num_nodes() == gi.get_num_nodes());
1740 
1741  return gi;
1742  invert_digraph <GT, SA> (g, gi, sa);
1743  }
1744 };
1745 
1752  template <class GT>
1754 {
1755 public:
1756 
1757  typedef typename GT::Arc_Type Distance_Type;
1758 
1759  static const Distance_Type Zero_Distance;
1760 
1761  static const Distance_Type Max_Distance;
1762 
1763  Distance_Type & operator () (typename GT::Arc * a) const
1764  {
1765  return a->get_info();
1766  }
1767 
1768  Distance_Type & operator () (typename GT::Arc * a, typename GT::Node*) const
1769  {
1770  return a->get_info();
1771  }
1772 
1773  static void set_zero(typename GT::Arc * a) { a->get_info() = 0; }
1774 };
1775 
1776 template <class GT>
1777 const typename Dft_Dist<GT>::Distance_Type Dft_Dist<GT>::Max_Distance =
1778  std::numeric_limits<typename Dft_Dist<GT>::Distance_Type>::max();
1779 
1780 template <class GT>
1781 const typename Dft_Dist<GT>::Distance_Type Dft_Dist<GT>::Zero_Distance = 0.0;
1782 
1796 template <class GT, class Distance = Dft_Dist<GT>>
1797  typename Distance::Distance_Type
1798 get_min_path(typename GT::Node * s, typename GT::Node * end, Path<GT> & path)
1799 {
1800  typename Distance::Distance_Type dist = 0.0;
1801  path.empty();
1802  path.insert(end);
1803 
1804  auto p = end;
1805  do
1806  {
1807  p = (typename GT::Node *) NODE_COOKIE(p);
1808  path.insert(p);
1809  dist = dist + Distance() (path.get_first_arc());
1810  }
1811  while (p != s);
1812 
1813  return dist;
1814 }
1815 
1822 template <class GT,
1823  class Distance = Dft_Dist<GT>,
1824  class SA = Dft_Show_Arc<GT>>
1826 {
1827  Distance dist;
1828  SA sa;
1829 
1830 public:
1831 
1832  Total_Cost(Distance __dist = Distance(), SA __sa = SA())
1833  : dist(__dist), sa(__sa)
1834  {
1835  // empty
1836  }
1837 
1839  typename Distance::Distance_Type total_cost(GT & g)
1840  {
1841  typename Distance::Distance_Type sum = 0;
1842 
1843  // recorrer todos los arcos y sumar su peso
1844  for (Arc_Iterator <GT, SA> it(g, sa); it.has_curr(); it.next_ne())
1845  sum += dist(it.get_current_arc_ne());
1846 
1847  return sum;
1848  }
1849 
1851  typename Distance::Distance_Type operator () (GT & g)
1852  {
1853  return total_cost (g);
1854  }
1855 
1856  bool operator () (typename GT::Arc * a)
1857  {
1858  if (not sa(a))
1859  return false;
1860 
1861  dist += dist(a);
1862  return true;
1863  }
1864 };
1865 
1866 
1867 
1868 } // end namespace Aleph
1869 
1870 # endif // TPL_GRAPH_UTILS_H
Definition: tpl_graph_utils.H:138
GT invert_digraph(const GT &g)
Definition: tpl_graph_utils.H:1642
DynList< typename GT::Node * > compute_cut_nodes(const GT &g, typename GT::Node *start)
Definition: tpl_graph_utils.H:1199
Definition: tpl_graph.H:1225
long paint_subgraphs(const GT &g, const DynList< typename GT::Node *> &cut_node_list)
Definition: tpl_graph_utils.H:1447
#define ARC_COUNTER(p)
Definition: aleph-graph.H:339
Invert_Digraph(SA __sa)
Construct functor wih filter sa.
Definition: tpl_graph_utils.H:1694
Pair * insert(const Key &key, const Data &data)
Definition: tpl_dynMapTree.H:112
#define NODE_COOKIE(p)
Definition: aleph-graph.H:333
GT build_spanning_tree(const DynArray< typename GT::Arc *> &arcs)
Definition: tpl_graph_utils.H:1115
auto get_it() const
Definition: htlist.H:151
bool is_empty() const noexcept
rioReturn true if this is empty
Definition: tpl_dynListQueue.H:112
bool test_connectivity(const GT &g)
Definition: tpl_graph_utils.H:565
void insert(Arc *arc)
Definition: tpl_graph.H:2951
void for_each(Operation &operation) noexcept(noexcept(operation))
Definition: htlist.H:589
Definition: tpl_dynMapTree.H:62
Path< GT > find_path_breadth_first(const GT &g, typename GT::Node *start, typename GT::Node *end)
Definition: tpl_graph_utils.H:487
Breadth_First_Traversal(SA __sa=SA())
Definition: tpl_graph_utils.H:438
#define IS_NODE_VISITED(p, bit)
Definition: aleph-graph.H:327
bool test_for_cycle(const GT &g, typename GT::Node *src)
Definition: tpl_graph_utils.H:603
size_t breadth_first_traversal(const GT &g, typename GT::Node *start, bool(*visit)(const GT &, typename GT::Node *, typename GT::Arc *))
Definition: tpl_graph_utils.H:280
GT map_subgraph(const GT &g, const long color)
Definition: tpl_graph_utils.H:1521
Definition: tpl_graph_utils.H:1618
void build_subgraph(const GT &g, GT &sg, typename GT::Node *g_src, size_t &node_count)
Definition: tpl_graph_utils.H:878
Definition: tpl_dynListQueue.H:50
bool test_for_path(const GT &g, typename GT::Node *start_node, typename GT::Node *end_node)
Definition: tpl_graph_utils.H:756
#define ARC_COOKIE(p)
Definition: aleph-graph.H:366
#define NODE_COUNTER(p)
Definition: aleph-graph.H:311
void map_arcs(typename GTS::Arc *p, typename GTT::Arc *q) noexcept
Definition: tpl_graph.H:3445
Distance::Distance_Type total_cost(GT &g)
Compute the total cost.
Definition: tpl_graph_utils.H:1839
#define IS_ARC_VISITED(p, bit)
Definition: aleph-graph.H:360
Depth_First_Traversal(SA __sa=SA())
Definition: tpl_graph_utils.H:195
Definition: tpl_graph.H:53
DynList< typename GT::Arc * > arcs(typename GT::Node *p, SA sa=SA())
Definition: tpl_graph.H:1893
void map_nodes(typename GTS::Node *p, typename GTT::Node *q) noexcept
Definition: tpl_graph.H:3419
Definition: ah-comb.H:35
Definition: tpl_graph_utils.H:378
Definition: tpl_graph.H:1063
DynList< GT > inconnected_components(const GT &g)
Definition: tpl_graph_utils.H:830
Arc * get_first_arc() const
Definition: tpl_graph.H:3082
Pair * search(const Key &key) const noexcept
Definition: tpl_dynMapTree.H:214
#define NODE_BITS(p)
Definition: aleph-graph.H:305
Definition: tpl_graph_utils.H:96
Definition: tpl_graph_utils.H:1753
Definition: tpl_graph_utils.H:1687
#define ARC_BITS(p)
Definition: aleph-graph.H:351
void empty() noexcept
Empty the queue.
Definition: tpl_dynListQueue.H:185
Definition: tpl_dynArray.H:159
GT find_depth_first_spanning_tree(const GT &g, typename GT::Node *gnode)
Definition: tpl_graph_utils.H:943
size_t depth_first_traversal(const GT &g, typename GT::Node *start_node, bool(*visit)(const GT &g, typename GT::Node *, typename GT::Arc *))
Definition: tpl_graph_utils.H:69
Definition: tpl_graph_utils.H:1825
GT find_breadth_first_spanning_tree(GT &g, typename GT::Node *gp)
Definition: tpl_graph_utils.H:1035
Definition: ahDry.H:41
void empty()
Clean the path: all the nodes and arc are removed.
Definition: tpl_graph.H:2761
T & append(const T &item)
Definition: htlist.H:1471
std::tuple< GT, DynList< typename GT::Arc * > > map_cut_graph(const GT &g, const DynList< typename GT::Node *> &cut_node_list)
Definition: tpl_graph_utils.H:1569
T get()
Definition: tpl_dynListQueue.H:165
Definition: tpl_graph.H:1177
Definition: List.H:49
T & put(const T &data)
The type of element.
Definition: tpl_dynListQueue.H:125
T & get_last() const
Definition: htlist.H:1572

Leandro Rabindranath León