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_aleph_graph.H
1 # ifndef ALEPH_GRAPH_H
2 # define ALEPH_GRAPH_H
3 
4 # include <memory>
5 
6 namespace Aleph {
7 
8 static const long No_Visited = 0; // nodo o arco no ha sido visitado
9 
11 enum Graph_Bits
12 {
13  Depth_First,
14  Breadth_First,
15  Test_Cycle,
16  Is_Acyclique,
17  Test_Path,
18  Find_Path,
19  Kruskal,
20  Prim,
21  Dijkstra,
22  Euler,
23  Maximum_Flow,
24  Spanning_Tree,
25  Build_Subtree,
26  Convert_Tree,
27  Cut,
28  Min,
29 
30  Num_Bits_Graph
31 };
32 
47 class Bit_Fields
48 {
49 public:
50 
51  unsigned int depth_first : 1;
52  unsigned int breadth_first : 1;
53  unsigned int test_cycle : 1;
54  unsigned int is_acyclique : 1;
55  unsigned int test_path : 1;
56  unsigned int find_path : 1;
57  unsigned int kruskal : 1;
58  unsigned int prim : 1;
59  unsigned int dijkstra : 1;
60  unsigned int euler : 1;
61  unsigned int maximum_flow : 1;
62  unsigned int spanning_tree : 1;
63  unsigned int build_subtree : 1;
64  unsigned int convert_tree : 1;
65  unsigned int cut : 1;
66  unsigned int min : 1;
67 
70  : depth_first(0), breadth_first(0), test_cycle(0),
71  is_acyclique(0), test_path(0), find_path(0), kruskal(0),
72  prim(0), dijkstra(0), euler(0), maximum_flow(0),
74  cut(0), min(0) {}
75 
86  bool get_bit(const int & bit) const
87  throw(std::exception, std::out_of_range)
88  {
89  switch (bit)
90  {
91  case Aleph::Depth_First: return depth_first;
92  case Aleph::Breadth_First: return breadth_first;
93  case Aleph::Test_Cycle: return test_cycle;
94  case Aleph::Is_Acyclique: return is_acyclique;
95  case Aleph::Test_Path: return test_path;
96  case Aleph::Find_Path: return find_path;
97  case Aleph::Kruskal: return kruskal;
98  case Aleph::Prim: return prim;
99  case Aleph::Dijkstra: return dijkstra;
100  case Aleph::Euler: return euler;
101  case Aleph::Maximum_Flow: return maximum_flow;
102  case Aleph::Spanning_Tree: return spanning_tree;
103  case Aleph::Build_Subtree: return build_subtree;
104  case Aleph::Convert_Tree: return convert_tree;
105  case Aleph::Cut: return cut;
106  case Aleph::Min: return min;
107  default:
108  throw std::out_of_range("bit number out of range");
109  }
110  }
111 
124  void set_bit(const int & bit, const int & value)
125  {
126  I(value == 0 or value == 1);
127 
128  switch (bit)
129  {
130  case Aleph::Depth_First: depth_first = value; break;
131  case Aleph::Breadth_First: breadth_first = value; break;
132  case Aleph::Test_Cycle: test_cycle = value; break;
133  case Aleph::Is_Acyclique: is_acyclique = value; break;
134  case Aleph::Test_Path: test_path = value; break;
135  case Aleph::Find_Path: find_path = value; break;
136  case Aleph::Kruskal: kruskal = value; break;
137  case Aleph::Prim: prim = value; break;
138  case Aleph::Dijkstra: dijkstra = value; break;
139  case Aleph::Euler: euler = value; break;
140  case Aleph::Maximum_Flow: maximum_flow = value; break;
141  case Aleph::Spanning_Tree: spanning_tree = value; break;
142  case Aleph::Build_Subtree: build_subtree = value; break;
143  case Aleph::Convert_Tree: convert_tree = value; break;
144  case Aleph::Cut: cut = value; break;
145  case Aleph::Min: min = value; break;
146  default:
147  throw std::out_of_range("bit number out of range");
148  }
149  }
150 
152  void reset(const int & bit) { set_bit(bit, 0); }
153 
155  void reset()
156  {
157  depth_first = 0;
158  breadth_first = 0;
159  test_cycle = 0;
160  is_acyclique = 0;
161  test_path = 0;
162  find_path = 0;
163  kruskal = 0;
164  prim = 0;
165  dijkstra = 0;
166  euler = 0;
167  maximum_flow = 0;
168  spanning_tree = 0;
169  build_subtree = 0;
170  convert_tree = 0;
171  cut = 0;
172  min = 0;
173  }
174 };
175 
176 
177 struct Graph_Attr
178 {
179  Bit_Fields control_bits;
180  long counter;
181  void * cookie;
182 
183  Graph_Attr() : counter(No_Visited), cookie(NULL) { }
184 };
185 
186 template <typename __Node_Info>
188 {
189 public:
190  Graph_Attr attrs;
191 
192  typedef __Node_Info Node_Info;
193 
194  typedef Node_Info Item_Type;
195 
196  typedef Node_Info Node_Type;
197 
198  size_t num_arcs;
199 
200  Node_Info node_info;
201 
202  Node_Info & get_info() { return node_info; }
203 
204  const Node_Info & get_info() const { return node_info; }
205 
207  : num_arcs(0)
208  {
209  // Empty
210  }
211 
212  Aleph_Graph_Node(const Aleph_Graph_Node & node)
213  : num_arcs(0), node_info(node.info)
214  {
215  // Empty
216  }
217 
219  : num_arcs(0)
220  {
221  std::swap(node_info, node.info);
222  }
223 
224  Aleph_Graph_Node(const Node_Info & info)
225  : num_arcs(0), node_info(info)
226  {
227  // Empty
228  }
229 
230  Aleph_Graph_Node(Node_Info && info)
231  : num_arcs(0), node_info(std::move(info))
232  {
233  // Empty
234  }
235 
237  : num_arcs(0), node_info(node->info)
238  {
239  // Empty
240  }
241 };
242 
243 template <typename __Arc_Info>
245 {
246  typedef __Arc_Info Arc_Info;
247 
248  typedef Arc_Info Item_Type;
249 
250  typedef Arc_Info Arc_Type;
251 
252  Arc_Info arc_info;
253 
254  Graph_Attr attrs;
255 
256  void * src_node;
257 
258  void * tgt_node;
259 
260  Arc_Info & get_info() { return arc_info; }
261 
262  const Arc_Info & get_info() const { return arc_info; }
263 
264  void * get_connected_node(void * node)
265  {
266  return src_node == node ? tgt_node : src_node;
267  }
268 
269  Aleph_Graph_Arc()
270  {
271  // Empty
272  }
273 
274  Aleph_Graph_Arc(const Arc_Info & info)
275  : arc_info(info)
276  {
277  // Empty
278  }
279 
280  Aleph_Graph_Arc(Arc_Info && info)
281  : arc_info(std::move(info))
282  {
283  // Empty
284  }
285 
286  Aleph_Graph_Arc(void * src, void * tgt, const Arc_Info & info)
287  : src_node(src), tgt_node(tgt), arc_info(info)
288  {
289  // Empty
290  }
291 
292  Aleph_Graph_Arc(void * src, void * tgt, Arc_Info && info)
293  : src_node(src), tgt_node(tgt), arc_info(std::move(info))
294  {
295  // Empty
296  }
297 
298  Aleph_Graph_Arc(void * src, void * tgt)
299  : src_node(src), tgt_node(tgt)
300  {
301  // Empty
302  }
303 };
304 
309 # define NODE_BITS(p) ((p)->attrs.control_bits)
310 
314 # define NODE_COUNTER(p) ((p)->attrs.counter)
315 
320 # define NODE_COLOR(p) ((p)->attrs.counter)
321 
330 # define IS_NODE_VISITED(p, bit) (NODE_BITS(p).get_bit(bit))
331 
336 # define NODE_COOKIE(p) ((p)->attrs.cookie)
337 
342 # define ARC_COUNTER(p) ((p)->attrs.counter)
343 
348 # define ARC_COLOR(p) ((p)->attrs.counter)
349 
354 # define ARC_BITS(p) ((p)->attrs.control_bits)
355 
363 # define IS_ARC_VISITED(p, bit) (ARC_BITS(p).get_bit(bit))
364 
369 # define ARC_COOKIE(p) ((p)->attrs.cookie)
370 
371 
372 template <class __Graph_Node, class __Graph_Arc>
374 {
375 public:
376  typedef __Graph_Node Node;
377  typedef __Graph_Arc Arc;
378  typedef typename Node::Node_Type Node_Type;
379  typedef typename Arc::Arc_Type Arc_Type;
380 
381  Aleph_Graph(bool _digraph)
382  : digraph(_digraph)
383  {
384  // Empty
385  }
386 
387 protected:
388 
389  void * cookie;
390 
391  struct Reset_Node
392  {
393  void operator () (Aleph_Graph&, Node * node) const
394  {
395  NODE_BITS(node).reset();
396  NODE_COUNTER(node) = 0;
397  NODE_COOKIE(node) = NULL;
398  }
399  };
400 
401  struct Reset_Arc
402  {
403  void operator () (Aleph_Graph&, Arc * arc) const
404  {
405  ARC_BITS(arc).reset();
406  ARC_COUNTER(arc) = 0;
407  ARC_COOKIE(arc) = NULL;
408  }
409  };
410 
411  size_t num_nodes;
412  size_t num_arcs;
413  bool digraph;
414 
415  void init()
416  {
417  num_nodes = num_arcs = 0;
418  cookie = NULL;
419  digraph = false;
420  }
421 
422  void common_swap(Aleph_Graph & g)
423  {
424  if (digraph != g.digraph)
425  throw std::domain_error("source and target incompatible");
426  std::swap(num_nodes, g.num_nodes);
427  std::swap(num_arcs, g.num_arcs);
428  std::swap(digraph, g.digraph);
429  std::swap(cookie, g.cookie);
430  }
431 
432 public:
433 
434  void *& get_cookie() { return cookie; }
435 
436  bool is_digraph() const { return digraph; }
437 
438  const size_t & get_num_nodes() const { return num_nodes; }
439 
440  const size_t & vsize() const { return get_num_nodes(); }
441 
442  Node * get_src_node(Arc * arc) { return (Node*) arc->src_node; }
443 
444  Node * get_tgt_node(Arc * arc) { return (Node*) arc->tgt_node; }
445 
446  Node * get_connected_node(Arc * arc, Node * node)
447  {
448  return (Node*) arc->get_connected_node(node);
449  }
450 
451  const size_t & get_num_arcs() const { return num_arcs; }
452 
453  const size_t & esize() const { return get_num_arcs(); }
454 
455  const size_t & get_num_arcs(Node * node) const
456  {
457  return node->num_arcs;
458  }
459 
460  Bit_Fields & get_control_bits(Node * node)
461  {
462  return NODE_BITS(node).reset();
463  }
464 
465  void reset_bit(Node * node, const int & bit)
466  {
467  NODE_BITS(node).reset(bit);
468  }
469 
470  void reset_bits(Node * node) { NODE_BITS(node).reset(); }
471 
472  void set_bit(Node * node, const int bit, const int value)
473  {
474  NODE_BITS(node).set_bit(bit, value);
475  }
476 
477  Bit_Fields & get_control_bits(Arc * arc) { return ARC_BITS(arc); }
478 
479  void reset_bit(Arc * arc, const int bit)
480  {
481  ARC_BITS(arc).reset(bit);
482  }
483 
484  void reset_bits(Arc * arc) { ARC_BITS(arc).reset(); }
485 
486  void set_bit(Arc * arc, const int bit, const int value)
487  {
488  ARC_BITS(arc).set_bit(bit, value);
489  }
490 
491  void *& get_cookie(Node * node) { return NODE_COOKIE(node); }
492 
493  void *& get_cookie(Arc * arc) { return ARC_COOKIE(arc); }
494 
495  long & get_counter(Node * node) { return NODE_COUNTER(node); }
496 
497  void reset_counter(Node * node) { NODE_COUNTER(node) = No_Visited; }
498 
499  void reset_node(Node * node)
500  {
501  node_bits(node).reset();
502  NODE_COUNTER(node) = 0;
503  NODE_COOKIE(node) = NULL;
504  }
505 
506  long & get_counter(Arc * arc) { return ARC_COUNTER(arc); }
507 
508  void reset_counter(Arc * arc) { ARC_COUNTER(arc) = No_Visited; }
509 
510  void reset_arc(Arc * arc)
511  {
512  ARC_BITS(arc).reset();
513  ARC_COUNTER(arc) = 0;
514  ARC_COOKIE(arc) = NULL;
515  }
516 
517  template <class N1, class N2> static
518  void map_nodes(N1 * p, N2 * q)
519  {
520  I(p != NULL and q != NULL);
521 
522  if (NODE_COOKIE(p) == NULL)
523  {
524  NODE_COOKIE(p) = q;
525  NODE_COOKIE(q) = p;
526  return;
527  }
528 
529  NODE_COOKIE(q) = NODE_COOKIE(p);
530  NODE_COOKIE(p) = q;
531  }
532 
533  template <class A1, class A2> static
534  void map_arcs(A1 * p, A2 * q)
535  {
536  I(p != NULL and q != NULL);
537 
538  if (ARC_COOKIE(p) == NULL)
539  {
540  ARC_COOKIE(p) = q;
541  ARC_COOKIE(q) = p;
542  return;
543  }
544 
545  ARC_COOKIE(q) = ARC_COOKIE(p);
546  ARC_COOKIE(p) = q;
547  }
548 
549  inline virtual Node * insert_node(Node * node) = 0;
550 
551  inline virtual Node * insert_node(const Node_Type & node_info) = 0;
552 
553  inline virtual Node * insert_node(Node_Type && node_info = Node_Type()) = 0;
554 
555  inline virtual void remove_node(Node * node) = 0;
556 
557  inline virtual Node * get_first_node() = 0;
558 
559  inline virtual Arc * get_first_arc() = 0;
560 
561  inline virtual Arc * get_first_arc(Node *) = 0;
562 
563  inline virtual Arc * insert_arc(Node * src_node, Node * tgt_node,
564  const typename Arc::Arc_Type & arc_info) = 0;
565 
566  inline virtual Arc *
567  insert_arc(Node * src_node, Node * tgt_node,
568  typename Arc::Arc_Type && arc_info) = 0;
569 
570  inline virtual Arc * insert_arc(Node * src_node, Node * tgt_node) = 0;
571 
572  inline virtual void remove_arc(Arc * arc) = 0;
573 
574  inline virtual void disconnect_arc(Arc * arc) = 0;
575 
576  inline virtual Arc * connect_arc(Arc * arc) = 0;
577 
578  virtual ~Aleph_Graph();
579 
580 };
581 
582 # define GRAPH_ITERATIVE_METHODS \
583  void reset_bit_nodes(const int & bit) \
584  { \
585  for (Node_Iterator itor(*this); itor.has_curr(); itor.next()) \
586  reset_bit(itor.get_current_node(), bit); \
587  } \
588  \
589  void reset_bit_arcs(const int & bit) \
590  { \
591  for (Arc_Iterator itor(*this); itor.has_curr(); itor.next()) \
592  reset_bit(itor.get_current_arc(), bit); \
593  } \
594  void reset_bit_nodes() \
595  { \
596  for (Node_Iterator itor(*this); itor.has_curr(); itor.next()) \
597  reset_bits(itor.get_current_node()); \
598  } \
599  \
600  void reset_bit_arcs() \
601  { \
602  for (Arc_Iterator itor(*this); itor.has_curr(); itor.next()) \
603  reset_bits(itor.get_current_arc()); \
604  } \
605  \
606  Node * get_node(size_t k) \
607  { \
608  int m = Base_Graph::num_nodes/2; \
609  Node_Iterator it(*this); \
610  \
611  if (k < m) \
612  for (int i = 0; i < k; ++i) \
613  it.next(); \
614  else \
615  { \
616  it.reset_last(); \
617  for (int i = Base_Graph::num_nodes - 1; i > k; --i) \
618  it.prev(); \
619  } \
620  \
621  return it.get_curr(); \
622  } \
623  \
624  Node * get_arc(size_t k) \
625  { \
626  int m = Base_Graph::num_arcs/2; \
627  Arc_Iterator it(*this); \
628  \
629  if (k < m) \
630  for (int i = 0; i < k; ++i) \
631  it.next(); \
632  else \
633  { \
634  it.reset_last(); \
635  for (int i = Base_Graph::num_arcs - 1; i > k; --i) \
636  it.prev(); \
637  } \
638  \
639  return it.get_curr(); \
640  } \
641  \
642  void reset_counter_nodes() \
643  { \
644  for (Node_Iterator itor(*this); itor.has_curr(); itor.next()) \
645  reset_counter(itor.get_current_node()); \
646  } \
647  \
648  void reset_counter_arcs() \
649  { \
650  for (Arc_Iterator itor(*this); itor.has_curr(); itor.next()) \
651  reset_counter(itor.get_current_arc()); \
652  } \
653  \
654  void reset_cookie_nodes() \
655  { \
656  for (Node_Iterator itor(*this); itor.has_curr(); itor.next()) \
657  itor.get_current_node()->cookie = NULL; \
658  } \
659  \
660  void reset_cookie_arcs() \
661  { \
662  for (Arc_Iterator itor(*this); itor.has_curr(); itor.next()) \
663  itor.get_current_arc()->cookie = NULL; \
664  } \
665  inline void reset_nodes(); \
666  \
667  inline void reset_arcs(); \
668  \
669  typedef Node_Arc_Iterator Out_Iterator;
670 
671 
672 
673 # define GRAPH_SEARCH_METHODS \
674  template <class Equal> \
675  Node * search_node(const typename Node::Node_Type & node_info) \
676  { \
677  for (Node_Iterator itor(*this); itor.has_curr(); itor.next()) \
678  { \
679  Node * curr_node = itor.get_current_node(); \
680  if (Equal() (curr_node->get_info(), node_info)) \
681  return curr_node; \
682  } \
683  \
684  return NULL; \
685  } \
686  \
687  template <typename T, class Equal> \
688  Node * search_node(const T & data) \
689  { \
690  for (Node_Iterator it(*this); it.has_curr(); it.next()) \
691  { \
692  Node * p = it.get_current_node(); \
693  if (Equal () (p->get_info(), data)) \
694  return p; \
695  } \
696  \
697  return NULL; \
698  } \
699  \
700  Node * search_node(const typename Node::Node_Type & node_info) \
701  { \
702  return search_node<Aleph::equal_to<typename Node::Node_Type>>(node_info); \
703  } \
704  \
705  template <class Equal> \
706  Node * search_node(void * ptr) \
707  { \
708  for (Node_Iterator itor(*this); itor.has_curr(); itor.next()) \
709  { \
710  Node * curr_node = itor.get_current_node(); \
711  if (Equal () (curr_node, ptr)) \
712  return curr_node; \
713  } \
714  \
715  return NULL; \
716  } \
717  \
718  template <typename T, class Equal> \
719  Arc * search_Arc(const T & data) \
720  { \
721  for (Arc_Iterator it(*this); it.has_curr(); it.next()) \
722  { \
723  Arc * a = it.get_current_arc(); \
724  if (Equal () (a->get_info(), data)) \
725  return a; \
726  } \
727  \
728  return NULL; \
729  } \
730  \
731  template <class Equal> \
732  Arc * search_arc(const typename Arc::Arc_Type & arc_info) \
733  { \
734  for (Arc_Iterator it(*this); it.has_curr(); it.next()) \
735  { \
736  Arc * curr_arc = it.get_current_arc(); \
737  if (Equal () (curr_arc->get_info(), arc_info)) \
738  return curr_arc; \
739  } \
740  \
741  return NULL; \
742  } \
743  \
744  Arc * search_arc(const typename Arc::Arc_Type & arc_info) \
745  { \
746  return search_arc<Aleph::equal_to<Arc_Type> >(arc_info); \
747  } \
748  \
749  template <class Equal> \
750  Arc * search_arc(void * ptr) \
751  { \
752  for (Arc_Iterator itor(*this); itor.has_curr(); itor.next()) \
753  { \
754  Arc * curr_arc = itor.get_current_node(); \
755  if (Equal () (curr_arc, ptr)) \
756  return curr_arc; \
757  } \
758  \
759  return NULL; \
760  }
761 
762 
763 # define GRAPH_INSERTION_METHODS \
764  virtual Node * insert_node(const Node_Type & node_info) \
765  { \
766  return insert_node(new Node (node_info)); \
767  } \
768  \
769  virtual Node * insert_node(Node_Type && node_info = Node_Type()) \
770  { \
771  return insert_node(new Node(std::move(node_info))); \
772  } \
773  \
774  virtual Arc * \
775  insert_arc(Node * src, Node * tgt, const Arc_Type & arc_info)\
776  { \
777  return insert_arc(src, tgt, new Arc(arc_info) ); \
778  } \
779  \
780  virtual Arc * \
781  insert_arc(Node * src, Node * tgt, Arc_Type && arc_info = Arc_Type()) \
782  { \
783  return insert_arc(src, tgt, new Arc(std::move(arc_info))); \
784  }
785 
786 
787 #define GRAPH_METHODS_IMPLS(Name) \
788  template <typename Node, typename Arc> \
789 void Name<Node, Arc>::reset_nodes() \
790 { \
791  Operate_On_Nodes <Name, Aleph_Graph<Node, Arc>::Reset_Node> () (*this); \
792 } \
793  \
794  template <typename Node, typename Arc> \
795 void Name<Node, Arc>::reset_arcs() \
796 { \
797  Operate_On_Arcs <Name, Aleph_Graph<Node, Arc>::Reset_Arc> () (*this); \
798 }
799 
800 
881 } // end namespace Aleph
882 
883 # endif
#define ARC_COUNTER(p)
Definition: tpl_aleph_graph.H:342
Definition: tpl_aleph_graph.H:391
#define NODE_COOKIE(p)
Definition: tpl_aleph_graph.H:336
Bit_Fields()
pertenece a un camino mínimo
Definition: tpl_aleph_graph.H:69
unsigned int is_acyclique
Bit de verificación de ciclo.
Definition: aleph-graph.H:54
unsigned int min
nodo o arco de corte
Definition: aleph-graph.H:66
bool get_bit(const int &bit) const
Definition: tpl_aleph_graph.H:86
unsigned int breadth_first
Bit de búsqueda en profundidad.
Definition: aleph-graph.H:52
Definition: aleph-graph.H:177
unsigned int convert_tree
Bit de subgrafo.
Definition: aleph-graph.H:64
unsigned int cut
Conversión a Tree_Node.
Definition: aleph-graph.H:65
unsigned int kruskal
Bit de búsqueda de camino.
Definition: aleph-graph.H:57
unsigned int test_path
Bit de prueba de aciclicidad.
Definition: aleph-graph.H:55
Definition: tpl_aleph_graph.H:401
#define ARC_COOKIE(p)
Definition: tpl_aleph_graph.H:369
#define NODE_COUNTER(p)
Definition: tpl_aleph_graph.H:314
unsigned int test_cycle
Bit de búsqueda en amplitud.
Definition: aleph-graph.H:53
unsigned int find_path
Bit de prueba de existencia de camino.
Definition: aleph-graph.H:56
void set_bit(const int &bit, const int &value)
Definition: tpl_aleph_graph.H:124
unsigned int prim
Bit de algoritmo de Kruskal.
Definition: aleph-graph.H:58
unsigned int build_subtree
Bit de árbol abarcador.
Definition: aleph-graph.H:63
Definition: tpl_aleph_graph.H:373
unsigned int spanning_tree
Bit para flujos máximos.
Definition: aleph-graph.H:62
#define NODE_BITS(p)
Definition: tpl_aleph_graph.H:309
void reset()
Reinicia todos los bits a cero.
Definition: tpl_aleph_graph.H:155
long counter
bits de control del arco
Definition: aleph-graph.H:180
Definition: tpl_aleph_graph.H:244
#define ARC_BITS(p)
Definition: tpl_aleph_graph.H:354
unsigned int maximum_flow
Bit de camino euleriano.
Definition: aleph-graph.H:61
unsigned int euler
Bit de algoritmo de Dijkstra.
Definition: aleph-graph.H:60
Definition: tpl_aleph_graph.H:187
void reset(const int &bit)
Reinicia bit a cero.
Definition: tpl_aleph_graph.H:152
unsigned int dijkstra
Bit de algoritmo de Prim.
Definition: aleph-graph.H:59

Leandro Rabindranath León