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_agraph.H
1 # ifndef TPL_AGRAPH_H
2 # define TPL_AGRAPH_H
3 
4 # include <tpl_dynSetTree.H>
5 # include <array_it.H>
6 # include <tpl_sgraph.H>
7 
8 namespace Aleph {
9 
10 using namespace Aleph;
11 
12  template <typename Node_Info = Empty_Class>
14 {
15  static const size_t Contract_Factor = 4;
16  static const size_t Default_Cap = 4;
17 
18  void init(size_t dim)
19  {
20  arcs_dim = dim;
21  num_arcs = 0;
22  contract_threshold = arcs_dim/Contract_Factor;
23  arc_array = NULL;
24  if (arcs_dim == 0)
25  return;
26 
27  arc_array = (void**) malloc(arcs_dim*sizeof(void*));
28  if (arc_array == NULL)
29  throw std::bad_alloc();
30  }
31 
32 public:
33 
34  GRAPH_NODE_COMMON(Graph_Anode);
35 
36  void ** arc_array;
37  size_t arcs_dim;
38  size_t contract_threshold;
39 
40  Graph_Anode()
41  {
42  init(0);
43  }
44 
45  Graph_Anode(const Graph_Anode&)
46  {
47  init(0);
48  }
49 
50  Graph_Anode(const Node_Info & info) : node_info(info)
51  {
52  init(Default_Cap);
53  }
54 
56  {
57  init(0);
58  }
59 
60  ~Graph_Anode()
61  {
62  if (arc_array != NULL)
63  free(arc_array);
64  }
65 
66  void allocate_more(size_t new_size)
67  {
68  if (new_size == 0)
69  new_size = 1;
70 
71  void ** new_array = (void**) realloc(arc_array, new_size*sizeof(void*));
72  if (new_array == NULL)
73  throw std::bad_alloc();
74 
75  arc_array = new_array;
76  arcs_dim = new_size;
77  contract_threshold = arcs_dim/Contract_Factor;
78  }
79 
80  void * insert_arc(void * arc)
81  {
82  if (num_arcs == arcs_dim)
83  allocate_more(arcs_dim << 1); // 2*arcs_dim
84 
85  arc_array[num_arcs++] = arc;
86 
87  return arc;
88  }
89 
90  void remove_arc(void * arc)
91  {
92  bool removed = false;
93  for (size_t i = 0; i < num_arcs; ++i)
94  if (arc_array[i] == arc)
95  {
96  arc_array[i] = arc_array[--num_arcs];
97  removed = true;
98  break;
99  }
100 
101  if (not removed)
102  throw std::domain_error("arc for deleting not found");
103 
104  if (num_arcs > contract_threshold)
105  return;
106 
107  // contraction
108  size_t new_sz = arcs_dim >> 1; // num_arcs/2
109  arc_array = (void**) realloc(arc_array, new_sz*sizeof(void*));
110  arcs_dim = new_sz;
111  contract_threshold = arcs_dim/Contract_Factor;
112  }
113 
114  bool compress()
115  {
116  void ** new_array = (void**) realloc(arc_array, num_arcs*sizeof(void*));
117  if (new_array == NULL)
118  return false;
119 
120  arc_array = new_array;
121  arcs_dim = num_arcs;
122  contract_threshold = num_arcs/Contract_Factor;
123 
124  return true;
125  }
126 };
127 
128 
129  template <typename Arc_Info = Empty_Class>
131 {
132 public:
133 
134  GRAPH_ARC_COMMON(Graph_Aarc);
135 
136  Graph_Aarc() : src_node(NULL), tgt_node(NULL)
137  {
138  /* empty */
139  }
140 
141  Graph_Aarc(const Arc_Info & info)
142  : arc_info(info), src_node(NULL), tgt_node(NULL)
143  {
144  /* empty */
145  }
146 
147  Graph_Aarc(void * src, void * tgt, const Arc_Info & data)
148  : arc_info(data), src_node(src), tgt_node(tgt)
149  {
150  // empty
151  }
152 
153  Graph_Aarc(void * src, void * tgt) : src_node(src), tgt_node(tgt)
154  {
155  // empty
156  }
157 };
158 
159 
160  template <class __Graph_Node = Graph_Anode<int>,
161  class __Graph_Arc = Graph_Aarc<int>>
163 {
164  GRAPH_ATTR_COMMON(Array_Graph);
165 
166 private:
167 
170 
171  DynSetNode node_set;
172  DynSetArc arc_set;
173 
174 public:
175 
176  class Node_Iterator : public DynSetNode::Iterator
177  {
178  public:
179 
181  typedef Node * Item_Type;
182 
185 
186  Node_Iterator() { /* empty */ }
187 
189  : DynSetNode::Iterator(g.node_set)
190  {
191  // empty
192  }
193 
195  Node * get_current_node() const
196  {
197  return this->get_curr();
198  }
199  };
200 
208  class Arc_Iterator : public DynSetArc::Iterator
209  {
210  public:
211 
213  typedef Arc * Item_Type;
214 
217 
218  Arc_Iterator() { /* empty */ }
219 
220  Arc_Iterator(Array_Graph & _g) : DynSetArc::Iterator(_g.arc_set)
221  {
222  // empty
223  }
224 
226  Arc * get_current_arc() const
227  {
228  return this->get_curr();
229  }
230 
232  Node * get_src_node() { return (Node*) get_current_arc()->src_node; }
233 
235  Node * get_tgt_node() { return (Node*) get_current_arc()->tgt_node; }
236  };
237 
238 
239  class Node_Arc_Iterator : public Array_Iterator<void*>
240  {
241  Node * src_node;
242 
243  public:
244 
246  typedef Arc * Item_Type;
247 
249  typedef Node * Set_Type;
250 
252  Node_Arc_Iterator() : src_node(NULL) { /* empty */ }
253 
255  Node_Arc_Iterator(Node * src)
256  : Array_Iterator<void*>(src->arc_array, src->num_arcs), src_node(src)
257  {
258  // empty
259  }
260 
262  Arc * get_current_arc() const
263  {
264  return (Arc*) const_cast<Node_Arc_Iterator*>(this)->
266  }
267 
269  Arc * get_current() const { return get_current_arc(); }
270 
272  Arc * get_curr() const { return get_current_arc(); }
273 
275  Node * get_tgt_node() const
276  {
277  Arc * a = get_curr();
278  return (Node*) a->get_connected_node(src_node);
279  }
280  };
281 
282  GRAPH_ITERATIVE_METHODS;
283 
284  GRAPH_SEARCH_METHODS;
285 
286  virtual Node * insert_node(Node * p)
287  {
288  I(p->num_arcs == 0);
289 
290  Node ** ret_val = node_set.append(p);
291 
292  ++num_nodes;
293 
294  I(num_nodes = node_set.size());
295  I(ret_val != NULL);
296 
297  return *ret_val;
298  }
299 
300  void compress()
301  {
302  node_set.for_each([/* Lambda */] (Node * p) { p->compress(); });
303  }
304 
305 private:
306 
307  Arc * try_insert_arc(Node * src, Node * tgt, void * a)
308  {
309  Arc * aptr = (Arc*) a;
310 
311  aptr->src_node = src;
312  aptr->tgt_node = tgt;
313  src->insert_arc(aptr);
314 
315  if (not digraph and src != tgt)
316  {
317  try
318  {
319  tgt->insert_arc(aptr);
320  }
321  catch (std::bad_alloc)
322  {
323  src->remove_arc(aptr);
324  throw;
325  }
326  }
327 
328  try
329  {
330  arc_set.append(aptr);
331  ++num_arcs;
332  I(num_arcs == arc_set.size());
333  }
334  catch (std::bad_alloc)
335  {
336  src->remove_arc(aptr);
337  if (not digraph and src != tgt)
338  tgt->remove_arc(aptr);
339  throw;
340  }
341 
342  return aptr;
343  }
344 
345 public:
346 
347  Arc * connect_arc(Arc * arc)
348  {
349  return try_insert_arc(get_src_node(arc), get_tgt_node(arc), arc);
350  }
351 
352 private:
353 
354  Arc * insert_arc(Node * src, Node * tgt, void * a)
355  {
356  bool compress_done = false;
357 
358  retry:
359  try
360  {
361  return try_insert_arc(src, tgt, a);
362  }
363  catch (bad_alloc)
364  {
365  if (compress_done)
366  throw;
367 
368  compress();
369  compress_done = true;
370  goto retry;
371  }
372  }
373 
374 public:
375 
376  Arc * disconnect_arc(Arc * arc)
377  {
378  Node * src = (Node*) arc->src_node;
379  Node * tgt = (Node*) arc->tgt_node;
380 
381  src->remove_arc(arc);
382  if (not digraph and src != tgt)
383  tgt->remove_arc(arc);
384 
385  arc_set.remove(arc);
386  --num_arcs;
387  I(num_arcs == arc_set.size());
388 
389  return arc;
390  }
391 
392  GRAPH_INSERTION_METHODS;
393 
394  virtual void remove_arc(Arc * a)
395  {
396  delete disconnect_arc(a);
397  }
398 
399  virtual void remove_node(Node * p)
400  {
401  DynArray<Arc*> arcs; // anota los arcos que hay que eliminar
402 
403  if (digraph)
404  for (size_t i = 0; i < num_arcs; ++i)
405  {
406  Arc * arc = arc_set(i);
407 
408  if (get_src_node(arc) == p or get_tgt_node(arc) == p)
409  arcs.append(arc);
410  }
411  else
412  for (size_t i = 0, n = p->num_arcs; i < n; ++i)
413  {
414  Arc * arc = (Arc*) p->arc_array[i];
415  arcs.append(arc);
416  }
417 
418  for (size_t i = 0; i < arcs.size(); ++i)
419  remove_arc(arcs(i));
420 
421  node_set.remove(p);
422  --num_nodes;
423 
424  I(num_nodes == node_set.size());
425 
426  delete p;
427  }
428 
429  Node * get_first_node() const
430  {
431  return const_cast<DynSetNode&>(node_set).get_first();
432  }
433 
434  Arc * get_first_arc() const
435  {
436  return const_cast<DynSetArc&>(arc_set).get_first();
437  }
438 
439  Arc * get_first_arc(Node * p) const
440  {
441  if (get_num_arcs(p) == 0)
442  throw std::range_error("Node has not arcs");
443  return (Arc*) p->arc_array[0];
444  }
445 
446  Array_Graph()
447  {
448  init();
449  }
450 
451 private:
452 
453  void clear()
454  {
455  arc_set.for_each( [/* Lambda */] (const Arc * p) { delete p; } );
456  node_set.for_each( [/* Lambda */] (const Node * p) { delete p; } );
457  }
458 
459 public:
460 
461  ~Array_Graph()
462  {
463  clear();
464  }
465 
466  Array_Graph(const Array_Graph & g)
467  {
468  init();
469  copy_graph(*this, const_cast<Array_Graph&>(g), false);
470  }
471 
472  void swap(Array_Graph & g)
473  {
474  common_swap(g);
475  node_set.swap(g.node_set);
476  arc_set.swap(g.arc_set);
477  }
478 
480  {
481  init();
482  swap(g);
483  }
484 
485  Array_Graph & operator = (const Array_Graph & g)
486  {
487  if (&g == this)
488  return *this;
489 
490  copy_graph(*this, const_cast<Array_Graph&>(g), false);
491 
492  return *this;
493  }
494 
495  Array_Graph & operator = (Array_Graph && g)
496  {
497  swap(g);
498  return *this;
499  }
500 
501 private:
502 
503  template <class Cmp>
504  struct Cmp_Arc
505  {
506  Cmp & cmp;
507 
508  Cmp_Arc(Cmp && __cmp = Cmp()) : cmp(__cmp) { /* empty */ }
509 
510  Cmp_Arc(Cmp & __cmp) : cmp(__cmp) { /* empty */ }
511 
512  bool operator () (Arc * a1, Arc * a2) const
513  {
514  return cmp(a1, a2);
515  }
516  };
517 
518 public:
519 
520  template <class Compare>
521  void sort_arcs(Compare &)
522  {
523  throw std::domain_error("sortarcs is not defined for Array_Graph");
524  }
525 
526  template <class Compare>
527  void sort_arcs(Compare &&)
528  {
529  throw std::domain_error("sortarcs is not defined for Array_Graph");
530  }
531 
532  GRAPH_FUNCTIONAL_METHODS(Array_Graph);
533 };
534 
552 template <typename __Graph_Node = Graph_Anode<int>,
553  typename __Graph_Arc = Graph_Aarc<int>>
554 class Array_Digraph : public Array_Graph<__Graph_Node, __Graph_Arc>
555 {
557 
558 public:
559 
560  typedef __Graph_Node Node;
561 
562  typedef __Graph_Arc Arc;
563 
564  Array_Digraph()
565  {
566  this->digraph = true;
567  }
568 
569  Array_Digraph(const Array_Digraph & dg)
571  {
572  this->digraph = true;
573  }
574 
575  Array_Digraph & operator = (const Array_Digraph<Node, Arc> & g)
576  {
577  if (this == &g)
578  return *this;
579 
580  copy_graph(*this, const_cast<Array_Digraph<Node, Arc>&>(g));
581 
582  return *this;
583  }
584 
585  Array_Digraph(Array_Digraph && dg) : GT()
586  {
587  this->digraph = true;
588  this->swap(dg);
589  }
590 
591  Array_Digraph & operator = (Array_Digraph<Node, Arc> && g)
592  {
593  this->swap(g);
594 
595  return *this;
596  }
597 };
598 
599 
600 GRAPH_METHODS_IMPLS(Array_Graph);
601 
602 
603 } // namespace Aleph {
604 
605 # endif // TPL_AGRAPH_H
Definition: tpl_agraph.H:239
Node * Set_Type
El tipo de conjunto sobre el cual se itera.
Definition: tpl_agraph.H:249
Definition: tpl_agraph.H:554
Array_Graph Set_Type
El tipo de conjunto sobre el cual se itera.
Definition: tpl_agraph.H:184
Array_Graph Set_Type
El tipo de conjunto sobre el cual se itera.
Definition: tpl_agraph.H:216
size_t remove(const Key &key)
Definition: tpl_dynSetTree.H:274
const size_t & size() const
Retorna la cardinalidad del conjunto.
Definition: tpl_dynSetTree.H:408
size_t size() const
Retorna dimensión actual (más lejano índice escrito)
Definition: tpl_dynArray.H:523
Arc * Item_Type
El tipo de dato que retorna get_current().
Definition: tpl_agraph.H:246
Node * get_tgt_node()
Retorna el nodo destino del arco actual (sólo cuenta si es digrafo)
Definition: tpl_agraph.H:235
Definition: array_it.H:11
Definition: tpl_agraph.H:162
void swap(DynSetTree &dset)
Definition: tpl_dynSetTree.H:65
Node_Arc_Iterator()
Instancia un iterador vacío (inválido).
Definition: tpl_agraph.H:252
Node_Arc_Iterator(Node *src)
Instancia un iterador sobre el nodo _src_node.
Definition: tpl_agraph.H:255
Definition: tpl_agraph.H:13
Arc * Item_Type
Tipo de elemento que retorna get_current()
Definition: tpl_agraph.H:213
Definition: tpl_agraph.H:130
Definition: tpl_agraph.H:208
Node * get_tgt_node() const
Retorna el nodo destino del arco actual.
Definition: tpl_agraph.H:275
T & append()
Definition: tpl_dynArray.H:1115
Arc * get_current() const
Definition: tpl_agraph.H:269
void copy_graph(GT &gtgt, GT &gsrc, const bool cookie_map=false)
Definition: tpl_graph.H:2505
Definition: tpl_dynArray.H:70
Node * get_src_node()
Retorna el nodo origen del arco actual (sólo cuenta si es digrafo)
Definition: tpl_agraph.H:232
Arc * get_current_arc() const
Retorna un puntero al arco actual.
Definition: tpl_agraph.H:226
Node * get_current_node() const
retorna el nodo actual.
Definition: tpl_agraph.H:195
Definition: tpl_agraph.H:176
Arc * get_current_arc() const
Retorna el arco actual.
Definition: tpl_agraph.H:262
Node * Item_Type
Tipo de elemento que retorna get_current()
Definition: tpl_agraph.H:181
Arc * get_curr() const
Definition: tpl_agraph.H:272

Leandro Rabindranath León