Aleph-w  1.5a.2
Biblioteca general de algoritmos y estructuras de datos
 Todo Clases Archivos Funciones Variables 'typedefs' Enumeraciones Amigas Grupos Páginas
tpl_graph_utils.H
1 # ifndef TPL_GRAPH_UTILS_H
2 # define TPL_GRAPH_UTILS_H
3 
4 
5 # include <limits>
6 # include <tpl_agraph.H>
7 # include <tpl_dynListQueue.H>
8 
9 using namespace Aleph;
10 
11 namespace Aleph {
12 
13  template <class GT, class SA> inline static bool
14 __depth_first_traversal(GT & g, typename GT::Node * node,
15  typename GT::Arc * arc,
16  bool (*visit)(GT & g, typename GT::Node *,
17  typename GT::Arc *),
18  size_t & count);
19 
65  template <class GT, class SA = Dft_Show_Arc<GT>> inline size_t
66 depth_first_traversal(GT & g, typename GT::Node * start_node,
67  bool (*visit)(GT & g, typename GT::Node *,
68  typename GT::Arc *),
69  SA sa = SA())
70 {
71  g.reset_bit_nodes(Depth_First); // reiniciar Depth_First de nodos
72  g.reset_bit_arcs(Depth_First); // reiniciar Depth_First de arcos
73  size_t counter = 0; // inicialmente no se ha visitado ningún nodo
74 
75  __depth_first_traversal<GT,SA>(g, start_node, NULL, visit, counter, sa);
76 
77  return counter;
78 }
79 
114  template <class GT, class SA = Dft_Show_Arc<GT>> inline
115 size_t depth_first_traversal(GT & g,
116  bool (*visit)(GT &, typename GT::Node *,
117  typename GT::Arc *),
118  SA sa = SA())
119 {
120  return depth_first_traversal <GT, SA> (g, g.get_first_node(), visit, sa);
121 }
122 
127  template <class GT>
129 {
130  bool operator () (GT &, typename GT::Node *, typename GT::Arc *)
131  {
132  return false;
133  }
134 };
135 
192  template <class GT,
193  class Operation = Default_Visit_Op<GT>,
194  class SA = Dft_Show_Arc<GT>>
196 {
197  Operation * op;
198  SA & sa;
199  size_t count;
200  GT * g_ptr;
201 
202 private:
203 
204  bool __dft(typename GT::Node * node, typename GT::Arc * arc = NULL)
205  {
206  if (IS_NODE_VISITED(node, Depth_First))
207  return false;
208 
209  NODE_BITS(node).set_bit(Depth_First, true); // marca nodo visitado
210  count++;
211 
212  if ((*op)(*g_ptr, node, arc))
213  return true; // sí, invóquela
214 
215  if (count == g_ptr->get_num_nodes()) // ¿se visitaron todos lo nodos?
216  return true;
217 
218  // recorrer recursivamente arcos de node
219  for (Node_Arc_Iterator<GT, SA> it(node, sa); it.has_current(); it.next())
220  {
221  typename GT::Arc * arc = it.get_current_arc();
222  if (IS_ARC_VISITED(arc, Depth_First))
223  continue;
224 
225  ARC_BITS(arc).set_bit(Depth_First, true); // visitado
226  if (__dft (it.get_tgt_node(), arc))
227  return true; // ya se exploró cabalmente it.get_tgt_node()
228  }
229 
230  return false; // retorne y siga explorando
231  }
232 
233  size_t dft(GT & g, typename GT::Node * start_node, Operation & __op)
234  {
235  op = &__op;
236  g_ptr = &g;
237 
238  g_ptr->reset_bit_nodes(Depth_First); // reiniciar Depth_First de nodos
239  g_ptr->reset_bit_arcs(Depth_First); // reiniciar Depth_First de arcos
240 
241  count = 0;
242 
243  __dft(start_node);
244 
245  return count;
246  }
247 
248 public:
249 
252  Depth_First_Traversal(SA && __sa = SA())
253  : sa(__sa)
254  {
255  /* empty */
256  }
257 
261  : sa(__sa)
262  {
263  /* empty */
264  }
265 
272  size_t operator () (GT & g, Operation && op = Operation())
273  {
274  return dft(g, g.get_first_node(), op);
275  }
276 
277  size_t operator () (GT & g, Operation & op)
278  {
279  return dft(g, g.get_first_node(), op);
280  }
281 
289  size_t operator () (GT & g, typename GT::Node * sn,
290  Operation && op = Operation())
291  {
292  return dft(g, sn, op);
293  }
294 
295  size_t operator () (GT & g, typename GT::Node * sn, Operation & op)
296  {
297  return dft(g, sn, op);
298  }
299 };
300 
301 
302  template <class GT, class SA> inline static bool
303 __depth_first_traversal(GT & g, typename GT::Node * node,
304  typename GT::Arc * arc,
305  bool (*visit)(GT & g, typename GT::Node *,
306  typename GT::Arc *),
307  size_t & count,
308  SA sa = SA())
309 {
310  if (IS_NODE_VISITED(node, Depth_First))
311  return false;
312 
313  NODE_BITS(node).set_bit(Depth_First, true); // marca nodo visitado
314  count++;
315 
316  if (visit != NULL) // verifique si hay función de visita
317  if ((*visit)(g, node, arc))
318  return true; // sí, invóquela
319 
320  if (count == g.get_num_nodes()) // ¿se visitaron todos lo nodos?
321  return true;
322 
323  // recorrer recursivamente arcos de node
324  for (Node_Arc_Iterator<GT, SA> it(node, sa); it.has_current(); it.next())
325  {
326  typename GT::Arc * arc = it.get_current_arc();
327  if (IS_ARC_VISITED(arc, Depth_First))
328  continue;
329 
330  ARC_BITS(arc).set_bit(Depth_First, true); // visitado
331  if (__depth_first_traversal<GT, SA>(g, it.get_tgt_node(), arc,
332  visit, count, sa))
333  return true; // ya se exploró cabalmente it.get_tgt_node()
334  }
335 
336  return false; // retorne y siga explorando
337 }
338 
379  template <class GT, class SA = Dft_Show_Arc<GT>> inline size_t
380 breadth_first_traversal(GT & g, typename GT::Node * start,
381  bool (*visit)(GT &, typename GT::Node *,
382  typename GT::Arc *) )
383 {
384  g.reset_bit_nodes(Breadth_First);
385  g.reset_bit_arcs(Breadth_First);
386  DynListQueue<typename GT::Arc*> q; // cola de arcos pendientes
387 
388  // ingresar a la cola los arcos de nodo start
389  for (Node_Arc_Iterator<GT, SA> it(start); it.has_current(); it.next())
390  q.put(it.get_current_arc());
391 
392  NODE_BITS(start).set_bit(Breadth_First, true);
393  size_t node_counter = 1; // contador de nodos visitados
394 
395  if (visit != NULL)
396  if ((*visit)(g, start, NULL))
397  return 1;
398 
399  // mientras queden arcos en cola y resten todos por visitar
400  while (not q.is_empty() and node_counter < g.get_num_nodes())
401  {
402  typename GT::Arc * arc = q.get();// saque de cola más cercano
403  ARC_BITS(arc).set_bit(Breadth_First, true);
404 
405  typename GT::Node * src = g.get_src_node(arc);
406  typename GT::Node * tgt = g.get_tgt_node(arc);
407  if (IS_NODE_VISITED(src, Breadth_First) and
408  IS_NODE_VISITED(tgt, Breadth_First))
409  continue;
410 
411  typename GT::Node * visit_node = // próximo a visitar
412  IS_NODE_VISITED(src, Breadth_First) ? tgt : src;
413 
414  if (visit != NULL)
415  if ((*visit)(g, visit_node, arc))
416  break;
417 
418  NODE_BITS(visit_node).set_bit(Breadth_First, true);
419  node_counter++;
420 
421  // insertar en cola arcos del nodo recién visitado
422  for (Node_Arc_Iterator<GT, SA> it(visit_node); it.has_curr(); it.next())
423  {
424  typename GT::Arc * curr_arc = it.get_current_arc();
425  if (IS_ARC_VISITED(curr_arc, Breadth_First))
426  continue;
427 
428  // revise nodos del arcos para ver si han sido visitados
429  if (IS_NODE_VISITED(g.get_src_node(curr_arc), Breadth_First) and
430  IS_NODE_VISITED(g.get_tgt_node(curr_arc), Breadth_First))
431  continue; // nodos ya visitados
432 
433  q.put(curr_arc);
434  }
435  }
436 
437  return node_counter;
438  }
439 
483  template <class GT, class SA = Dft_Show_Arc<GT>> inline size_t
485  bool (*visit)(GT &, typename GT::Node *,
486  typename GT::Arc *)
487  )
488 {
489  return breadth_first_traversal<GT, SA>(g, g.get_first_node(), visit);
490 }
491 
524  template <class GT,
525  class Operation = Default_Visit_Op<GT>,
526  class SA = Dft_Show_Arc<GT>>
528 {
529  SA & sa;
530  size_t count;
531 
532  size_t bft(GT & g, typename GT::Node * start, Operation & op)
533  {
534  g.reset_bit_nodes(Breadth_First);
535  g.reset_bit_arcs(Breadth_First);
536  DynListQueue<typename GT::Arc*> q; // cola de arcos pendientes
537 
538  // ingresar a la cola los arcos de nodo start
539  for (Node_Arc_Iterator<GT, SA> it(start); it.has_current(); it.next())
540  q.put(it.get_current_arc());
541 
542  NODE_BITS(start).set_bit(Breadth_First, true);
543  count = 1; // contador de nodos visitados
544 
545  if (op (g, start, NULL))
546  return 1;
547 
548  // mientras queden arcos en cola y resten todos por visitar
549  while (not q.is_empty() and count < g.get_num_nodes())
550  {
551  typename GT::Arc * arc = q.get();// saque de cola más cercano
552  ARC_BITS(arc).set_bit(Breadth_First, true);
553 
554  typename GT::Node * src = g.get_src_node(arc);
555  typename GT::Node * tgt = g.get_tgt_node(arc);
556 
557  if (IS_NODE_VISITED(src, Breadth_First) and
558  IS_NODE_VISITED(tgt, Breadth_First))
559  continue;
560 
561  typename GT::Node * curr = // próximo a visitar
562  IS_NODE_VISITED(src, Breadth_First) ? tgt : src;
563 
564  if (op (g, curr, arc))
565  break;
566 
567  NODE_BITS(curr).set_bit(Breadth_First, true);
568  count++;
569 
570  // insertar en cola arcos del nodo recién visitado
571  for (Node_Arc_Iterator<GT, SA> it(curr); it.has_current(); it.next())
572  {
573  typename GT::Arc * curr_arc = it.get_current_arc();
574  if (IS_ARC_VISITED(curr_arc, Breadth_First))
575  continue;
576 
577  // revise nodos del arcos para ver si han sido visitados
578  if (IS_NODE_VISITED(g.get_src_node(curr_arc), Breadth_First) and
579  IS_NODE_VISITED(g.get_tgt_node(curr_arc), Breadth_First))
580  continue; // nodos ya visitados
581 
582  q.put(curr_arc);
583  }
584  }
585 
586  return count;
587  }
588 
589 public:
590 
593  Breadth_First_Traversal(SA && __sa = SA()) : sa(__sa) { /* empty */ }
594 
595  Breadth_First_Traversal(SA & __sa) : sa(__sa) { /* empty */ }
596 
605  size_t operator () (GT & g, Operation && op = Operation())
606  {
607  return bft (g, g.get_first_node(), op);
608  }
609 
610  size_t operator () (GT & g, Operation & op)
611  {
612  return bft (g, g.get_first_node(), op);
613  }
614 
624  size_t operator () (GT & g, typename GT::Node * p,
625  Operation && op = Operation())
626  {
627  return bft(g, p, op);
628  }
629 
630  size_t operator () (GT & g, typename GT::Node * p, Operation & op)
631  {
632  return bft(g, p, op);
633  }
634 };
635 
636 
637  template <class GT> inline static
638 void __insert_in_queue(GT & g, DynListQueue<Path<GT> *> & q,
639  typename GT::Node * node, typename GT::Arc * arc,
640  Path<GT> * path_ptr = NULL)
641 {
642  unique_ptr<Path<GT>> path_auto;
643  if (path_ptr == NULL) // ¿iniciar o copiar*
644  path_auto = unique_ptr<Path<GT>>(new Path<GT>(g, node)); // iniciar
645  else
646  path_auto = unique_ptr<Path<GT>>(new Path<GT>(*path_ptr));// copiar
647 
648  path_auto->append(arc); // añadir el nuevo arco
649  q.put(path_auto.get()); // insertar el nuevo camino en cola
650  path_auto.release();
651 }
652 
684  template <class GT, class SA = Dft_Show_Arc<GT>> inline
685 bool find_path_breadth_first(GT & g, typename GT::Node * start,
686  typename GT::Node * end, Path<GT> & path)
687 {
688  if (not path.inside_graph(g))
689  throw std::invalid_argument("Path does not belong to graph");
690 
691  path.clear_path(); // limpiamos cualquier cosa que esté en path
692  g.reset_nodes();
693  g.reset_arcs();
694 
695  DynListQueue<typename GT::Arc*> q; // cola de caminos parciales
696 
697  // insertar arcs iniciales que salen desde start
698  for (Node_Arc_Iterator<GT, SA> i(start); i.has_curr(); i.next())
699  q.put(i.get_current_arc());
700 
701  NODE_BITS(start).set_bit(Find_Path, true); // márquelo visitado
702 
703  bool path_found = false;
704 
705  while (not q.is_empty()) // mientras queden arcos por visitar
706  {
707  typename GT::Arc * arc = q.get();
708  typename GT::Node * src = g.get_src_node(arc);
709  typename GT::Node * tgt = g.get_tgt_node(arc);
710 
711  if (IS_NODE_VISITED(src, Find_Path) and IS_NODE_VISITED(tgt, Find_Path))
712  continue;
713 
714  if (IS_NODE_VISITED(tgt, Find_Path))
715  std::swap(src, tgt);
716 
717  ARC_BITS(arc).set_bit(Find_Path, true);
718  NODE_BITS(tgt).set_bit(Find_Path, true);
719  NODE_COOKIE(tgt) = src;
720 
721  if (tgt == end) // ¿se encontró un camino?
722  {
723  path_found = true;
724  break;
725  }
726 
727  for (Node_Arc_Iterator<GT,SA> i(tgt); i.has_curr(); i.next())
728  {
729  typename GT::Arc * a = i.get_current_arc();
730  if (IS_ARC_VISITED(a, Find_Path)) // ¿arco visitado?
731  continue; // sí ==> avanzar al siguiente
732 
733  // revise nodos del arco para ver si han sido visitados
734  if (IS_NODE_VISITED(g.get_src_node(a), Find_Path) and
735  IS_NODE_VISITED(g.get_tgt_node(a), Find_Path))
736  continue; // nodos ya visitados ==> no meter arco
737 
738  q.put(a);
739  }
740  }
741 
742  if (not path_found)
743  return false;
744 
745  q.empty();
746  path.insert(end);
747  typename GT::Node * p = end;
748  while (p != start)
749  {
750  p = (typename GT::Node *) NODE_COOKIE(p);
751  path.insert(p);
752  }
753 
754  return true;
755 }
756 
757 
783  template <class GT, class SA = Dft_Show_Arc<GT>> inline
784 bool test_connectivity(GT & g)
785 {
786  if (g.is_digraph()) // sólo es válida para grafos, no digrafos
787  throw std::domain_error("test_connectivity() does not work on digraphs");
788 
789  if (g.get_num_arcs() < g.get_num_nodes() - 1)
790  return false;
791 
792  return depth_first_traversal<GT, SA>(g, NULL) == g.get_num_nodes();
793 }
794 
795 
796  template <class GT, class SA> inline static
797  bool __test_cycle(GT & g, typename GT::Node * src_node,
798  typename GT::Node * curr_node);
816  template <class GT, class SA = Dft_Show_Arc<GT>> inline
817  bool test_for_cycle(GT & g, typename GT::Node * src_node)
818  {
819  g.reset_bit_nodes(Test_Cycle); // reiniciar Test_Cycle para nodos
820  g.reset_bit_arcs(Test_Cycle); // reiniciar Test_Cycle para arcos
821 
822  // explorar recursivamente por arcos adyacentes a src_node
823  for (Node_Arc_Iterator<GT, SA> it(src_node); it.has_current(); it.next())
824  {
825  typename GT::Arc * arc = it.get_current_arc();
826  if (IS_ARC_VISITED(arc, Test_Cycle))
827  continue;
828 
829  ARC_BITS(arc).set_bit(Test_Cycle, true); // pintar arco
830 
831  if (__test_cycle<GT,SA>(g, src_node, it.get_tgt_node()))
832  return true; // ciclo detectado
833  }
834  // Se han explorado todos los caminos desde src_node
835  // sin encontrar de nuevo a src_node ==> no hay ciclo
836  return false;
837  }
838 
839 
840  template <class GT, class SA> inline static
841  bool __test_cycle(GT & g, typename GT::Node * src_node,
842  typename GT::Node * curr_node)
843  {
844  if (src_node == curr_node)
845  return true; // ciclo detectado!
846 
847  if (IS_NODE_VISITED(curr_node, Test_Cycle))
848  return false;
849 
850  NODE_BITS(curr_node).set_bit(Test_Cycle, true); // marque nodo
851 
852  // buscar caminos desde current_node a ver si llega a src_node
853  for (Node_Arc_Iterator<GT, SA> it(curr_node); it.has_current(); it.next())
854  {
855  typename GT::Arc * arc = it.get_current_arc();
856  if (IS_ARC_VISITED(arc, Test_Cycle))
857  continue;
858 
859  ARC_BITS(arc).set_bit(Test_Cycle, true); // marque arco
860 
861  if (__test_cycle<GT,SA>(g, src_node, it.get_tgt_node()))
862  return true; // ciclo encontrado desde el arco actual
863  }
864  // En este punto se han explorado caminos desde curr_node
865  // sin encontrar src_node ==> no existe ciclo por curr_node
866  return false;
867  }
868 
869  template <class GT, class SA> inline static
870  bool __is_graph_acyclique(GT & g, typename GT::Node * curr_node)
871  {
872  if (IS_NODE_VISITED(curr_node, Is_Acyclique))
873  return false;
874 
875  NODE_BITS(curr_node).set_bit(Is_Acyclique, true); // marcar nodo
876 
877  for (Node_Arc_Iterator<GT, SA> i(curr_node); i.has_current(); i.next())
878  {
879  typename GT::Arc * arc = i.get_current_arc();
880  if (IS_ARC_VISITED(arc, Is_Acyclique))
881  continue;
882 
883  ARC_BITS(arc).set_bit(Is_Acyclique, true);
884 
885  if (not __is_graph_acyclique<GT,SA>(g, i.get_tgt_node()))
886  return false;
887  }
888  // todos los arcos recorridos sin encontrar ciclo ==>
889  // el grafo es acíclico pasando por curr_node
890  return true;
891  }
892 
927  template <class GT, class SA = Dft_Show_Arc<GT>> inline
928 bool is_graph_acyclique(GT & g, typename GT::Node * start_node)
929 {
930  if (g.is_digraph())
931  throw std::domain_error("is_graph_acyclique() does not work for digraps");
932 
933  if (g.get_num_arcs() >= g.get_num_nodes())
934  return false;
935 
936  g.reset_bit_arcs(Is_Acyclique);
937  g.reset_bit_nodes(Is_Acyclique);
938 
939  return __is_graph_acyclique<GT,SA>(g, start_node);
940 }
941 
965  template <class GT, class SA = Dft_Show_Arc<GT>> inline
966 bool is_graph_acyclique(GT & g)
967 {
968  if (g.is_digraph())
969  throw std::domain_error("is_graph_acyclique() does not work for digraps");
970 
971  if (g.get_num_arcs() >= g.get_num_nodes())
972  return false;
973 
974  g.reset_bit_arcs(Is_Acyclique);
975  g.reset_bit_nodes(Is_Acyclique);
976 
977  for (Node_Iterator<GT> it(g); it.has_current(); it.next())
978  {
979  typename GT::Node * current_node = it.get_current_node();
980  if (IS_NODE_VISITED(current_node, Is_Acyclique))
981  continue;
982 
983  if (not __is_graph_acyclique<GT,SA>(g, current_node))
984  return false;
985  }
986 
987  return true;
988 }
989 
1024  template <class GT, class SA = Dft_Show_Arc<GT>>
1025 inline bool has_cycle(GT & g)
1026 {
1027  return not is_graph_acyclique<GT,SA>(g);
1028 }
1029 
1030 
1031  template <class GT, class SA> inline static
1032 bool __test_for_path(GT & g, typename GT::Node * curr_node,
1033  typename GT::Node * end_node);
1034 
1064  template <class GT, class SA = Dft_Show_Arc<GT>> inline
1065 bool test_for_path(GT& g, typename GT::Node * start_node,
1066  typename GT::Node * end_node)
1067 { // si el grafo es conexo ==> existe camino
1068  if (not g.is_digraph() and g.get_num_arcs() >= g.get_num_nodes())
1069  return true;
1070 
1071  g.reset_bit_nodes(Test_Path);
1072  g.reset_bit_arcs(Test_Path);
1073 
1074  // buscar recursivamente por arcos adyacentes a start_node
1075  for (Node_Arc_Iterator<GT, SA> i(start_node); i.has_current(); i.next())
1076  {
1077  typename GT::Arc * arc = i.get_current_arc();
1078  ARC_BITS(arc).set_bit(Test_Path, true); // marcar arco
1079  if (__test_for_path<GT, SA>(g, i.get_tgt_node(), end_node))
1080  return true;
1081  }
1082  // todos los arcos de start_node han sido explorados sin
1083  // encontrar camino hasta end_node ==> no existe camino
1084  return false;
1085 }
1086 
1087 
1088  template <class GT, class SA> inline static
1089 bool __test_for_path(GT & g, typename GT::Node * curr_node,
1090  typename GT::Node * end_node)
1091 {
1092  if (curr_node == end_node)
1093  return true; // se alcanzó a end_node
1094 
1095  if (IS_NODE_VISITED(curr_node, Test_Path)) // ¿se visitó curr_node?
1096  return false; // sí, no explore
1097 
1098  NODE_BITS(curr_node).set_bit(Test_Path, true); // pintar curr_node
1099 
1100  // buscar recursivamente a través de arcos de curr_node
1101  for (Node_Arc_Iterator<GT, SA> i(curr_node); i.has_current(); i.next())
1102  {
1103  typename GT::Arc * arc = i.get_current_arc();
1104  if (IS_ARC_VISITED(arc, Test_Path))
1105  continue;
1106 
1107  ARC_BITS(arc).set_bit(Test_Path, true); // pintar arco
1108  if (__test_for_path<GT, SA>(g, i.get_tgt_node(), end_node))
1109  return true;
1110  }
1111 
1112  // todos los arcos adyacentes de curr_node explorados sin
1113  // encontrar a end_node ==> no existe camino por curr_node
1114  return false;
1115 }
1116 
1117  template <class GT, class SA = Dft_Show_Arc<GT>> inline
1118  void inconnected_components(GT & g, DynDlist<GT> & list);
1119 
1120  template <class GT, class SA = Dft_Show_Arc<GT>> inline
1121  void build_subgraph(GT & g, GT & sg,
1122  typename GT::Node * g_src, size_t & node_count);
1123 
1124 
1125 
1163  template <class GT, class SA> inline
1165 {
1166  g.reset_nodes();
1167  g.reset_arcs();
1168  size_t count = 0; // contador de nodos visitados
1169  for (typename GT::Node_Iterator i(g); // recorrer nodos de g
1170  count < g.get_num_nodes() and i.has_current(); i.next())
1171  {
1172  typename GT::Node * curr = i.get_current_node();
1173  if (IS_NODE_VISITED(curr, Build_Subtree))
1174  continue;
1175 
1176  // crear subgrafo componente inconexo conectado por curr_node
1177  list.append(GT()); // crea subgrafo y lo inserta en lista
1178  GT & subgraph = list.get_last(); // grafo insertado en list
1179 
1180  build_subgraph <GT, SA> (g, subgraph, curr, count);
1181  }
1182 }
1183 
1184 
1214  template <class GT, class SA> inline
1215 void build_subgraph(GT & g, GT & sg,
1216  typename GT::Node * g_src, size_t & node_count)
1217 {
1218  if (IS_NODE_VISITED(g_src, Build_Subtree))
1219  return;
1220 
1221  NODE_BITS(g_src).set_bit(Build_Subtree, true); // g_src visitado
1222  ++node_count;
1223 
1224  typename GT::Node * sg_src = mapped_node <GT> (g_src);
1225  if (sg_src == NULL) // ¿está mapeado g_src?
1226  { // No, cree imagen de g_src en el subgrafo sg y mapee
1227  sg_src = sg.insert_node(g_src->get_info());
1228  GT::map_nodes(g_src, sg_src);
1229  }
1230 
1231  for (Node_Arc_Iterator<GT, SA> i(g_src); // explore desde g_src
1232  node_count < g.get_num_nodes() and i.has_current(); i.next())
1233  {
1234  typename GT::Arc * arc = i.get_current_arc();
1235  if (IS_ARC_VISITED(arc, Build_Subtree))
1236  continue; // avance próximo arco
1237 
1238  ARC_BITS(arc).set_bit(Build_Subtree, true); // arc visitado
1239  typename GT::Node * g_tgt = i.get_tgt_node(); // destino de arc
1240  typename GT::Node * sg_tgt = mapped_node <GT> (g_tgt);
1241  if (sg_tgt == NULL) // ¿está mapeado en sg?
1242  { // no, hay que mapearlo e insertarlo en el subgrafo sg
1243  sg_tgt = sg.insert_node(g_tgt->get_info());
1244  GT::map_nodes(g_tgt, sg_tgt);
1245  }
1246 
1247  // tenemos nodos en subgrafo, insertamos arco y mapeamos
1248  typename GT::Arc * sg_arc =
1249  sg.insert_arc(sg_src, sg_tgt, arc->get_info());
1250  GT::map_arcs(arc, sg_arc);
1251 
1252  build_subgraph<GT,SA>(g, sg, g_tgt, node_count);
1253  }
1254 }
1255 
1256 
1257  template <class GT, class SA> inline static
1258 bool __find_depth_first_spanning_tree(GT & g,
1259  typename GT::Node * gnode,
1260  typename GT::Arc * garc,
1261  GT & tree,
1262  typename GT::Node * tnode);
1263 
1305  template <class GT, class SA = Dft_Show_Arc<GT>> inline
1306 void find_depth_first_spanning_tree(GT & g, typename GT::Node * gnode,
1307  GT & tree)
1308 {
1309  g.reset_nodes();
1310  g.reset_arcs();
1311 
1312  clear_graph(tree); // asegurar que árbol destino esté vacío
1313 
1314  NODE_BITS(gnode).set_bit(Spanning_Tree, true); // marcar gnode
1315 
1316  typename GT::Node * tnode = tree.insert_node(gnode->get_info());
1317  GT::map_nodes(gnode, tnode);
1318 
1319  for (Node_Arc_Iterator<GT, SA> i(gnode); i.has_current(); i.next())
1320  {
1321  typename GT::Arc * arc = i.get_current_arc();
1322  if (IS_ARC_VISITED(arc, Spanning_Tree))
1323  continue;
1324 
1325  typename GT::Node * arc_tgt_node = i.get_tgt_node();
1326  if (IS_NODE_VISITED(arc_tgt_node, Spanning_Tree))
1327  continue; // destino ya visitado desde otro arco
1328 
1329  if (__find_depth_first_spanning_tree<GT,SA>(g, arc_tgt_node,
1330  arc, tree, tnode))
1331  return; // ya el árbol está calculado
1332  }
1333 }
1334 
1370  template <class GT, class SA = Dft_Show_Arc<GT>> inline
1371 void find_depth_first_spanning_tree(GT & g, GT & tree)
1372 {
1373  typename GT::Node * start_node = g.get_first_node();
1374  find_depth_first_spanning_tree<GT,SA>(g, start_node, tree);
1375 }
1376 
1377 
1378  template <class GT, class SA> inline static
1379 bool __find_depth_first_spanning_tree(GT & g, typename GT::Node * gnode,
1380  typename GT::Arc * garc,
1381  GT & tree, typename GT::Node * tnode)
1382 {
1383  NODE_BITS(gnode).set_bit(Spanning_Tree, true); // marcar nodo
1384  ARC_BITS(garc).set_bit(Spanning_Tree, true); // marcar arco
1385 
1386  typename GT::Node * tree_tgt_node = tree.insert_node(gnode->get_info());
1387  GT::map_nodes(gnode, tree_tgt_node);
1388 
1389  typename GT::Arc * tarc =
1390  tree.insert_arc(tnode, tree_tgt_node, garc->get_info());
1391  GT::map_arcs(garc, tarc);
1392 
1393  tnode = tree_tgt_node;
1394  if (tree.get_num_nodes() == g.get_num_nodes()) // ¿grafo abarcado?
1395  return true; // tree ya contiene el árbol abarcador
1396 
1397  I(tree.get_num_nodes() > tree.get_num_arcs()); // debe ser acíclico
1398 
1399  for (Node_Arc_Iterator<GT, SA> i(gnode); i.has_current(); i.next())
1400  {
1401  typename GT::Arc * arc = i.get_current_arc();
1402  if (IS_ARC_VISITED(arc, Spanning_Tree))
1403  continue;
1404 
1405  typename GT::Node * arc_tgt_node = i.get_tgt_node();
1406  if (IS_NODE_VISITED(arc_tgt_node, Spanning_Tree))
1407  continue; // destino ya visitado desde otro arco
1408 
1409  if (__find_depth_first_spanning_tree<GT,SA>(g, arc_tgt_node,
1410  arc, tree, tnode))
1411  return false; // ya el árbol está calculado
1412  }
1413 
1414  return false;
1415 }
1416 
1456  template <class GT, class SA = Dft_Show_Arc<GT>> inline
1457 void find_breadth_first_spanning_tree(GT & g, typename GT::Node * gp, GT & tree)
1458 {
1459  g.reset_bit_nodes(Spanning_Tree);
1460  g.reset_bit_arcs(Spanning_Tree);
1461  clear_graph(tree);
1462  unique_ptr<typename GT::Node> tp_auto(new typename GT::Node(gp));
1463  tree.insert_node(tp_auto.get());
1464  GT::map_nodes(gp, tp_auto.release());
1465 
1466  DynListQueue<typename GT::Arc*> q; // insertar en cola arcos gp
1467  for (Node_Arc_Iterator<GT, SA> i(gp); i.has_current(); i.next())
1468  q.put(i.get_current_arc());
1469 
1470  NODE_BITS(gp).set_bit(Spanning_Tree, true);
1471 
1472  while (not q.is_empty())
1473  {
1474  typename GT::Arc * garc = q.get();
1475  ARC_BITS(garc).set_bit(Spanning_Tree, true);
1476  typename GT::Node * gsrc = g.get_src_node(garc);
1477  typename GT::Node * gtgt = g.get_tgt_node(garc);
1478 
1479  if (IS_NODE_VISITED(gsrc, Spanning_Tree) and
1480  IS_NODE_VISITED(gtgt, Spanning_Tree))
1481  continue; // los dos nodos de garc ya fueron visitados
1482 
1483  if (IS_NODE_VISITED(gtgt, Spanning_Tree)) // ¿gtgt visitado?
1484  std::swap(gsrc, gtgt); // sí, intercámbielo con gsrc
1485 
1486  typename GT::Node * tsrc = mapped_node<GT>(gsrc);
1487  NODE_BITS(gtgt).set_bit(Spanning_Tree, true); // gtgt visitado
1488 
1489  // crear copia de gtgt, insertarlo en tree y mapearlo
1490  unique_ptr<typename GT::Node> ttgt_auto(new typename GT::Node(gtgt));
1491  tree.insert_node(ttgt_auto.get());
1492  typename GT::Node * ttgt = ttgt_auto.release();
1493  GT::map_nodes(gtgt, ttgt);
1494 
1495  // insertar nuevo arco en tree y mapearlo
1496  typename GT::Arc * tarc = tree.insert_arc(tsrc, ttgt, garc->get_info());
1497  GT::map_arcs(garc, tarc);
1498  if (tree.get_num_nodes() == g.get_num_nodes()) // ¿abarca a g?
1499  break;
1500 
1501  // insertar en cola arcos de gtgt
1502  for (Node_Arc_Iterator<GT, SA> i(gtgt); i.has_current(); i.next())
1503  {
1504  typename GT::Arc * current_arc = i.get_current_arc();
1505  if (IS_ARC_VISITED(current_arc, Spanning_Tree))
1506  continue;
1507 
1508  // revise nodos de arcos para ver si han sido visitados
1509  if (IS_NODE_VISITED(g.get_src_node(current_arc),Spanning_Tree) and
1510  IS_NODE_VISITED(g.get_tgt_node(current_arc),Spanning_Tree))
1511  continue; // nodos ya visitados ==> no meter arco
1512  q.put(current_arc);
1513  }
1514  }
1515 }
1516 
1535  template <class GT>
1536 void build_spanning_tree(GT & g, GT & tree, DynArray<typename GT::Arc> * arcs,
1537  const bool with_map = false)
1538 {
1539  tree.clear();
1540  for (int i = 0; i < g.get_num_nodes(); ++i)
1541  {
1542  typename GT::Arc * garc = arcs[i];
1543  if (garc == NULL)
1544  continue;
1545 
1546  typename GT::Node * gsrc = g.get_src_node(garc);
1547  typename GT::Node * tsrc = NULL;
1548  if (IS_NODE_VISITED(gsrc, Spanning_Tree))
1549  tsrc = mapped_node <GT> (gsrc);
1550  else
1551  {
1552  NODE_BITS(gsrc).set_bit(Spanning_Tree, true);
1553  tsrc = tree.insert_node(gsrc->get_info());
1554  }
1555 
1556  typename GT::Node * gtgt = g.get_tgt_node(garc);
1557  typename GT::Node * ttgt = NULL;
1558  if (IS_NODE_VISITED(gtgt, Spanning_Tree))
1559  ttgt = mapped_node <GT> (gtgt);
1560  else
1561  {
1562  NODE_BITS(gtgt).set_bit(Spanning_Tree, true);
1563  ttgt = tree.insert_node(gtgt->get_info());
1564  }
1565 
1566  typename GT::Arc * tarc = tree.insert_arc(tsrc, ttgt, garc->get_info());
1567  ARC_BITS(garc).set_bit(Min, true);
1568  if (with_map)
1569  {
1570  GT::map_nodes(gsrc, tsrc);
1571  GT::map_nodes(gtgt, ttgt);
1572  GT::map_arcs(garc, tarc);
1573  }
1574  }
1575 }
1576 
1577  template <class GT> inline static
1578 long & df(typename GT::Node * p)
1579 {
1580  return NODE_COUNTER(p);
1581 }
1582 
1583  template <class GT> inline static
1584 long & low(typename GT::Node * p)
1585 {
1586  return reinterpret_cast<long&>(NODE_COOKIE(p));
1587 }
1588 
1589  template <class GT>
1590 struct Init_Low
1591 {
1592  void operator () (GT & g, typename GT::Node * node)
1593  {
1594  g.reset_counter(node); // inicializa df
1595  low <GT> (node) = -1; // inicializa low
1596  }
1597 };
1598 
1599  template <class GT, class SA> inline static
1600 void __compute_cut_nodes(GT & g, DynDlist<typename GT::Node *> & list,
1601  typename GT::Node * p, typename GT::Arc * a,
1602  long & curr_df);
1603 
1637  template <class GT, class SA = Dft_Show_Arc<GT>>
1638 void compute_cut_nodes(GT & g, typename GT::Node * start,
1640 {
1642  g.reset_arcs();
1643  long current_df = 0; // contador global de visitas
1644  NODE_BITS(start).set_bit(Depth_First, true); // marcar start
1645  df <GT> (start) = current_df++;
1646  int call_counter = 0; // contador llamadas recursivas
1647 
1648  // Recorra los arcos de start mientras g no haya sido abarcado
1649  for (Node_Arc_Iterator<GT, SA> i(start);
1650  i.has_current() and current_df < g.get_num_nodes(); i.next())
1651  {
1652  typename GT::Node * tgt = i.get_tgt_node();
1653  if (IS_NODE_VISITED(tgt, Depth_First))
1654  continue;
1655 
1656  typename GT::Arc * arc = i.get_current_arc();
1657  if (IS_ARC_VISITED(arc, Depth_First))
1658  continue;
1659 
1660  ARC_BITS(arc).set_bit(Depth_First, true);
1661  __compute_cut_nodes <GT, SA> (g, list, tgt, arc, current_df);
1662  ++call_counter;
1663  }
1664 
1665  if (call_counter > 1) // ¿es la raíz un punto de articulación?
1666  {
1667  NODE_BITS(start).set_bit(Cut, true);
1668  list.append(start);
1669  }
1670  }
1671 
1672  template <class GT, class SA> inline static
1673 void __compute_cut_nodes(GT & g, DynDlist<typename GT::Node *> & list,
1674  typename GT::Node * p, typename GT::Arc * a,
1675  long & curr_df)
1676 {
1677  NODE_BITS(p).set_bit(Depth_First, true); // pinte p visitado
1678  low <GT> (p) = df <GT> (p) = curr_df++; // asígnele df
1679 
1680  // recorrer arcos de p mientras no se abarque a g
1681  bool p_is_cut_node = false;
1682  for (Node_Arc_Iterator <GT, SA> i(p); i.has_current(); i.next())
1683  {
1684  typename GT::Arc * arc = i.get_current_arc();
1685  if (arc == a)
1686  continue; // a es el padre de arc ==> ignorarlo
1687 
1688  typename GT::Node * tgt = i.get_tgt_node();
1689  if (IS_NODE_VISITED(tgt, Depth_First))
1690  {
1691  if (not IS_ARC_VISITED(arc, Depth_First)) // no abarcador?
1692  if (df<GT>(tgt) < low<GT>(p)) // sí, verificar valor low
1693  low<GT>(p) = df<GT>(tgt); // actualizar low(p)
1694 
1695  continue;
1696  }
1697 
1698  if (IS_ARC_VISITED(arc, Depth_First))
1699  continue;
1700 
1701  ARC_BITS(arc).set_bit(Depth_First, true); // marque arco
1702 
1703  __compute_cut_nodes<GT, SA>(g, list, tgt, arc, curr_df);
1704 
1705  if (low<GT>(tgt) < low<GT>(p))
1706  low<GT>(p) = low<GT>(tgt); // actualizar low(p)
1707 
1708  if (low<GT>(tgt) >= df<GT>(p) and df<GT>(tgt) != 0) // ¿de corte?
1709  p_is_cut_node = true;
1710  }
1711 
1712  // aquí, p ya fue explorado recursivamente
1713  if (p_is_cut_node)
1714  {
1715  NODE_BITS(p).set_bit(Cut, true);
1716  list.append(p);
1717  }
1718 }
1719 
1720 const long Cross_Arc = -1;
1721 
1722  template <class GT> inline static
1723 bool is_a_cross_arc(typename GT::Arc * a)
1724 {
1725  return ARC_COUNTER(a) == Cross_Arc;
1726 }
1727 
1728  template <class GT> inline static
1729 bool is_a_cut_node(typename GT::Node * p)
1730 {
1731  return NODE_BITS(p).get_bit(Cut);
1732 }
1733 
1734  template <class GT> inline static
1735 bool is_an_cut_arc(typename GT::Arc * a)
1736 {
1737  return ARC_BITS(a).get_bit(Cut);
1738 }
1739  template <class GT> inline static
1740 bool is_node_painted(typename GT::Node * p)
1741 {
1742  return NODE_COUNTER(p) > 0;
1743 }
1744 
1745  template <class GT> inline static
1746 bool is_arc_painted(typename GT::Arc * arc)
1747 {
1748  return ARC_COUNTER(arc) > 0;
1749 }
1750 
1751  template <class GT> inline static
1752 void paint_node(typename GT::Node * p, const long & color)
1753 {
1754  NODE_COUNTER(p) = color;
1755 }
1756 
1757  template <class GT> inline static
1758 void paint_arc(typename GT::Arc * a, const long & color)
1759 {
1760  ARC_COUNTER(a) = color;
1761 }
1762 
1763  template <class GT> inline static
1764 const long & get_color(typename GT::Node * p)
1765 {
1766  return NODE_COUNTER(p);
1767 }
1768 
1769  template <class GT> inline static
1770 const long & get_color(typename GT::Arc * a)
1771 {
1772  return ARC_COUNTER(a);
1773 }
1774 
1775  template <class GT, class SA> inline static
1776 void __paint_subgraph(GT & g,
1777  typename GT::Node * p, // Nodo actual
1778  typename GT::Arc * a, // Arco que conduce a p
1779  const long & current_color);
1780 
1781  template <class GT, class SA> inline static
1782 void __paint_subgraph(GT & g, typename GT::Node * p, const long & current_color)
1783 {
1784  I(not is_a_cut_node <GT> (p));
1785 
1786  if (is_node_painted <GT> (p))
1787  return;
1788 
1789  paint_node <GT> (p, current_color);
1790 
1791  for (Node_Arc_Iterator<GT, SA> it(p); it.has_current(); it.next())
1792  {
1793  typename GT::Arc * arc = it.get_current_arc();
1794  if (is_arc_painted <GT> (arc))
1795  continue;
1796 
1797  typename GT::Node * tgt = it.get_tgt_node();
1798  if (is_a_cut_node <GT> (tgt))
1799  continue;
1800 
1801  paint_arc <GT> (arc, current_color);
1802 
1803  __paint_subgraph <GT, SA> (g, tgt, current_color);
1804  }
1805 }
1806 
1807  template <class GT, class SA> inline static
1808 void __paint_from_cut_node(GT & g, typename GT::Node * p, long & current_color)
1809 {
1810  I(is_a_cut_node <GT> (p));
1811 
1812  // pintar recursivamente con dif colores bloques conectados a p
1813  for (Node_Arc_Iterator<GT, SA> it(p); it.has_current(); it.next())
1814  {
1815  typename GT::Arc * arc = it.get_current_arc();
1816 
1817  I(not is_arc_painted <GT> (arc));
1818 
1819  typename GT::Node * tgt_node = it.get_tgt_node();
1820  if (is_a_cut_node <GT> (tgt_node)) // ¿ es un arco de corte?
1821  {
1822  ARC_BITS(arc).set_bit(Cut, true); // marque como de corte
1823  continue; // avance a próximo arco
1824  }
1825  else
1826  {
1827  paint_arc <GT> (arc, Cross_Arc); // marque como de cruce
1828  if (is_node_painted <GT> (tgt_node))
1829  continue;
1830  }
1831 
1832  // pintar recursivamente nodo conectado a arc
1833  __paint_subgraph <GT, SA> (g, tgt_node, current_color);
1834 
1835  current_color++; // cambiar color (sig arco en otro bloque)
1836 
1837  I(not is_arc_painted <GT> (arc));
1838  }
1839 }
1840 
1890  template <class GT, class SA = Dft_Show_Arc<GT>> inline long
1891 paint_subgraphs(GT & g, const DynDlist<typename GT::Node*> & cut_node_list)
1892 {
1893  g.reset_counter_nodes();
1894  g.reset_counter_arcs();
1895  long current_color = 1;
1896 
1897  // Recorrer cada nodo de corte y pintar sus bloques
1899  i(cut_node_list); i.has_current(); i.next())
1900  __paint_from_cut_node<GT,SA>(g, i.get_current(), current_color);
1901 
1902  return current_color;
1903 }
1904 
1905 
1906 
1907  template <class GT, class SA> inline static
1908 void __map_subgraph(GT & g, GT & sg, typename GT::Node * gsrc,
1909  const long & color)
1910 {
1911  I(get_color <GT> (gsrc) == color);
1912 
1913  typename GT::Node * tsrc = mapped_node<GT>(gsrc); // gsrc en sg
1914 
1915  // recorrer arcos de gsrc y añadir a sg los del color de interés
1916  for (Node_Arc_Iterator <GT, SA> i(gsrc); i.has_current(); i.next())
1917  {
1918  typename GT::Arc * garc = i.get_current_arc();
1919  if (get_color<GT>(garc) != color or IS_ARC_VISITED(garc, Build_Subtree))
1920  continue; // arco es de otro color o ya está visitado
1921 
1922  ARC_BITS(garc).set_bit(Build_Subtree, true);
1923 
1924  typename GT::Node * gtgt = i.get_tgt_node();
1925 
1926  I(get_color <GT> (gtgt) == color);
1927 
1928  typename GT::Node * ttgt = NULL; // imagen gtgt en sg
1929  if (IS_NODE_VISITED(gtgt, Build_Subtree)) // ¿gtgt en sg?
1930  ttgt = mapped_node<GT> (gtgt);
1931  else
1932  { // gtgt no está en sg ==> copiarlo y mapearlo
1933  unique_ptr<typename GT::Node> ttgt_auto(new typename GT::Node(gtgt));
1934  sg.insert_node(ttgt_auto.get());
1935  GT::map_nodes(gtgt, ttgt_auto.get());
1936  NODE_BITS(gtgt).set_bit(Build_Subtree, true);
1937  ttgt = ttgt_auto.release();
1938  }
1939 
1940  typename GT::Arc * tarc = sg.insert_arc(tsrc, ttgt, garc->get_info());
1941  GT::map_arcs(garc, tarc);
1942 
1943  __map_subgraph<GT, SA> (g, sg, gtgt, color);
1944  }
1945 }
1946 
1980  template <class GT, class SA = Dft_Show_Arc<GT>>
1981 void map_subgraph(GT & g, GT & sg, const long & color)
1982 {
1983  clear_graph(sg);
1984  typename GT::Node * first = NULL; // busque primer nodo con color
1985  for (typename GT::Node_Iterator it(g); it.has_current(); it.next())
1986  if (get_color <GT> (it.get_current_node()) == color)
1987  first = it.get_current_node();
1988 
1989  if (first == NULL) // Encontró el color?
1990  throw std::domain_error("Color does not exist in the graph");
1991 
1992  // cree first, insértelo en sg y mapéelo
1993  unique_ptr<typename GT::Node> auto_tsrc(new typename GT::Node(first));
1994  sg.insert_node(auto_tsrc.get());
1995  GT::map_nodes(first, auto_tsrc.release());
1996  NODE_BITS(first).set_bit(Build_Subtree, true);
1997 
1998  try
1999  {
2000  __map_subgraph <GT, SA> (g, sg, first, color); // mapee first
2001  }
2002  catch (...)
2003  {
2004  clear_graph(sg);
2005  }
2006 }
2007 
2008 
2049  template <class GT, class SA = Dft_Show_Arc<GT>>
2050 void map_cut_graph(GT & g, DynDlist<typename GT::Node*> & cut_node_list,
2051  GT & cut_graph,
2052  DynDlist<typename GT::Arc*> & cross_arc_list)
2053 {
2054  clear_graph(cut_graph);
2055 
2056  // recorra lista de nodos de corte e insértelos en cut_graph
2058  it(cut_node_list); it.has_curr(); it.next())
2059  {
2060  typename GT::Node * gp = it.get_current();
2061 
2062  I (is_a_cut_node <GT> (gp));
2063 
2064  unique_ptr<typename GT::Node> tp_auto(new typename GT::Node(gp));
2065  cut_graph.insert_node(tp_auto.get());
2066  GT::map_nodes(gp, tp_auto.release());
2067  }
2068 
2069  // recorra arcos de g ==> cut_graph = {arcos no corte} U
2070  // cross_arc_list = {arcos de cruce}
2071  for (Arc_Iterator <GT, SA> it(g); it.has_current(); it.next())
2072  {
2073  typename GT::Arc * garc = it.get_current_arc();
2074  if (is_a_cross_arc <GT> (garc))
2075  {
2076  cross_arc_list.append(garc);
2077  continue;
2078  }
2079 
2080  if (not is_an_cut_arc <GT> (garc))
2081  continue;
2082 
2083  typename GT::Node * src = mapped_node<GT>(g.get_src_node(garc));
2084  typename GT::Node * tgt = mapped_node<GT>(g.get_tgt_node(garc));
2085 
2086  I(src != NULL and tgt != NULL);
2087 
2088  typename GT::Arc * arc = cut_graph.insert_arc(src, tgt, garc->get_info());
2089  GT::map_arcs(garc, arc);
2090  }
2091 }
2092 
2093 
2101  template <class GT, class Distance>
2103 {
2104  Distance & dist;
2105 
2106  Distance_Compare(Distance && __dist = Distance())
2107  : dist(__dist)
2108  {
2109  // empty
2110  }
2111 
2112  Distance_Compare(Distance & __dist)
2113  : dist(__dist)
2114  {
2115  // empty
2116  }
2117 
2118  bool operator () (typename GT::Arc * a1, typename GT::Arc * a2)
2119  {
2120  return dist(a1) < dist(a2);
2121  }
2122 };
2123 
2145  template <class GT, class SA = Dft_Show_Arc<GT>>
2146 bool is_reachable(GT & g, typename GT::Node * src, typename GT::Node * tgt)
2147 {
2148  if (not g.is_digraph())
2149  throw std::domain_error("g is not a digraph");
2150 
2151  return test_for_path <GT, SA> (g, src, tgt);
2152 }
2153 
2169  template <class GT, class SA = Dft_Show_Arc<GT>>
2171  {
2172  public:
2173 
2182  bool operator () (GT & g, typename GT::Node * src,
2183  typename GT::Node * tgt) const
2184  {
2185  return is_reachable<GT, SA> (g, src, tgt);
2186  }
2187  };
2188 
2206  template <class GT, class SA = Dft_Show_Arc<GT>>
2207 void invert_digraph(GT & g, GT & gi, SA && sa = SA())
2208 {
2209  if (not g.is_digraph())
2210  throw std::domain_error("g is not a digraph");
2211 
2212  if (not gi.is_digraph())
2213  throw std::domain_error("gi is not a digraph");
2214 
2215  clear_graph(gi);
2216  g.reset_nodes();
2217 
2218  // recorrer todos los arcos del digrafo g
2219  for (Arc_Iterator<GT, SA> it(g, sa); it.has_current(); it.next())
2220  {
2221  typename GT::Arc * arc = it.get_current();
2222 
2223  // procesar nodo origen
2224  typename GT::Node * ssrc = g.get_src_node(arc);
2225  typename GT::Node * rsrc = mapped_node<GT> (ssrc);
2226  if (rsrc == NULL) // ¿ya está creado ssrc en gi?
2227  { // no == crearlo, insertarlo y mapearlo
2228  unique_ptr<typename GT::Node> rsrc_auto(new typename GT::Node(ssrc));
2229  gi.insert_node(rsrc_auto.get());
2230  GT::map_nodes(ssrc, rsrc_auto.get());
2231  rsrc = rsrc_auto.release();
2232  }
2233 
2234  // procesar nodo origen
2235  typename GT::Node * stgt = g.get_tgt_node(arc);
2236  typename GT::Node * rtgt = mapped_node<GT> (stgt);
2237  if (rtgt == NULL) // ¿ya está creado ssrc en gi?
2238  { // no == crearlo, insertarlo y mapearlo
2239  unique_ptr<typename GT::Node> rtgt_auto(new typename GT::Node(stgt));
2240  gi.insert_node(rtgt_auto.get());
2241  GT::map_nodes(stgt, rtgt_auto.get());
2242  rtgt = rtgt_auto.release();
2243  }
2244 
2245  typename GT::Arc * ai = gi.insert_arc(rtgt, rsrc, arc->get_info());
2246  GT::map_arcs(arc, ai);
2247  }
2248 
2249  I(g.get_num_arcs() == gi.get_num_arcs() and
2250  g.get_num_nodes() == gi.get_num_nodes());
2251 }
2252 
2253 
2258  template <class GT, class SA = Dft_Show_Arc<GT>>
2260 {
2261  SA & sa;
2262 
2263 public:
2264 
2265  Invert_Digraph(SA && __sa = SA()) : sa(__sa) { /* empty */ }
2266 
2267  Invert_Digraph(SA & __sa) : sa(__sa) { /* empty */ }
2268 
2269 
2277  void operator () (GT & g, GT & gi) const
2278  {
2279  invert_digraph <GT, SA> (g, gi, sa);
2280  }
2281 };
2282 
2290  template <class GT>
2292 {
2293 public:
2294 
2295  typedef typename GT::Arc_Type Distance_Type;
2296 
2297  static const Distance_Type Zero_Distance = 0;
2298 
2299  static const Distance_Type Max_Distance;
2300 
2301  Distance_Type & operator () (typename GT::Arc * a) const
2302  {
2303  return a->get_info();
2304  }
2305 };
2306 
2307 template <class GT>
2308 const typename Dft_Dist<GT>::Distance_Type Dft_Dist<GT>::Max_Distance =
2309  std::numeric_limits<typename Dft_Dist<GT>::Distance_Type>::max();
2310 
2311 
2312 template <class GT, class Distance = Dft_Dist<GT>>
2313 typename Distance::Distance_Type
2314 get_min_path(typename GT::Node * s, typename GT::Node * end,
2315  Path<GT> & path)
2316 {
2317  typename Distance::Distance_Type dist = 0;
2318  path.clear_path();
2319  path.insert(end);
2320 
2321  typename GT::Node * p = end;
2322  do
2323  {
2324  p = (typename GT::Node *) NODE_COOKIE(p);
2325  path.insert(p);
2326  dist = dist + Distance()(path.get_first_arc());
2327  }
2328  while (p != s);
2329 
2330  return dist;
2331 }
2332 
2340 template <class GT,
2341  class Distance = Dft_Dist<GT>,
2343  class SA = Dft_Show_Arc<GT>>
2345 {
2346  Distance & dist;
2347  Plus & plus;
2348  SA & sa;
2349 
2350 public:
2351 
2352  Total_Cost(Distance && __dist = Distance(),
2353  Plus && __plus = Plus(),
2354  SA && __sa = SA())
2355  : dist(__dist), plus(__plus), sa(__sa)
2356  {
2357  // empty
2358  }
2359 
2360  Total_Cost(Distance & __dist, Plus & __plus, SA & __sa)
2361  : dist(__dist), plus(__plus), sa(__sa)
2362  {
2363  // empty
2364  }
2365 
2366 public:
2367 
2369  typename Distance::Distance_Type total_cost(GT & g)
2370  {
2371  typename Distance::Distance_Type sum = Distance::Zero_Distance;
2372 
2373  // recorrer todos los arcos y sumar su peso
2374  for (Arc_Iterator <GT, SA> it(g, sa); it.has_curr(); it.next())
2375  sum = plus(sum, dist(it.get_current_arc()));
2376 
2377  return sum;
2378  }
2379 
2380 public:
2381 
2383  typename Distance::Distance_Type operator () (GT & g)
2384  {
2385  return total_cost (g);
2386  }
2387 };
2388 
2389 
2390 
2391 } // end namespace Aleph
2392 
2393 # endif // TPL_GRAPH_UTILS_H
size_t depth_first_traversal(GT &g, bool(*visit)(GT &, typename GT::Node *, typename GT::Arc *), SA sa=SA())
Definition: tpl_graph_utils.H:115
Definition: tpl_graph_utils.H:195
bool has_cycle(GT &g)
Definition: tpl_graph_utils.H:1025
Itor::difference_type count(const Itor &beg, const Itor &end, const T &value)
Definition: ahAlgo.H:127
#define ARC_COUNTER(p)
Definition: aleph-graph.H:254
#define NODE_COOKIE(p)
Definition: aleph-graph.H:248
bool operator()(GT &g, typename GT::Node *src, typename GT::Node *tgt) const
Definition: tpl_graph_utils.H:2182
Definition: tpl_dynDlist.H:26
Definition: tpl_graph.H:751
Definition: tpl_graph.H:1389
size_t operator()(GT &g, Operation &&op=Operation())
Definition: tpl_graph_utils.H:272
void insert(Arc *arc)
Definition: tpl_graph.H:1758
void map_cut_graph(GT &g, DynDlist< typename GT::Node * > &cut_node_list, GT &cut_graph, DynDlist< typename GT::Arc * > &cross_arc_list)
Definition: tpl_graph_utils.H:2050
#define IS_NODE_VISITED(p, bit)
Definition: aleph-graph.H:242
bool test_for_path(GT &g, typename GT::Node *start_node, typename GT::Node *end_node)
Definition: tpl_graph_utils.H:1065
Distance::Distance_Type operator()(GT &g)
Definition: tpl_graph_utils.H:2383
Breadth_First_Traversal(SA &&__sa=SA())
Definition: tpl_graph_utils.H:593
Definition: tpl_graph_utils.H:2102
Definition: tpl_dynListQueue.H:22
Depth_First_Traversal(SA &__sa)
Definition: tpl_graph_utils.H:260
#define NODE_COUNTER(p)
Definition: aleph-graph.H:226
bool is_reachable(GT &g, typename GT::Node *src, typename GT::Node *tgt)
Definition: tpl_graph_utils.H:2146
bool inside_graph(GT &gr) const
retorna true si el camino this refiere al grafo gr
Definition: tpl_graph.H:1562
void clear_graph(GT &g)
Definition: tpl_graph.H:2486
#define IS_ARC_VISITED(p, bit)
Definition: aleph-graph.H:275
void build_subgraph(GT &g, GT &sg, typename GT::Node *g_src, size_t &node_count)
Definition: tpl_graph_utils.H:1215
void build_spanning_tree(GT &g, GT &tree, DynArray< typename GT::Arc > *arcs, const bool with_map=false)
Definition: tpl_graph_utils.H:1536
Definition: tpl_graph.H:26
void find_depth_first_spanning_tree(GT &g, GT &tree)
Definition: tpl_graph_utils.H:1371
Definition: tpl_graph_utils.H:527
bool is_graph_acyclique(GT &g)
Definition: tpl_graph_utils.H:966
Definition: tpl_graph.H:634
void compute_cut_nodes(GT &g, typename GT::Node *start, DynDlist< typename GT::Node * > &list)
Definition: tpl_graph_utils.H:1638
void next()
Adelanta el iterador una posición.
Definition: filter_iterator.H:143
size_t breadth_first_traversal(GT &g, bool(*visit)(GT &, typename GT::Node *, typename GT::Arc *))
Definition: tpl_graph_utils.H:484
Depth_First_Traversal(SA &&__sa=SA())
Definition: tpl_graph_utils.H:252
Definition: tpl_graph_utils.H:2170
#define NODE_BITS(p)
Definition: aleph-graph.H:221
void inconnected_components(GT &g, DynDlist< GT > &list)
Definition: tpl_graph_utils.H:1164
Definition: tpl_graph_utils.H:128
void operator()(GT &g, GT &gi) const
Definition: tpl_graph_utils.H:2277
Definition: tpl_graph_utils.H:2291
Definition: tpl_graph_utils.H:2259
bool test_connectivity(GT &g)
Definition: tpl_graph_utils.H:784
T & get_last()
Retorna una referencia al último elemento de la lista.
Definition: tpl_dynDlist.H:202
void clear_path()
Limpia el camino (se eliminan todos sus nodos y arcos).
Definition: tpl_graph.H:1620
Definition: tpl_graph.H:814
#define ARC_BITS(p)
Definition: aleph-graph.H:266
Definition: tpl_dynArray.H:70
Arc * get_first_arc()
Retorna el primer arco del camino.
Definition: tpl_graph.H:1826
long paint_subgraphs(GT &g, const DynDlist< typename GT::Node * > &cut_node_list)
Definition: tpl_graph_utils.H:1891
bool find_path_breadth_first(GT &g, typename GT::Node *start, typename GT::Node *end, Path< GT > &path)
Definition: tpl_graph_utils.H:685
Definition: tpl_graph_utils.H:2344
Definition: ahFunction.H:54
size_t operator()(GT &g, Operation &&op=Operation())
Definition: tpl_graph_utils.H:605
T get()
Definition: tpl_dynListQueue.H:107
Distance::Distance_Type total_cost(GT &g)
Invoca al cálculo del coste total.
Definition: tpl_graph_utils.H:2369
Definition: tpl_graph.H:694
Definition: List.H:23
void find_breadth_first_spanning_tree(GT &g, typename GT::Node *gp, GT &tree)
Definition: tpl_graph_utils.H:1457
void invert_digraph(GT &g, GT &gi, SA &&sa=SA())
Definition: tpl_graph_utils.H:2207
void map_subgraph(GT &g, GT &sg, const long &color)
Definition: tpl_graph_utils.H:1981
bool test_for_cycle(GT &g, typename GT::Node *src_node)
Definition: tpl_graph_utils.H:817
Definition: tpl_graph_utils.H:1590
T & put(const T &data)
Definition: tpl_dynListQueue.H:86
T & append(const T &item)
Definition: tpl_dynDlist.H:106

Leandro Rabindranath León