DeSiGNAR  0.5a
Data Structures General Library
graphutilities.H
Go to the documentation of this file.
1 /*
2  This file is part of Designar.
3  Copyright (C) 2017 by Alejandro J. Mujica
4 
5  This program is free software: you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation, either version 3 of the License, or
8  (at your option) any later version.
9 
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with this program. If not, see <http://www.gnu.org/licenses/>.
17 
18  Any user request of this software, write to
19 
20  Alejandro Mujica
21 
22  aledrums@gmail.com
23 */
24 
25 # ifndef GRAPHUTILITIES_H
26 # define GRAPHUTILITIES_H
27 
28 # include <types.H>
29 # include <array.H>
30 # include <list.H>
31 # include <queue.H>
32 # include <map.H>
33 # include <heap.H>
34 
35 namespace Designar
36 {
37  enum class GraphTag : nat_t
38  {
39  DEPTH_FIRST = 1,
40  BREADTH_FIRST = 2,
41  KRUSKAL = 4,
42  PRIM = 8,
43  DIJKSTRA = 16,
44  ASTAR = 32,
45  SPANNING_TREE = 64,
46  MIN_SPANNING_TREE = 128,
47  COMPONENT = 256,
48  CUT = 512,
49  PATH = 1024,
50  MIN_PATH = 2048,
51  MIN_PATH_TREE = 4096
52  };
53 
55  {
56  nat_t tag;
57  lint_t _counter;
58  void * _cookie;
59 
60  public:
61  CommonNodeArc();
62 
63  void visit(GraphTag);
64 
65  void unvisit(GraphTag);
66 
67  bool is_visited(GraphTag) const;
68 
69  void *& cookie();
70 
71  void reset_tag();
72 
73  lint_t & counter();
74 
75  void reset();
76  };
77 
78  template <class GT> using Node = typename GT::Node;
79  template <class GT> using Arc = typename GT::Arc;
80  template <class GT> using NodeIt = typename GT::NodeIterator;
81  template <class GT> using ArcIt = typename GT::ArcIterator;
82  template <class GT> using AdArcIt = typename GT::AdjacentArcIterator;
83 
85  {
86  if (x->cookie() == nullptr)
87  {
88  x->cookie() = y;
89  y->cookie() = x;
90  }
91  else
92  {
93  y->cookie() = x->cookie();
94  x->cookie() = y;
95  }
96  }
97 
98  template <class SG, class TG = SG>
99  void map_nodes(Node<SG> * p, Node<TG> * q)
100  {
101  map_graph_item(p, q);
102  }
103 
104  template <class SG, class TG = SG>
105  void map_arcs(Arc<SG> * a, Arc<TG> * b)
106  {
107  map_graph_item(a, b);
108  }
109 
110  template <class SG, class TG = SG>
111  typename TG::Node * mapped_node(Node<SG> * p)
112  {
113  return reinterpret_cast<Node<TG> *>(p->cookie());
114  }
115 
116  template <class SG, class TG = SG>
117  typename TG::Arc * mapped_arc(Arc<SG> * a)
118  {
119  return reinterpret_cast<Arc<TG> *>(a->cookie());
120  }
121 
122  template <class GT>
123  class Path
124  {
125  public:
127  using ArcType = Arc<GT>;
128 
129  private:
130  struct PathDesc
131  {
132  NodeType * node;
133  ArcType * arc;
134 
135  PathDesc(NodeType * _node = nullptr, ArcType * _arc = nullptr)
136  : node(_node), arc(_arc)
137  {
138  // Empty
139  }
140  };
141 
142  using ListType = DLList<PathDesc>;
143 
144  GT * ptr_owner_graph;
145  ListType list;
146 
147  void test_for_graph() const
148  {
149  if (ptr_owner_graph == nullptr)
150  throw std::logic_error("Graph has not been specified");
151  }
152 
153  public:
155  : ptr_owner_graph(nullptr), list()
156  {
157  // Empty
158  }
159 
160  Path(const GT & graph)
161  : ptr_owner_graph(const_cast<GT *>(&graph)), list()
162  {
163  // Empty
164  }
165 
166  Path(GT * graph_ptr)
167  : ptr_owner_graph(graph_ptr), list()
168  {
169  // Empty
170  }
171 
172  Path(const Path & path)
173  : ptr_owner_graph(path.ptr_owner_graph), list(path.list)
174  {
175  // Empty
176  }
177 
178  Path(Path && path)
179  : ptr_owner_graph(nullptr), list()
180  {
181  std::swap(ptr_owner_graph, path.ptr_owner_graph);
182  std::swap(list, path.list);
183  }
184 
185  GT & get_graph()
186  {
187  test_for_graph();
188  return *ptr_owner_graph;
189  }
190 
191  void init(NodeType * start)
192  {
193  test_for_graph();
194  list.clear();
195  list.append(PathDesc(start));
196  }
197 
198  void set(GT & graph, NodeType * ptr_start = nullptr)
199  {
200  clear();
201 
202  ptr_owner_graph = &graph;
203 
204  if (ptr_start != nullptr)
205  init(ptr_start);
206  }
207 
208  void clear()
209  {
210  list.clear();
211  }
212 
213  void insert(ArcType * arc)
214  {
215  test_for_graph();
216 
217  if (list.is_empty())
218  throw std::domain_error("Path is empty");
219 
220  PathDesc & first = list.get_first();
221 
222  NodeType * prev_node = arc->get_connected_node(first.node);
223 
224  list.insert(PathDesc(prev_node, arc));
225  }
226 
227  void insert(NodeType * s)
228  {
229  test_for_graph();
230 
231  if (list.is_empty())
232  {
233  init(s);
234  return;
235  }
236 
237  PathDesc & first = list.get_first();
238 
239  ArcType * ptr_arc = ptr_owner_graph->search_arc(s, first.node);
240 
241  if (ptr_arc == nullptr)
242  throw std::logic_error("There is not arc between last and current node");
243 
244  list.insert(PathDesc(s, ptr_arc));
245  }
246 
247  void append(ArcType * arc)
248  {
249  test_for_graph();
250 
251  if (list.is_empty())
252  throw std::domain_error("Path is empty");
253 
254  PathDesc & last = list.get_last();
255 
256  last.arc = arc;
257 
258  NodeType * next_node = arc->get_connected_node(last.node);
259 
260  list.append(PathDesc(next_node));
261  }
262 
263  void append(NodeType * t)
264  {
265  test_for_graph();
266 
267  if (list.is_empty())
268  {
269  init(t);
270  return;
271  }
272 
273  PathDesc & last = list.get_last();
274 
275  ArcType * ptr_arc = ptr_owner_graph->search_arc(last.node, t);
276 
277  if (ptr_arc == nullptr)
278  throw std::logic_error("There is not arc between last and current node");
279 
280  last.arc = ptr_arc;
281 
282  list.append(PathDesc(t));
283  }
284 
286  {
287  test_for_graph();
288 
289  if (list.is_empty())
290  throw std::underflow_error("Path is empty");
291 
292  list.remove_last();
293 
294  if (not list.is_empty())
295  list.get_last().arc = nullptr;
296  }
297 
299  {
300  test_for_graph();
301 
302  if (list.is_empty())
303  throw std::overflow_error("Path is empty");
304 
305  return list.get_last().node;
306  }
307 
309  {
310  test_for_graph();
311 
312  if (list.is_empty())
313  throw std::overflow_error("Path is empty");
314 
315  return list.get_last().node;
316  }
317 
319  {
320  if (list.is_empty())
321  throw std::underflow_error("Path is empty");
322 
323  return list.get_first().node;
324  }
325 
327  {
328  if (list.is_empty())
329  throw std::underflow_error("Path is empty");
330 
331  return list.get_first().node;
332  }
333 
335  {
336  if (list.is_empty())
337  throw std::overflow_error("Path is empty");
338 
339  if (list.size() == 1)
340  throw std::overflow_error("Path has only one node (without arcs)");
341 
342  return list.get_last().arc;
343  }
344 
346  {
347  if (list.is_empty())
348  throw std::overflow_error("Path is empty");
349 
350  if (list.size() == 1)
351  throw std::overflow_error("Path has only one node (without arcs)");
352 
353 
354  return list.get_last().arc;
355  }
356 
358  {
359  if (list.is_empty())
360  throw std::underflow_error("Path is empty");
361 
362  if (list.is_unitarian())
363  throw std::underflow_error("Path has only one node (without arcs)");
364 
365  return list.get_first().arc;
366  }
367 
369  {
370  if (list.is_empty())
371  throw std::underflow_error("Path is empty");
372 
373  if (list.is_unitarian())
374  throw std::underflow_error("Path has only one node (without arcs)");
375 
376  return list.get_first().arc;
377  }
378 
379  template <class Op>
380  void for_each(Op & op) const
381  {
382  for (const PathDesc & path_desc : list)
383  op(path_desc.node, path_desc.arc);
384  }
385 
386  template <class Op>
387  void for_each(Op && op = Op()) const
388  {
389  for_each<Op>(op);
390  }
391 
392  template <class Op>
393  void for_each(Op & op)
394  {
395  for (PathDesc & path_desc : list)
396  op(path_desc.node, path_desc.arc);
397  }
398 
399  template <class Op>
400  void for_each(Op && op = Op())
401  {
402  for_each<Op>(op);
403  }
404 
405  Path & operator = (const Path & path)
406  {
407  if (&path == this)
408  return *this;
409 
410  ptr_owner_graph = path.ptr_owner_graph;
411  list = path.list;
412 
413  return *this;
414  }
415 
417  {
418  return list.template map<Node<GT> *,SLList<Node<GT> *>>([] (auto & pd)
419  {
420  return pd.node;
421  });
422  }
423 
424  SLList<Arc<GT> *> arcs() const
425  {
426  return list.template map_if<Arc<GT> *>
427  ([] (auto & pd)
428  {
429  return pd.arc;
430  },
431  [] (auto & pd)
432  {
433  return pd.arc != nullptr;
434  });
435  }
436 
437  Path & operator = (Path && path)
438  {
439  std::swap(ptr_owner_graph, path.ptr_owner_graph);
440  std::swap(list, path.list);
441 
442  return *this;
443  }
444 
445  bool is_empty() const
446  {
447  return list.is_empty();
448  }
449 
450  nat_t size() const
451  {
452  return list.size();
453  }
454  };
455 
456  // For compute cut nodes and Tarjan algorithm
457  template <class GT>
458  inline lint_t & df(Node<GT> * p)
459  {
460  return p->counter();
461  }
462 
463  template <class GT>
464  inline lint_t & low(Node<GT> * p)
465  {
466  return (lint_t &) p->cookie();
467  }
468 
469 
470  // For Dijkstra and Astar algorithms
471  template <class GT, class Distance>
473  {
474  public:
476  typename Distance::Type accumulated_distance;
477 
479  : tree_node(nullptr), accumulated_distance(Distance::ZERO)
480  {
481  // empty
482  }
483  };
484 
485  template <class GT, class Distance>
487  {
488  public:
490  typename Distance::Type potential;
492 
494  : tree_arc(nullptr), potential(Distance::ZERO), is_in_queue(false)
495  {
496  // empty
497  }
498  };
499 
500  template <class GT, class Distance>
502  {
503  return (MinPathNodeInfo<GT, Distance> *&) p->cookie();
504  }
505 
506  template <class GT, class Distance>
507  inline Node<GT> *& TREE_NODE(Node<GT> * p)
508  {
509  return NI<GT, Distance>(p)->tree_node;
510  }
511 
512  template <class GT, class Distance>
513  inline typename Distance::Type & ACC(Node<GT> * p)
514  {
515  return NI<GT, Distance>(p)->accumulated_distance;
516  }
517 
518  template <class GT, class Distance>
520  {
521  return (MinPathArcInfo<GT, Distance> *&) a->cookie();
522  }
523 
524  template <class GT, class Distance>
525  inline Arc<GT> *& TREE_ARC(Arc<GT> * a)
526  {
527  return AI<GT, Distance>(a)->tree_arc;
528  }
529 
530  template <class GT, class Distance>
531  inline typename Distance::Type & POT(Arc<GT> * a)
532  {
533  return AI<GT, Distance>(a)->potential;
534  }
535 
536  template <class GT, class Distance>
537  inline bool & IS_IN_QUEUE(Arc<GT> * a)
538  {
539  return AI<GT, Distance>(a)->is_in_queue;
540  }
541 
542  template <class GT, class Distance>
543  inline void allocate_node_info(const GT & g)
544  {
545  g.for_each_node([](Node<GT> * node)
546  {
547  NI<GT, Distance>(node) = new MinPathNodeInfo<GT, Distance>;
548  });
549  }
550 
551  template <class GT, class Distance>
552  inline void allocate_arc_info(const GT & g)
553  {
554  g.for_each_arc([] (Arc<GT> * arc)
555  {
556  AI<GT, Distance>(arc) = new MinPathArcInfo<GT, Distance>;
557  });
558  }
559 
560  template <class GT, class Distance>
561  void destroy_node_info(const GT & g)
562  {
563  g.for_each_node([] (Node<GT> * node)
564  {
565  auto to_destroy = NI<GT, Distance>(node);
566  auto ptr_tree_node = TREE_NODE<GT, Distance>(node);
567 
568  if (ptr_tree_node == nullptr)
569  node->cookie() = nullptr;
570  else
571  {
572  node->cookie() = ptr_tree_node;
573  ptr_tree_node->cookie() = node;
574  }
575 
576  delete to_destroy;
577  });
578  }
579 
580  template <class GT, class Distance>
581  void destroy_arc_info(const GT & g)
582  {
583  g.for_each_arc([&] (Arc<GT> * arc)
584  {
585  auto to_destroy = AI<GT, Distance>(arc);
586  auto ptr_tree_arc = TREE_ARC<GT, Distance>(arc);
587 
588  if (ptr_tree_arc == nullptr)
589  arc->cookie() = nullptr;
590  else
591  {
592  arc->cookie() = ptr_tree_arc;
593  ptr_tree_arc->cookie() = arc;
594  }
595 
596  delete to_destroy;
597  });
598  }
599 
600  template <class GT, class Distance, class Heap>
601  void put_in_heap(Arc<GT> * a, Node<GT> * t, Heap & h)
602  {
603  if (IS_IN_QUEUE<GT, Distance>(a))
604  return;
605 
606  IS_IN_QUEUE<GT, Distance>(a) = true;
607  h.insert_arc(a, t);
608  }
609 
610  template <class GT, class Distance, class Heap>
611  Arc<GT> * get_from_heap(Heap & h)
612  {
613  Arc<GT> * ret_val = h.get_min_arc();
614  IS_IN_QUEUE<GT, Distance>(ret_val) = false;
615  return ret_val;
616  }
617 
618  template <class GT, class Distance>
619  class GetPot
620  {
621  public:
622  typename Distance::Type operator () (Arc<GT> * a)
623  {
624  return POT<GT, Distance>(a);
625  }
626  };
627 
628  template <class GT>
630  {
631  public:
632  void operator () (Node<GT> *, nat_t, nat_t)
633  {
634  // empty
635  }
636  };
637 
638  template <class GT>
640  {
641  public:
642  void operator () (Arc<GT> *, nat_t, nat_t)
643  {
644  // empty
645  }
646  };
647 
648  template <class GT>
650  {
651  public:
652  void operator () (Node<GT> *)
653  {
654  // empty
655  }
656  };
657 
658  template <class GT>
660  {
661  public:
662  void operator () (Arc<GT> *)
663  {
664  // empty
665  }
666  };
667 
668  template <class GT>
670  {
671  public:
672  void operator () (std::ostream & out, const Node<GT> * p)
673  {
674  out << p->get_info();
675  }
676 
677  void operator () (std::ofstream & out, const Node<GT> * p)
678  {
679  out.write(reinterpret_cast<const char *>(&p->get_info()),
680  sizeof(typename GT::NodeInfoType));
681  }
682  };
683 
684  template <class GT>
686  {
687  public:
688  void operator () (std::ostream & out, const Arc<GT> * a)
689  {
690  out << a->get_info();
691  }
692 
693  void operator () (std::ofstream & out, const Arc<GT> * a)
694  {
695  out.write(reinterpret_cast<const char *>(&a->get_info()),
696  sizeof(typename GT::ArcInfoType));
697  }
698  };
699 
700  template <class GT>
702  {
703  public:
704  void operator () (std::ostream & out, const GT & g)
705  {
706  out << g.get_info();
707  }
708 
709  void operator () (std::ofstream & out, const GT & g)
710  {
711  out.write(reinterpret_cast<const char *>(&g.get_info()),
712  sizeof(typename GT::GraphInfoType));
713  }
714  };
715 
716  template <class GT>
718  {
719  public:
720  void operator () (std::istream & in, Node<GT> * p)
721  {
722  in >> p->get_info();
723  }
724 
725  void operator () (std::ifstream & in, Node<GT> * p)
726  {
727  in.read(reinterpret_cast<char *>(&p->get_info()),
728  sizeof(typename GT::NodeInfoType));
729  }
730  };
731 
732  template <class GT>
734  {
735  public:
736  void operator () (std::istream & in, Arc<GT> * a)
737  {
738  in >> a->get_info();
739  }
740 
741  void operator () (std::ifstream & in, Arc<GT> * a)
742  {
743  in.read(reinterpret_cast<char *>(&a->get_info()),
744  sizeof(typename GT::ArcInfoType));
745  }
746  };
747 
748  template <class GT>
750  {
751  public:
752  void operator () (std::istream & in, GT & g)
753  {
754  in >> g.get_info();
755  }
756 
757  void operator () (std::ifstream & in, GT & g)
758  {
759  in.read(reinterpret_cast<char *>(&g.get_info()),
760  sizeof(typename GT::GraphInfoType));
761  }
762  };
763 
764  template <class GT>
766  {
767  public:
768  std::string operator () (Node<GT> * p)
769  {
770  std::stringstream s;
771  s << "label = \"" << p->get_info() << "\"";
772  return s.str();
773  }
774  };
775 
776  template <class GT>
778  {
779  public:
780  std::string operator () (Arc<GT> * a)
781  {
782  std::stringstream s;
783  s << "label = \"" << a->get_info() << "\"";
784  return s.str();
785  }
786  };
787 
788  template <class GT>
790  {
791  public:
792  std::string operator () (const GT &)
793  {
794  return " // Without graph attributes";
795  }
796  };
797 
798 } // end namespace Designar
799 
800 # endif // GRAPHUTILITIES_H
Definition: graphutilities.H:619
void clear()
Definition: list.H:652
Path()
Definition: graphutilities.H:154
void map_arcs(Arc< SG > *a, Arc< TG > *b)
Definition: graphutilities.H:105
void for_each(Op &op)
Definition: graphutilities.H:393
Definition: graphutilities.H:749
void allocate_arc_info(const GT &g)
Definition: graphutilities.H:552
Arc< GT > * tree_arc
Definition: graphutilities.H:489
void init(NodeType *start)
Definition: graphutilities.H:191
Node< GT > * tree_node
Definition: graphutilities.H:475
Definition: graphutilities.H:733
NodeType * get_first_node()
Definition: graphutilities.H:318
Definition: graphutilities.H:659
NodeType * get_first_node() const
Definition: graphutilities.H:326
typename GT::ArcIterator ArcIt
Definition: graphutilities.H:81
bool is_empty() const
Definition: nodesdef.H:153
lint_t & df(Node< GT > *p)
Definition: graphutilities.H:458
void insert(ArcType *arc)
Definition: graphutilities.H:213
void clear()
Definition: graphutilities.H:208
void remove_last_node()
Definition: graphutilities.H:285
Path(const Path &path)
Definition: graphutilities.H:172
Definition: graphutilities.H:717
ArcType * get_first_arc() const
Definition: graphutilities.H:368
T remove_last()
Definition: list.H:739
void insert(NodeType *s)
Definition: graphutilities.H:227
Definition: graphutilities.H:629
MinPathNodeInfo< GT, Distance > *& NI(Node< GT > *p)
Definition: graphutilities.H:501
T & get_first()
Definition: list.H:695
Definition: graphutilities.H:685
NodeType * get_last_node()
Definition: graphutilities.H:298
lint_t & low(Node< GT > *p)
Definition: graphutilities.H:464
Arc< GT > * get_from_heap(Heap &h)
Definition: graphutilities.H:611
MinPathNodeInfo()
Definition: graphutilities.H:478
T & get_last()
Definition: list.H:711
void map_graph_item(CommonNodeArc *x, CommonNodeArc *y)
Definition: graphutilities.H:84
void append(ArcType *arc)
Definition: graphutilities.H:247
Definition: graphutilities.H:649
SLList< Node< GT > * > nodes() const
Definition: graphutilities.H:416
SLList< Arc< GT > * > arcs() const
Definition: graphutilities.H:424
nat_t size() const
Definition: graphutilities.H:450
bool is_empty() const
Definition: graphutilities.H:445
void map_nodes(Node< SG > *p, Node< TG > *q)
Definition: graphutilities.H:99
void for_each(Op &&op=Op())
Definition: graphutilities.H:400
typename GT::AdjacentArcIterator AdArcIt
Definition: graphutilities.H:82
void for_each(Op &op) const
Definition: graphutilities.H:380
bool is_unitarian() const
Definition: nodesdef.H:163
Arc< GT > *& TREE_ARC(Arc< GT > *a)
Definition: graphutilities.H:525
MinPathArcInfo< GT, Distance > *& AI(Arc< GT > *a)
Definition: graphutilities.H:519
void for_each(Op &&op=Op()) const
Definition: graphutilities.H:387
void destroy_arc_info(const GT &g)
Definition: graphutilities.H:581
Path(Path &&path)
Definition: graphutilities.H:178
void allocate_node_info(const GT &g)
Definition: graphutilities.H:543
typename GT::Node Node
Definition: graphutilities.H:78
Node< GT > *& TREE_NODE(Node< GT > *p)
Definition: graphutilities.H:507
Definition: graphutilities.H:669
long long lint_t
Definition: types.H:49
T & insert(const T &item)
Definition: list.H:663
void put_in_heap(Arc< GT > *a, Node< GT > *t, Heap &h)
Definition: graphutilities.H:601
Definition: italgorithms.H:33
GT & get_graph()
Definition: graphutilities.H:185
Definition: graphutilities.H:777
bool is_in_queue
Definition: graphutilities.H:491
ArcType * get_last_arc()
Definition: graphutilities.H:334
Definition: graphutilities.H:639
T & append(const T &item)
Definition: list.H:679
Definition: graphutilities.H:486
ArcType * get_first_arc()
Definition: graphutilities.H:357
Definition: graphutilities.H:472
void append(NodeType *t)
Definition: graphutilities.H:263
Definition: graphutilities.H:54
NodeType * get_last_node() const
Definition: graphutilities.H:308
Definition: graphutilities.H:765
Definition: graphutilities.H:789
Definition: graphutilities.H:123
Path(GT *graph_ptr)
Definition: graphutilities.H:166
void destroy_node_info(const GT &g)
Definition: graphutilities.H:561
Definition: array.H:32
Distance::Type potential
Definition: graphutilities.H:490
unsigned long int nat_t
Definition: types.H:50
bool & IS_IN_QUEUE(Arc< GT > *a)
Definition: graphutilities.H:537
typename GT::NodeIterator NodeIt
Definition: graphutilities.H:80
nat_t size() const
Definition: list.H:647
Node< GT > NodeType
Definition: graphutilities.H:126
Distance::Type & ACC(Node< GT > *p)
Definition: graphutilities.H:513
TG::Node * mapped_node(Node< SG > *p)
Definition: graphutilities.H:111
Distance::Type & POT(Arc< GT > *a)
Definition: graphutilities.H:531
GraphTag
Definition: graphutilities.H:37
Path(const GT &graph)
Definition: graphutilities.H:160
typename GT::Arc Arc
Definition: graphutilities.H:79
MinPathArcInfo()
Definition: graphutilities.H:493
Definition: graphutilities.H:701
ArcType * get_last_arc() const
Definition: graphutilities.H:345
Arc< GT > ArcType
Definition: graphutilities.H:127
TG::Arc * mapped_arc(Arc< SG > *a)
Definition: graphutilities.H:117
Distance::Type accumulated_distance
Definition: graphutilities.H:476