Aleph-w  1.9
General library for algorithms and data structures
tpl_sgraph.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_SGRAPH_H
28 # define TPL_SGRAPH_H
29 
30 # include <memory>
31 # include <htlist.H>
32 # include <tpl_graph.H>
33 # include <tpl_dynSetTree.H>
34 
35 using namespace Aleph;
36 
37 namespace Aleph {
38 
39 
76  template <typename Node_Info = Empty_Class>
77 struct Graph_Snode : public GTNodeCommon<Node_Info>
78 {
80  friend class GTNodeCommon<Node_Info>;
81 
82  DynList<void*> arc_list; // lista de adyacencia
83 
97  Graph_Snode(const Node_Info & info)
98  noexcept(std::is_nothrow_copy_constructible<Node_Info>::value) : Base(info)
99  {
100  /* empty */
101  }
102 
103  Graph_Snode(Node_Info && info = Node_Info())
104  noexcept(std::is_nothrow_move_constructible<Node_Info>::value)
105  : Base(move(info))
106  {
107  /* empty */
108  }
109 
110  Graph_Snode(const Graph_Snode & node)
111  noexcept(std::is_nothrow_copy_constructible<Node_Info>::value)
112  : Graph_Snode(node.node_info)
113  {
114  /* empty */
115  }
116 
117  Graph_Snode & operator = (const Graph_Snode & node)
118  noexcept(std::is_nothrow_copy_assignable<Node_Info>::value)
119  {
120  if (&node == this)
121  return *this;
122  this->node_info = node.node_info;
123  return *this;
124  }
125 
142  noexcept(std::is_nothrow_copy_assignable<Node_Info>::value)
143  : Base(node->get_info())
144  {
145  /* empty */
146  }
147 };
148 
185  template <typename Arc_Info = Empty_Class>
186 class Graph_Sarc : public GTArcCommon<Arc_Info>
187 {
188  using Base = GTArcCommon<Arc_Info>;
189 
190 public:
191 
192  Graph_Sarc(const Arc_Info & info)
193  noexcept(std::is_nothrow_copy_constructible<Arc_Info>::value)
194  : Base(info)
195  {
196  /* empty */
197  }
198 
199  Graph_Sarc(Arc_Info && info = Arc_Info())
200  noexcept(std::is_nothrow_move_constructible<Arc_Info>::value)
201  : Base(move(info))
202  {
203  /* empty */
204  }
205 
206  Graph_Sarc(const Graph_Sarc & arc)
207  noexcept(std::is_nothrow_copy_constructible<Arc_Info>::value)
208  : Graph_Sarc(arc.arc_info)
209  {
210  /* empty */
211  }
212 
213  Graph_Sarc & operator = (const Graph_Sarc & arc)
214  noexcept(std::is_nothrow_copy_assignable<Arc_Info>::value)
215  {
216  if (&arc == this)
217  return *this;
218  this->arc_info = arc.arc_info;
219  return *this;
220  }
221 
222  Graph_Sarc(void * src, void * tgt, const Arc_Info & data)
223  noexcept(std::is_nothrow_copy_constructible<Arc_Info>::value)
224  : Base(src, tgt, data)
225  {
226  // empty
227  }
228 
229  Graph_Sarc(void * src, void * tgt, Arc_Info && data)
230  noexcept(std::is_nothrow_move_constructible<Arc_Info>::value)
231  : Base(src, tgt, move(data))
232  {
233  // empty
234  }
235 };
236 
237 
266  template <typename __Graph_Node = Graph_Snode<unsigned long>,
267  typename __Graph_Arc = Graph_Sarc<unsigned long>>
269  : public GraphCommon<List_SGraph<__Graph_Node, __Graph_Arc>,
270  __Graph_Node, __Graph_Arc>
271 {
272 public:
273 
274  using Node = __Graph_Node;
275  using Arc = __Graph_Arc;
276  using Node_Type = typename Node::Node_Type;
277  using Arc_Type = typename Arc::Arc_Type;
278 
279  friend class GraphCommon<List_SGraph<__Graph_Node, __Graph_Arc>,
280  __Graph_Node, __Graph_Arc>;
281 
283  __Graph_Node, __Graph_Arc>;
284 
285  // using FuncBase::search_arc; // TODO: delete after full dry
286  using CommonBase::insert_node;
287  using CommonBase::insert_arc;
288 
289 private:
290 
293 
294  DynSetNode node_list; // lista de nodos
295  DynSetArc arc_list; // lista de arcos
296 
297 public:
298 
299  List_SGraph() noexcept { /* empty */ }
300 
301  virtual ~List_SGraph()
302  {
303  clear();
304  }
305 
306  List_SGraph(const List_SGraph & g)
307  {
308  copy_graph(*this, g);
309  }
310 
311  void swap(List_SGraph & g) noexcept
312  {
313  this->common_swap(g);
314  node_list.swap(g.node_list);
315  arc_list.swap(g.arc_list);
316  }
317 
318  List_SGraph(List_SGraph && g) noexcept
319  {
320  swap(g);
321  }
322 
323  List_SGraph & operator = (const List_SGraph & g)
324  {
325  if (&g == this)
326  return *this;
327 
328  clear();
329 
330  copy_graph(*this, const_cast<List_SGraph&>(g));
331 
332  return *this;
333  }
334 
335  List_SGraph & operator = (List_SGraph && g) noexcept
336  {
337  swap(g);
338 
339  return *this;
340  }
341 
348  class Node_Iterator : public DynSetNode::Iterator
349  {
350  public:
351 
353  using Item_Type = Node *;
354 
356  using Set_Type = List_SGraph;
357 
358  Node_Iterator() noexcept { /* empty */ }
359 
360  Node_Iterator(const List_SGraph & g) noexcept
361  : DynSetNode::Iterator(g.node_list)
362  {
363  // empty
364  }
365 
367  Node * get_current_node() const
368  {
369  return this->get_curr();
370  }
371 
372  Node * get_current_node_ne() const noexcept
373  {
374  return this->get_curr_ne();
375  }
376  };
377 
385  class Node_Arc_Iterator : public DynList<void*>::Iterator
386  {
387  Node * src_node;
388 
389  public:
390 
392  using Item_Type = Arc *;
393 
395  using Set_Type = Node *;
396 
398  Node_Arc_Iterator() noexcept { /* empty */ }
399 
401  Node_Arc_Iterator(Node * src) noexcept
402  : DynList<void*>::Iterator(src->arc_list), src_node(src)
403  {
404  // empty
405  }
406 
408  Arc * get_curr_ne() const noexcept
409  {
410  return (Arc*) this->DynList<void*>::Iterator::get_curr_ne();
411  }
412 
414  Arc * get_curr() const
415  {
416  return (Arc*) this->DynList<void*>::Iterator::get_curr();
417  }
418 
419  Arc * get_current_arc_ne() const noexcept
420  {
421  return get_curr_ne();
422  }
423 
424  Arc * get_current_arc() const
425  {
426  return get_curr();
427  }
428 
430  Node * get_tgt_node_ne() const noexcept
431  {
432  Arc * a = get_curr_ne();
433  return (Node*) a->get_connected_node(src_node);
434  }
435 
437  Node * get_tgt_node() const
438  {
439  Arc * a = get_curr();
440  return (Node*) a->get_connected_node(src_node);
441  }
442  };
443 
451  class Arc_Iterator : public DynSetArc::Iterator
452  {
453  public:
454 
456  using Item_Type = Arc *;
457 
459  using Set_Type = List_SGraph;
460 
461  Arc_Iterator() noexcept { /* empty */ }
462 
463  Arc_Iterator(const List_SGraph & _g) noexcept
464  : DynSetArc::Iterator(_g.arc_list)
465  {
466  // empty
467  }
468 
470  Arc * get_current_arc_ne() const noexcept
471  {
472  return this->get_curr_ne();
473  }
474 
476  Node * get_src_node_ne() const noexcept
477  {
478  return (Node*) get_current_arc_ne()->src_node;
479  }
480 
482  Node * get_tgt_node_ne() const noexcept
483  {
484  return (Node*) get_current_arc_ne()->tgt_node;
485  }
486 
488  Arc * get_current_arc() const
489  {
490  return this->get_curr();
491  }
492 
494  Node * get_src_node() const { return (Node*) get_current_arc()->src_node; }
495 
497  Node * get_tgt_node() const { return (Node*) get_current_arc()->tgt_node; }
498  };
499 
500 
517  virtual Node * insert_node(Node * p)
518  {
519  assert(p->arc_list.is_empty());
520 
521  this->num_nodes++;
522  node_list.append(p);
523  return p;
524  }
525 
526 private:
527 
528  Arc * insert_arc(Node * src, Node * tgt, void * a)
529  {
530  Arc * arc = (Arc*) a;
531 
532  arc->src_node = src;
533  arc->tgt_node = tgt;
534 
535  src->arc_list.append(a);
536  src->num_arcs++;
537  if (not this->digraph and src != tgt)
538  {
539  tgt->arc_list.append(a);
540  tgt->num_arcs++;
541  }
542 
543  arc_list.append(arc);
544  this->num_arcs++;
545 
546  return arc;
547  }
548 
549  void disconnect_arc(Arc * arc)
550  {
551  Node * src = (Node*) arc->src_node;
552  Node * tgt = (Node*) arc->tgt_node;
553 
554  src->arc_list.remove_ne([arc] (auto a) { return a == arc; });
555  src->num_arcs--;
556 
557  if (not this->digraph and src != tgt)
558  {
559  tgt->arc_list.remove_ne([arc] (auto a) { return a == arc; });
560  tgt->num_arcs--;
561  }
562  }
563 
564 public:
565 
576  virtual void remove_arc(Arc * arc) noexcept
577  {
578  disconnect_arc(arc);
579  arc_list.remove(arc);
580  this->num_arcs--;
581  delete arc;
582  }
583 
584  virtual void remove_node(Node * p) noexcept
585  {
586  DynList<Arc*> arcs_to_remove;
587  arc_list.for_each([this, &arcs_to_remove, p] (auto arc)
588  {
589  if (this->get_src_node(arc) == p or this->get_tgt_node(arc) == p)
590  {
591  this->disconnect_arc(arc);
592  this->num_arcs--;
593  arcs_to_remove.append(arc);
594  }
595  });
596 
597  arcs_to_remove.for_each([this] (auto a)
598  {
599  arc_list.remove(a);
600  delete a;
601  });
602  node_list.remove(p);
603  this->num_nodes--;
604 
605  delete p;
606  }
607 
608  Node * get_first_node() const
609  {
610  return (Node*) node_list.get_first();
611  }
612 
613  Arc * get_first_arc() const
614  {
615  return (Arc*) arc_list.get_first();
616  }
617 
618  Arc * get_first_arc(Node * p) const
619  {
620  return (Arc*) p->arc_list.get_first();
621  }
622 
623 private:
624 
625  void clear() noexcept
626  {
627  arc_list.for_each( [] (Arc * p) { delete p; } );
628  node_list.for_each( [] (Node * p) { delete p; } );
629  }
630 
631  template <class Cmp>
632  struct Cmp_Arc
633  {
634  Cmp & cmp;
635 
636  Cmp_Arc(Cmp && __cmp = Cmp())
637  noexcept(std::is_nothrow_constructible<Cmp>::value and
638  std::is_nothrow_move_assignable<Cmp>::value)
639  : cmp(__cmp) { /* empty */ }
640 
641  Cmp_Arc(Cmp & __cmp)
642  noexcept(std::is_nothrow_constructible<Cmp>::value)
643  : cmp(__cmp) { /* empty */ }
644 
645  bool operator () (Slinknc * s1, Slinknc * s2) const noexcept
646  {
647  Arc * arc1 = (Arc*) s1;
648  Arc * arc2 = (Arc*) s2;
649  return cmp(arc1, arc2);
650  }
651  };
652 
653 public:
654 
655  template <class Compare>
656  void sort_arcs(Compare & cmp) noexcept
657  {
658  Cmp_Arc<Compare> comp(cmp);
659  mergesort<HTList, Cmp_Arc<Compare>>(arc_list, comp);
660  }
661 
662  template <class Compare>
663  void sort_arcs(Compare && cmp = Compare()) noexcept
664  {
665  mergesort<Cmp_Arc<Compare>>(arc_list, Cmp_Arc<Compare>(cmp));
666  }
667 };
668 
686  template <typename __Graph_Node = Graph_Snode<int>,
687  typename __Graph_Arc = Graph_Sarc<int>>
688 class List_SDigraph : public List_SGraph<__Graph_Node, __Graph_Arc>
689 {
691 
692 public:
693 
694  using Node = __Graph_Node;
695 
696  using Arc = __Graph_Arc;
697 
698  List_SDigraph() noexcept
699  {
700  this->digraph = true;
701  }
702 
703  List_SDigraph(const List_SDigraph & dg) : GT()
704  {
705  this->digraph = true;
706  copy_graph(*this, dg, false);
707  }
708 
709  List_SDigraph & operator = (const List_SDigraph<Node, Arc> & g)
710  {
711  if (this == &g)
712  return *this;
713 
714  this->digraph = true;
715  copy_graph(*this, g, false);
716 
717  return *this;
718  }
719 
720  List_SDigraph(List_SDigraph && dg) noexcept
721  : GT()
722  {
723  this->digraph = true;
724  this->swap(dg);
725  }
726 
727  List_SDigraph & operator = (List_SDigraph<Node, Arc> && g) noexcept
728  {
729  this->digraph = true;
730  this->swap(g);
731 
732  return *this;
733  }
734 };
735 
736 
737 } // end namespace Aleph
738 
739 # endif /* TPL_SGRAPH_H */
Node_Info & get_info() noexcept
Return a modifiable reference to the data contained in the node.
Definition: graph-dry.H:242
Node * get_src_node() const
Retorna el nodo origen del arco actual (sólo cuenta si es digrafo)
Definition: tpl_sgraph.H:494
Node * get_tgt_node() const
Retorna el nodo destino del arco actual (sólo cuenta si es digrafo)
Definition: tpl_sgraph.H:497
Definition: tpl_sgraph.H:77
Node * get_tgt_node() const
Retorna el nodo destino del arco actual.
Definition: tpl_sgraph.H:437
Graph_Snode(const Node_Info &info) noexcept(std::is_nothrow_copy_constructible< Node_Info >::value)
Definition: tpl_sgraph.H:97
Graph_Snode(Graph_Snode *node) noexcept(std::is_nothrow_copy_assignable< Node_Info >::value)
Definition: tpl_sgraph.H:141
Definition: tpl_sgraph.H:688
size_t remove(const Key &key)
Definition: tpl_dynSetTree.H:327
Node * get_tgt_node_ne() const noexcept
Retorna el nodo destino del arco actual.
Definition: tpl_sgraph.H:430
Node_Arc_Iterator() noexcept
Instancia un iterador vacío (inválido).
Definition: tpl_sgraph.H:398
T & get_curr_ne() const noexcept
Return the current link guaranteeing no exception. Be careful.
Definition: htlist.H:1639
virtual void remove_arc(Arc *arc) noexcept
Definition: tpl_sgraph.H:576
void for_each(Operation &operation) noexcept(noexcept(operation))
Definition: htlist.H:589
Node_Arc_Iterator(Node *src) noexcept
Instancia un iterador sobre el nodo _src_node.
Definition: tpl_sgraph.H:401
void copy_graph(GT &gtgt, const GT &gsrc, const bool cookie_map=false)
Definition: tpl_graph.H:3482
Definition: graph-dry.H:272
void swap(DynSetTree &dset)
Definition: tpl_dynSetTree.H:96
Definition: graph-dry.H:329
size_t num_arcs
data associated to the node. Access it with get_info()
Definition: graph-dry.H:227
Definition: htlist.H:59
Node * get_src_node_ne() const noexcept
Retorna el nodo origen del arco actual (sólo cuenta si es digrafo)
Definition: tpl_sgraph.H:476
Definition: ah-comb.H:35
Definition: graph-dry.H:206
const Key & get_first() const
Definition: tpl_dynSetTree.H:483
NodeInfo Node_Type
The node.
Definition: graph-dry.H:233
Node * get_current_node() const
retorna el nodo actual.
Definition: tpl_sgraph.H:367
Arc * get_curr_ne() const noexcept
Return get_current_arc() without exception.
Definition: tpl_sgraph.H:408
Node * Item_Type
Tipo de elemento que retorna get_curr()
Definition: tpl_sgraph.H:353
Arc * get_curr() const
Return get_current_arc()
Definition: tpl_sgraph.H:414
virtual Node * insert_node(Node *p)
Definition: tpl_sgraph.H:517
T & get_curr() const
Definition: htlist.H:1649
Node * get_tgt_node_ne() const noexcept
Retorna el nodo destino del arco actual (sólo cuenta si es digrafo)
Definition: tpl_sgraph.H:482
Definition: tpl_sgraph.H:348
Arc * Item_Type
Tipo de elemento que retorna get_curr()
Definition: tpl_sgraph.H:456
Definition: htlist.H:1622
Definition: ahDry.H:41
T & append(const T &item)
Definition: htlist.H:1471
Arc * get_current_arc() const
Retorna un puntero al arco actual.
Definition: tpl_sgraph.H:488
Arc * get_current_arc_ne() const noexcept
Retorna un puntero al arco actual.
Definition: tpl_sgraph.H:470
Definition: tpl_sgraph.H:268
Definition: tpl_sgraph.H:451
Definition: tpl_sgraph.H:385
Definition: tpl_sgraph.H:186

Leandro Rabindranath León