DeSiGNAR  0.5a
Data Structures General Library
graphalgorithms.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 DSGGRAPHALGORITHMS_H
26 # define DSGGRAPHALGORITHMS_H
27 
28 # include <relation.H>
29 # include <graph.H>
30 # include <random.H>
31 
32 namespace Designar
33 {
34 
35  /* Depth first based algorithms */
36 
37  template <class GT, class Op>
38  void depth_first_traverse_prefix_rec(const GT &, Node<GT> *, Op &);
39 
40  template <class GT, class Op>
41  void depth_first_traverse_prefix(const GT &, Op & op);
42 
43  template <class GT, class Op>
44  void depth_first_traverse_prefix(const GT & g, Op && op = Op())
45  {
46  depth_first_traverse_prefix<GT, Op>(g, op);
47  }
48 
49  template <class GT, class Op>
50  void depth_first_traverse_sufix_rec(const GT &, Node<GT> *, Op &);
51 
52  template <class GT, class Op>
53  void depth_first_traverse_sufix(const GT &, Op & op);
54 
55  template <class GT, class Op>
56  void depth_first_traverse_sufix(const GT & g, Op && op = Op())
57  {
58  depth_first_traverse_sufix<GT, Op>(g, op);
59  }
60 
61  template <class GT, class Op>
62  void depth_first_traverse(const GT & g, Op & op)
63  {
64  depth_first_traverse_prefix<GT, Op>(g, op);
65  }
66 
67  template <class GT, class Op>
68  void depth_first_traverse(const GT & g, Op && op = Op())
69  {
70  depth_first_traverse<GT, Op>(g, op);
71  }
72 
73  template <class GT>
74  bool depth_first_search_path_rec(const GT &, Node<GT> *, Node<GT> *, Path<GT> &);
75 
76  template <class GT>
78 
79  template <class GT>
80  bool test_cycle_rec(const GT &, Node<GT> *, bool);
81 
82  template <class GT>
83  bool has_cycle(const GT &, Node<GT> *);
84 
85  template <class GT>
86  bool has_cycle(const GT &);
87 
88  template <class GT>
89  bool is_graph_acyclique(const GT &, Node<GT> *);
90 
91  template <class GT>
92  bool is_graph_acyclique(const GT &);
93 
94  template <class GT>
95  GT invert_digraph(const GT &, bool);
96 
97  template <class GT>
98  void build_subgraph_rec(const GT &, Node<GT> *, const GT &);
99 
100  template <class GT>
102 
103  template <class GT>
104  void add_nodes_to_component_rec(const GT &, Node<GT> *, SLList<Node<GT> *> &);
105 
106  template <class GT>
108 
109  template <class GT>
110  void compute_cut_nodes_rec(const GT &, Node<GT> *, Arc<GT> &,
111  SLList<Node<GT> *> &, lint_t &);
112 
113  template <class GT>
114  SLList<Node<GT> *> compute_cut_nodes(const GT &);
115 
116  template <class GT>
118 
119  template <class GT>
120  void paint_from_cut_node(const GT &, Node<GT> *, lint_t &);
121 
122  template <class GT>
123  lint_t paint_cut_nodes_subgraphs(const GT &, const SLList<Node<GT> *> &);
124 
125  template <class GT>
126  void build_cut_nodes_subgraph_rec(const GT &, Node<GT> *, const GT &, lint_t);
127 
128  template <class GT>
130 
131  template <class GT>
132  std::tuple<GT, SLList<Arc<GT> *>>
133  build_cut_graph(const GT &, const SLList<Node<GT> *> &);
134 
135  template <class GT>
136  std::tuple<SLList<GT>, GT, SLList<Arc<GT> *>>
138  const SLList<Node<GT> *> &);
139 
140  template <class GT>
141  void Kosaraju_build_subgraph_rec(const GT &, Node<GT> *, const GT &, nat_t);
142 
143  template <class GT>
145 
146  template <class GT>
147  SLList<Node<GT> *> df_topological_sort(const GT &);
148 
149  /* Breadth first based algorithms */
150 
151  template <class GT, class Op>
152  void breadth_first_traverse(const GT &, Node<GT> *, Op &);
153 
154  template <class GT, class Op>
155  void breadth_first_traverse(const GT & g, Node<GT> * p, Op && op = Op())
156  {
157  breadth_first_traverse<GT, Op>(g, p, op);
158  }
159 
160  template <class GT, class Op>
161  void breadth_first_traverse(const GT & g, Op & op)
162  {
163  breadth_first_traverse<GT, Op>(g, g.get_first_node(), op);
164  }
165 
166  template <class GT, class Op>
167  void breadth_first_traverse(const GT & g, Op && op = Op())
168  {
169  breadth_first_traverse<GT, Op>(g, op);
170  }
171 
172  template <class GT>
174 
175  template <class GT>
176  SLList<Node<GT> *> bf_topological_sort(const GT &);
177 
178  template <class GT>
180 
181  template <class GT, class Op>
182  void depth_first_traverse_prefix_rec(const GT & g, Node<GT> * p, Op & op)
183  {
184  if (p->is_visited(GraphTag::DEPTH_FIRST))
185  return;
186 
187  op(p);
188  p->visit(GraphTag::DEPTH_FIRST);
189 
190  for (AdArcIt<GT> it(g, p); it.has_current(); it.next())
191  {
192  Arc<GT> * a = *it;
193 
194  if (a->is_visited(GraphTag::DEPTH_FIRST))
195  continue;
196 
197  a->visit(GraphTag::DEPTH_FIRST);
198 
199  Node<GT> * q = it.get_tgt_node();
200 
202  }
203  }
204 
205  template <class GT, class Op>
206  void depth_first_traverse_sufix_rec(const GT & g, Node<GT> * p, Op & op)
207  {
208  if (p->is_visited(GraphTag::DEPTH_FIRST))
209  return;
210 
211  p->visit(GraphTag::DEPTH_FIRST);
212 
213  for (AdArcIt<GT> it(g, p); it.has_current(); it.next())
214  {
215  Arc<GT> * a = *it;
216 
217  if (a->is_visited(GraphTag::DEPTH_FIRST))
218  continue;
219 
220  a->visit(GraphTag::DEPTH_FIRST);
221 
222  Node<GT> * q = it.get_tgt_node();
223 
225  }
226 
227  op(p);
228  }
229 
230  template <class GT>
231  bool depth_first_search_path_rec(const GT & g, Node<GT> * p, Node<GT> * end,
232  Path<GT> & path)
233  {
234  if (p->is_visited(GraphTag::DEPTH_FIRST))
235  return false;
236 
237  p->visit(GraphTag::DEPTH_FIRST);
238 
239  path.append(p);
240 
241  if (p == end)
242  return true;
243 
244  for (AdArcIt<GT> it(g, p); it.has_current(); it.next())
245  {
246  Arc<GT> * a = *it;
247 
248  if (a->is_visited(GraphTag::DEPTH_FIRST))
249  continue;
250 
251  a->visit(GraphTag::DEPTH_FIRST);
252 
253  Node<GT> * q = it.get_tgt_node();
254 
255  if (depth_first_search_path_rec(g, q, end, path))
256  return true;
257  }
258 
259  path.remove_last_node();
260  return false;
261  }
262 
263  template <class GT>
264  bool test_cycle_rec(const GT & g, Node<GT> * p, bool has)
265  {
266  if (p->is_visited(GraphTag::DEPTH_FIRST))
267  return has;
268 
269  p->visit(GraphTag::DEPTH_FIRST);
270 
271  for (AdArcIt<GT> it(g, p); it.has_current(); it.next())
272  {
273  Arc<GT> * a = *it;
274 
275  if (a->is_visited(GraphTag::DEPTH_FIRST))
276  continue;
277 
278  a->visit(GraphTag::DEPTH_FIRST);
279 
280  Node<GT> * q = it.get_tgt_node();
281 
282  if (test_cycle_rec(g, q, has) == has)
283  return has;
284  }
285 
286  return not has;
287  }
288 
289  template <class GT>
290  bool has_cycle(const GT & g, Node<GT> * start)
291  {
292  g.reset_tag(GraphTag::DEPTH_FIRST);
293  return test_cycle_rec(g, start, true);
294  }
295 
296  template <class GT>
297  bool has_cycle(const GT & g)
298  {
299  if (g.get_num_arcs() >= g.get_num_nodes())
300  return true;
301 
302  return g.exists_node([&g] (Node<GT> * p)
303  {
304  return has_cycle(g, p);
305  });
306  }
307 
308 
309  template <class GT>
310  bool is_acyclique(const GT & g, Node<GT> * start)
311  {
312  g.reset_tag(GraphTag::DEPTH_FIRST);
313  return test_cycle_rec(g, start, false);
314  }
315 
316  template <class GT>
317  bool is_acyclique(const GT & g)
318  {
319  if (g.get_num_arcs() >= g.get_num_nodes())
320  return false;
321 
322  return g.all_nodes([&g] (Node<GT> * p)
323  {
324  return is_acyclique(g, p);
325  });
326  }
327 
328  template <class GT, class Op>
329  void depth_first_traverse_prefix(const GT & g, Op & op)
330  {
331  g.reset_tag(GraphTag::DEPTH_FIRST);
332 
333  for (NodeIt<GT> it(g); it.has_current(); it.next())
334  {
335  Node<GT> * p = it.get_current();
336 
337  if (p->is_visited(GraphTag::DEPTH_FIRST))
338  continue;
339 
341  }
342  }
343 
344  template <class GT, class Op>
345  void depth_first_traverse_sufix(const GT & g, Op & op)
346  {
347  g.reset_tag(GraphTag::DEPTH_FIRST);
348 
349  for (NodeIt<GT> it(g); it.has_current(); it.next())
350  {
351  Node<GT> * p = it.get_current();
352 
353  if (p->is_visited(GraphTag::DEPTH_FIRST))
354  continue;
355 
357  }
358  }
359 
360  template <class GT>
362  Node<GT> * end)
363  {
364  Path<GT> ret_val(g);
365 
366  if (begin == end)
367  {
368  ret_val.init(begin);
369  return ret_val;
370  }
371 
372  g.reset_tag(GraphTag::DEPTH_FIRST);
373 
374  depth_first_search_path_rec(g, begin, end, ret_val);
375  return ret_val;
376  }
377 
378  template <class GT>
379  GT invert_digraph(const GT & g)
380  {
381  if (not g.is_digraph())
382  throw std::domain_error("Argument must be a directed graph");
383 
384  g.reset_node_cookies();
385 
386  GT i;
387 
388  g.for_each_arc([&i] (auto a)
389  {
390  auto s = a->get_src_node();
391  auto t = a->get_tgt_node();
392  auto sp = mapped_node<GT>(s);
393 
394  if (sp == nullptr)
395  {
396  sp = i.insert_node(s->get_info());
397  map_nodes<GT>(s, sp);
398  }
399 
400  auto tp = mapped_node<GT>(t);
401 
402  if (tp == nullptr)
403  {
404  tp = i.insert_node(t->get_info());
405  map_nodes<GT>(t, tp);
406  }
407 
408  auto ap = i.insert_arc(tp, sp, a->get_info());
409  map_arcs<GT>(a, ap);
410  });
411 
412  return i;
413  }
414 
415 
416  template <class GT>
417  void build_subgraph_rec(const GT & g, Node<GT> * p, GT & t)
418  {
419  if (p->is_visited(GraphTag::COMPONENT))
420  return;
421 
422  p->visit(GraphTag::COMPONENT);
423 
424  Node<GT> * pp = t.insert_node(p->get_info());
425  map_nodes<GT>(p, pp);
426 
427  for (AdArcIt<GT> it(g, p); it.has_current(); it.next())
428  {
429  Arc<GT> * a = it.get_current();
430 
431  if (a->is_visited(GraphTag::COMPONENT))
432  continue;
433 
434  a->visit(GraphTag::COMPONENT);
435 
436  Node<GT> * q = it.get_tgt_node();
437 
438  build_subgraph_rec(g, q, t);
439 
440  Node<GT> * qq = mapped_node<GT>(q);
441 
442  Arc<GT> * aa = t.insert_arc(pp, qq, a->get_info());
443  map_arcs<GT>(a, aa);
444  }
445  }
446 
447  template <class GT>
449  {
450  if (g.is_digraph())
451  throw std::domain_error("Argument must be an undirected graph");
452 
453  g.reset_tag(GraphTag::COMPONENT);
454  g.reset_cookies();
455 
456  SLList<GT> ret;
457 
458  g.for_each_node([&g, &ret] (Node<GT> * p)
459  {
460  if (p->is_visited(GraphTag::COMPONENT))
461  return;
462 
463  GT h;
464  build_subgraph_rec(g, p, h);
465  ret.append(std::move(h));
466  });
467 
468 
469  return ret;
470  }
471 
472  template <class GT>
473  void add_nodes_to_component_rec(const GT & g, Node<GT> * p,
474  SLList<Node<GT> *> & list)
475  {
476  if (p->is_visited(GraphTag::COMPONENT))
477  return;
478 
479  p->visit(GraphTag::COMPONENT);
480 
481  list.append(p);
482 
483  for (AdArcIt<GT> it(g, p); it.has_current(); it.next())
484  {
485  Arc<GT> * a = it.get_current();
486 
487  if (a->is_visited(GraphTag::COMPONENT))
488  continue;
489 
490  a->visit(GraphTag::COMPONENT);
491 
492  Node<GT> * q = it.get_tgt_node();
493 
494  add_nodes_to_component_rec(g, q, list);
495  }
496  }
497 
498  template <class GT>
500  {
501  if (g.is_digraph())
502  throw std::domain_error("Argument must be an undirected graph");
503 
504  g.reset_tag(GraphTag::COMPONENT);
505  g.reset_cookies();
506 
507  SLList<SLList<Node<GT> *>> ret;
508 
509  g.for_each_node([&g, &ret] (Node<GT> * p)
510  {
511  if (p->is_visited(GraphTag::COMPONENT))
512  return;
513 
514  SLList<Node<GT> *> l;
516  ret.append(std::move(l));
517  });
518 
519 
520  return ret;
521  }
522 
523  template <class GT>
524  void compute_cut_nodes_rec(const GT & g, Node<GT> * p, Arc<GT> * a,
525  SLList<Node<GT> *> & l, lint_t & cdf)
526  {
527  p->visit(GraphTag::DEPTH_FIRST);
528  low<GT>(p) = df<GT>(p) = cdf++;
529 
530  bool is_cut = false;
531 
532  for (AdArcIt<GT> it(g, p); it.has_current(); it.next())
533  {
534  Arc<GT> * arc = it.get_current();
535 
536  if (arc == a)
537  continue;
538 
539  Node<GT> * q = it.get_tgt_node();
540 
541  if (q->is_visited(GraphTag::DEPTH_FIRST))
542  {
543  if (not arc->is_visited(GraphTag::DEPTH_FIRST))
544  low<GT>(p) = std::min(low<GT>(p), df<GT>(q));
545 
546  continue;
547  }
548 
549  if (arc->is_visited(GraphTag::DEPTH_FIRST))
550  continue;
551 
552  arc->visit(GraphTag::DEPTH_FIRST);
553 
554  compute_cut_nodes_rec(g, q, arc, l, cdf);
555 
556  low<GT>(p) = std::min(low<GT>(p), low<GT>(q));
557 
558  is_cut = low<GT>(q) >= df<GT>(p) and df<GT>(q) != 0;
559  }
560 
561  if (is_cut)
562  {
563  p->visit(GraphTag::CUT);
564  l.append(p);
565  }
566 
567  }
568 
569  template <class GT>
571  {
572  g.for_each_node([] (Node<GT> * p)
573  {
574  p->reset_tag();
575  df<GT>(p) = 0;
576  low<GT>(p) = -1;
577  });
578  g.reset_arcs();
579 
580  nat_t call_counter = 0;
581  lint_t current_df = 0;
582 
583  Node<GT> * start = g.get_first_node();
584  start->visit(GraphTag::DEPTH_FIRST);
585  df<GT>(start) = current_df++;
586 
587  SLList<Node<GT> *> list;
588 
589  for (AdArcIt<GT> it(g, start); it.has_current(); it.next())
590  {
591  Node<GT> * t = it.get_tgt_node();
592 
593  if (t->is_visited(GraphTag::DEPTH_FIRST))
594  continue;
595 
596  Arc<GT> * a = it.get_current();
597 
598  if (a->is_visited(GraphTag::DEPTH_FIRST))
599  continue;
600 
601  a->visit(GraphTag::DEPTH_FIRST);
602 
603  compute_cut_nodes_rec(g, t, a, list, current_df);
604  ++call_counter;
605  }
606 
607  if (call_counter > 1)
608  {
609  start->visit(GraphTag::CUT);
610  list.append(start);
611  }
612 
613  return list;
614  }
615 
616  template <class GT>
618  lint_t c)
619  {
620  if (p->counter() > 0)
621  return;
622 
623  p->counter() = c;
624 
625  for (AdArcIt<GT> it(g, p); it.has_current(); it.next())
626  {
627  Arc<GT> * a = it.get_current();
628 
629  if (a->counter() > 0)
630  continue;
631 
632  Node<GT> * q = it.get_tgt_node();
633 
634  if (q->is_visited(GraphTag::CUT))
635  continue;
636 
637  a->counter() = c;
638 
640  }
641  }
642 
643  template <class GT>
644  void paint_from_cut_node(const GT & g, Node<GT> * p, lint_t & color)
645  {
646  for (AdArcIt<GT> it(g, p); it.has_current(); it.next())
647  {
648  Arc<GT> * a = it.get_current();
649  Node<GT> * q = it.get_tgt_node();
650 
651  if (q->is_visited(GraphTag::CUT))
652  {
653  a->visit(GraphTag::CUT);
654  continue;
655  }
656  else
657  {
658  a->counter() = -1;
659 
660  if (q->counter() > 0)
661  continue;
662  }
663 
665  ++color;
666  }
667  }
668 
669  template <class GT>
670  lint_t paint_cut_nodes_subgraphs(const GT & g, const SLList<Node<GT> *> & l)
671  {
672  g.reset_counters();
673 
674  lint_t color = 1;
675 
676  l.for_each([&g, &color] (Node<GT> * curr)
677  {
678  paint_from_cut_node(g, curr, color);
679  });
680 
681  return color;
682  }
683 
684  template <class GT>
685  void build_cut_nodes_subgraph_rec(const GT & g, Node<GT> * p, GT & t,
686  lint_t color)
687  {
688  Node<GT> * pp = mapped_node<GT>(p);
689 
690  for (AdArcIt<GT> it(g, p); it.has_current(); it.next())
691  {
692  Arc<GT> * a = it.get_current();
693 
694  if (a->counter() != color or a->is_visited(GraphTag::COMPONENT))
695  continue;
696 
697  a->visit(GraphTag::COMPONENT);
698 
699  Node<GT> * q = it.get_tgt_node();
700  Node<GT> * qp = nullptr;
701 
702  if (q->is_visited(GraphTag::COMPONENT))
703  qp = mapped_node<GT>(q);
704  else
705  {
706  qp = t.insert_node(q->get_info());
707  map_nodes<GT>(q, qp);
708  q->visit(GraphTag::COMPONENT);
709  }
710 
711  Arc<GT> * ap = t.insert_arc(pp, qp, a->get_info());
712  map_arcs<GT>(a, ap);
713 
714  build_cut_nodes_subgraph_rec(g, q, t, color);
715  }
716  }
717 
718  template <class GT>
720  {
721  SLList<GT> list;
722 
723  for (NodeIt<GT> it(g); it.has_current(); it.next())
724  {
725  Node<GT> * p = it.get_current();
726 
727  if (p->counter() == 0 or p->is_visited(GraphTag::COMPONENT))
728  continue;
729 
730  GT t;
731  Node<GT> * q = t.insert_node(p->get_info());
732  map_nodes<GT>(p, q);
733  p->visit(GraphTag::COMPONENT);
734  build_cut_nodes_subgraph_rec(g, p, t, p->counter());
735  list.append(std::move(t));
736  }
737 
738  return list;
739  }
740 
741  template <class GT>
742  std::tuple<GT, SLList<Arc<GT> *>>
743  build_cut_graph(const GT & g, const SLList<Node<GT> *> & cut_nodes)
744  {
745  GT cut_graph;
746  SLList<Arc<GT> *> cross_arcs;
747 
748  cut_nodes.for_each([&] (Node<GT> * p)
749  {
750  Node<GT> * q = cut_graph.insert_node(p->get_info());
751  map_nodes<GT>(p, q);
752  });
753 
754 
755  g.for_each_arc([&] (Arc<GT> * a)
756  {
757  if (a->counter() == -1)
758  {
759  cross_arcs.append(a);
760  return;
761  }
762 
763  if (not a->is_visited(GraphTag::CUT))
764  return;
765 
766  auto p = mapped_node<GT>(a->get_src_node());
767  auto q = mapped_node<GT>(a->get_tgt_node());
768  Arc<GT> * ap =
769  cut_graph.insert_arc(p, q, a->get_info());
770  map_arcs<GT>(a, ap);
771  });
772 
773  return std::make_tuple(std::move(cut_graph), std::move(cross_arcs));
774  }
775 
776  template <class GT>
777  std::tuple<SLList<GT>, GT, SLList<Arc<GT> *>>
779  const SLList<Node<GT> *> & cut_nodes)
780  {
781  g.reset_cookies();
782  paint_cut_nodes_subgraphs(g, cut_nodes);
783  auto subgraphs = build_cut_nodes_subgraphs(g);
784  auto t = build_cut_graph(g, cut_nodes);
785  return std::make_tuple(std::move(subgraphs), std::move(std::get<0>(t)),
786  std::move(std::get<1>(t)));
787  }
788 
789  template <class GT>
790  void Kosaraju_build_subgraph_rec(const GT & inv_g, Node<GT> * p, GT & sg,
791  nat_t num)
792  {
793  if (p->is_visited(GraphTag::COMPONENT))
794  return;
795 
796  Node<GT> * pp = sg.insert_node(p->get_info());
797  map_nodes<GT>(p, pp);
798 
799  p->visit(GraphTag::COMPONENT);
800  p->counter() = num;
801 
802  for (AdArcIt<GT> it(inv_g, p); it.has_current(); it.next())
803  {
804  Arc<GT> * a = it.get_current();
805 
806  if (a->is_visited(GraphTag::COMPONENT))
807  continue;
808 
809  Node<GT> * q = a->get_tgt_node();
810 
811  Kosaraju_build_subgraph_rec(inv_g, q, sg, num);
812 
813  Node<GT> * qp = mapped_node<GT>(q);
814 
815  if (p->counter() != q->counter())
816  continue;
817 
818  Arc<GT> * ap = sg.insert_arc(qp, pp, a->get_info());
819 
820  map_arcs<GT>(a, ap);
821  }
822  }
823 
824  template <class GT>
826  {
827  if (not g.is_digraph())
828  throw std::domain_error("Argument must be a directed graph");
829 
830  g.reset_cookies();
831  g.reset_tag(GraphTag::COMPONENT);
832 
833  FixedArray<Node<GT> *> df(g.get_num_nodes());
834  nat_t i = 0;
835  depth_first_traverse_sufix(g, [&df, &i] (Node<GT> * p)
836  {
837  df[i++] = p;
838  });
839 
840  GT ig = invert_digraph(g);
841 
842  SLList<GT> ret;
843  nat_t num_component = 1;
844 
845  for (i = g.get_num_nodes(); i > 0; --i)
846  {
847  Node<GT> * v = mapped_node<GT>(df[i-1]);
848 
849  if (v->is_visited(GraphTag::COMPONENT))
850  continue;
851 
852  GT sc;
853  Kosaraju_build_subgraph_rec(ig, v, sc, num_component++);
854  ret.append(move(sc));
855  }
856 
857  return ret;
858  }
859 
860  template <class GT>
862  {
863  if (not g.is_digraph())
864  throw std::domain_error("Argument must be a directed graph");
865 
866  SLList<Node<GT> *> ret;
867 
868  depth_first_traverse_sufix(g, [&ret] (Node<GT> * p)
869  {
870  ret.insert(p);
871  });
872 
873  return ret;
874  }
875 
876  template <class GT, class Op>
877  void breadth_first_traverse(const GT & g, Node<GT> * begin, Op & op)
878  {
879  g.reset_tag(GraphTag::BREADTH_FIRST);
880 
881  op(begin);
882  begin->visit(GraphTag::BREADTH_FIRST);
883  ListQueue<Node<GT> *> queue;
884  queue.put(begin);
885 
886  while (not queue.is_empty())
887  {
888  Node<GT> * p = queue.get();
889 
890  for (AdArcIt<GT> it(g, p); it.has_current(); it.next())
891  {
892  Arc<GT> * a = *it;
893 
894  if (a->is_visited(GraphTag::BREADTH_FIRST))
895  continue;
896 
897  a->visit(GraphTag::BREADTH_FIRST);
898 
899  Node<GT> * q = it.get_tgt_node();
900 
901  if (q->is_visited(GraphTag::BREADTH_FIRST))
902  continue;
903 
904  op(q);
905  q->visit(GraphTag::BREADTH_FIRST);
906  queue.put(q);
907  }
908  }
909  }
910 
911  template <class GT>
913  Node<GT> * end)
914  {
915  Path<GT> ret_val(g);
916 
917  if (begin == end)
918  {
919  ret_val.init(begin);
920  return ret_val;
921  }
922 
923  g.reset_tag(GraphTag::BREADTH_FIRST);
924  g.reset_node_cookies();
925 
926  begin->visit(GraphTag::BREADTH_FIRST);
927  ListQueue<Node<GT> *> queue;
928  queue.put(begin);
929 
930  Node<GT> * ptr = nullptr;
931 
932  while (not queue.is_empty() and (ptr = queue.get()) != end)
933  {
934  for (AdArcIt<GT> it(g, ptr); it.has_current(); it.next())
935  {
936  Arc<GT> * a = *it;
937 
938  if (a->is_visited(GraphTag::BREADTH_FIRST))
939  continue;
940 
941  a->visit(GraphTag::BREADTH_FIRST);
942 
943  Node<GT> * q = it.get_tgt_node();
944 
945  if (q->is_visited(GraphTag::BREADTH_FIRST))
946  continue;
947 
948  q->cookie() = ptr;
949  q->visit(GraphTag::BREADTH_FIRST);
950  queue.put(q);
951  }
952  }
953 
954  if (end->cookie() == nullptr)
955  return ret_val;
956 
957  Node<GT> * aux = end;
958 
959  while (aux != begin)
960  {
961  ret_val.insert(aux);
962  aux = reinterpret_cast<Node<GT> *>(aux->cookie());
963  }
964 
965  ret_val.insert(begin);
966 
967  return ret_val;
968  }
969 
970  template <class GT>
972  {
973  if (not g.is_digraph())
974  throw std::domain_error("Argument must be a directed graph");
975 
976  g.reset_node_counter();
977 
978  g.for_each_arc([] (Arc<GT> * a)
979  {
980  ++a->get_tgt_node()->counter();
981  });
982 
983  ListQueue<Node<GT> *> queue;
984 
985  g.for_each_node([&queue] (Node<GT> * p)
986  {
987  if (p->counter() == 0)
988  queue.put(p);
989  });
990 
991  SLList<Node<GT> *> ret;
992 
993  while (not queue.is_empty())
994  {
995  Node<GT> * p = queue.get();
996 
997  ret.append(p);
998 
999  for (AdArcIt<GT> it(g, p); it.has_current(); it.next())
1000  {
1001  Node<GT> * q = it.get_tgt_node();
1002 
1003  if (--q->counter() == 0)
1004  queue.put(q);
1005  }
1006  }
1007 
1008  return ret;
1009  }
1010 
1011  template <class GT>
1013  {
1014  if (not g.is_digraph())
1015  throw std::domain_error("Argument must be a directed graph");
1016 
1017  g.reset_node_counter();
1018 
1019  g.for_each_arc([] (Arc<GT> * a)
1020  {
1021  ++a->get_tgt_node()->counter();
1022  });
1023 
1024  ListQueue<Node<GT> *> queue;
1025 
1026  g.for_each_node([&queue] (Node<GT> * p)
1027  {
1028  if (p->counter() == 0)
1029  queue.put(p);
1030  });
1031 
1032  SLList<SLList<Node<GT> *>> ret;
1033 
1034  while (not queue.is_empty())
1035  {
1036  ListQueue<Node<GT> *> aqueue;
1037 
1038  SLList<Node<GT> *> & l = ret.append(SLList<Node<GT> *>());
1039 
1040  while (not queue.is_empty())
1041  {
1042  Node<GT> * p = queue.get();
1043 
1044  l.append(p);
1045 
1046  for (AdArcIt<GT> it(g, p); it.has_current(); it.next())
1047  {
1048  Node<GT> * q = it.get_tgt_node();
1049 
1050  if (--q->counter() == 0)
1051  aqueue.put(q);
1052  }
1053  }
1054 
1055  queue = std::move(aqueue);
1056  }
1057 
1058  return ret;
1059  }
1060 
1061  template<class GT>
1063  {
1064  public:
1065  using Type = typename GT::ArcInfoType;
1066 
1067  static constexpr Type ZERO = 0;
1068  static constexpr Type MAX = std::numeric_limits<Type>::max();
1069 
1071  {
1072  return a.get_info();
1073  }
1074 
1075  const Type & operator () (Arc<GT> * a) const
1076  {
1077  return a->get_info();
1078  }
1079  };
1080 
1081  template <class GT, class Distance, class Cmp>
1083  {
1084  Distance & distance;
1085  Cmp & cmp;
1086 
1087  public:
1088  DistanceCmp(Distance & d, Cmp & _cmp)
1089  : distance(d), cmp(_cmp)
1090  {
1091  // empty
1092  }
1093 
1094  DistanceCmp(Distance && d = Distance(), Cmp && _cmp = Cmp())
1095  : distance(d), cmp(_cmp)
1096  {
1097  // empty
1098  }
1099 
1100  bool operator () (Arc<GT> * a, Arc<GT> * b) const
1101  {
1102  return cmp(distance(a), distance(b));
1103  }
1104  };
1105 
1106  template <class GT,
1107  class Distance = DefaultDistance<GT>,
1108  class Cmp = std::less<typename Distance::Type>>
1109  class Kruskal
1110  {
1111  public:
1113  using ArcType = Arc<GT>;
1114 
1115  private:
1117  using DistanceType = typename Distance::Type;
1118 
1119  static constexpr GraphTag TAG = GraphTag::KRUSKAL;
1120 
1121  Distance & distance;
1122  DistCmp cmp;
1123 
1124  public:
1125  Kruskal(Distance & _distance, Cmp & _cmp)
1126  : distance(_distance), cmp(distance, _cmp)
1127  {
1128  // empty
1129  }
1130 
1131  Kruskal(Distance && _distance = Distance(),
1132  Cmp && _cmp = Cmp())
1133  : distance(_distance),
1134  cmp(std::forward<Distance>(_distance), std::forward<Cmp>(_cmp))
1135  {
1136  // Empty
1137  }
1138 
1139  GT build_min_spanning_tree(const GT &);
1140 
1141  void paint_min_spanning_tree(const GT & g)
1142  {
1143  GT tree = build_min_spanning_tree(g);
1144 
1145  g.reset_tag(GraphTag::MIN_SPANNING_TREE);
1146 
1147  tree.for_each_node([] (Node<GT> * t_node)
1148  {
1149  Node<GT> * ptr_g_node = mapped_node<GT>(t_node);
1150  ptr_g_node->visit(GraphTag::MIN_SPANNING_TREE);
1151  });
1152 
1153  tree.for_each_arc([](Arc<GT> * t_arc)
1154  {
1155  Arc<GT> * ptr_g_arc = mapped_arc<GT>(t_arc);
1156  ptr_g_arc->visit(GraphTag::MIN_SPANNING_TREE);
1157  });
1158  }
1159  };
1160 
1161  template <class GT, class Distance, class DistanceCmp>
1163  {
1164  g.reset_tag(TAG);
1165  g.reset_cookies();
1166 
1167  const_cast<GT &>(g).template sort_arcs(cmp);
1168 
1169  GT tree;
1170 
1171  TRelation<Node<GT> *> nodes_rel(g.get_num_nodes());
1172 
1173  for (ArcIt<GT> it(g); it.has_current() and
1174  tree.get_num_arcs() < g.get_num_nodes() - 1; it.next())
1175  {
1176  Arc<GT> * ga = *it;
1177  Node<GT> * gs = ga->get_src_node();
1178  Node<GT> * gt = ga->get_tgt_node();
1179 
1180  Node<GT> * ts_ptr = mapped_node<GT>(gs);
1181 
1182  if (ts_ptr == nullptr)
1183  {
1184  gs->visit(TAG);
1185  ts_ptr = tree.insert_node(gs->get_info());
1186  map_nodes<GT>(gs, ts_ptr);
1187  }
1188 
1189  Node<GT> * tt_ptr = mapped_node<GT>(gt);
1190 
1191  if (tt_ptr == nullptr)
1192  {
1193  gt->visit(TAG);
1194  tt_ptr = tree.insert_node(gt->get_info());
1195  map_nodes<GT>(gt, tt_ptr);
1196  }
1197 
1198  if (nodes_rel.are_connected(ts_ptr, tt_ptr))
1199  continue;
1200 
1201  nodes_rel.join(ts_ptr, tt_ptr);
1202 
1203  Arc<GT> * ta = tree.insert_arc(ts_ptr, tt_ptr, ga->get_info());
1204  ga->visit(TAG);
1205  map_arcs<GT>(ga, ta);
1206  }
1207 
1208  return tree;
1209  }
1210 
1211  template <class GT, class Distance, class Cmp>
1213  {
1214  Distance & distance;
1215  Cmp & cmp;
1216 
1217  public:
1218  ArcHeapCmp(Distance & _distance, Cmp & _cmp)
1219  : distance(_distance), cmp(_cmp)
1220  {
1221  // empty
1222  }
1223  ArcHeapCmp(Distance && _distance = Distance(), Cmp && _cmp = Cmp())
1224  : distance(_distance), cmp(_cmp)
1225  {
1226  // empty
1227  }
1228 
1229  bool operator () (Arc<GT> * a, Arc<GT> * b) const
1230  {
1231  return cmp(distance(a), distance(b));
1232  }
1233  };
1234 
1235  template <class GT,
1236  class Distance = DefaultDistance<GT>,
1237  class Cmp = std::less<typename Distance::Type>>
1238  class ArcHeap : public LHeap<Arc<GT> *, ArcHeapCmp<GT, Distance, Cmp>>
1239  {
1240  using NodeType = Node<GT>;
1241  using ArcType = Arc<GT>;
1242  using Table = HashMap<Node<GT> *, Arc<GT> **>;
1244  using BaseHeap::BaseHeap;
1245 
1246  Table tgt_nodes;
1247 
1248  public:
1249  void insert_arc(Arc<GT> * a, Node<GT> * t)
1250  {
1251  Arc<GT> *** result = tgt_nodes.search(t);
1252 
1253  if (result == nullptr)
1254  {
1255  tgt_nodes[t] = const_cast<Arc<GT> **>(&BaseHeap::insert(a));
1256  return;
1257  }
1258 
1259  Arc<GT> ** ap = *result;
1260 
1261  if (BaseHeap::get_cmp()(*ap, a))
1262  return;
1263 
1264  BaseHeap::remove(*ap);
1265  tgt_nodes[t] = const_cast<Arc<GT> **>(&BaseHeap::insert(a));
1266  }
1267 
1268  Arc<GT> * get_min_arc()
1269  {
1270  Arc<GT> * arc_ptr = BaseHeap::top();
1271  Node<GT> * tgt_ptr = arc_ptr->get_src_node();
1272  Arc<GT> *** result = tgt_nodes.search(tgt_ptr);
1273 
1274  if (result == nullptr or **result != arc_ptr)
1275  result = tgt_nodes.search(tgt_ptr = arc_ptr->get_tgt_node());
1276 
1277  assert(**result == arc_ptr);
1278 
1279  BaseHeap::get();
1280  tgt_nodes.remove(tgt_ptr);
1281 
1282  return arc_ptr;
1283  }
1284  };
1285 
1286  template <class GT,
1287  class Distance = DefaultDistance<GT>,
1288  class Cmp = std::less<typename Distance::Type>>
1289  class Prim
1290  {
1291  public:
1293  using ArcType = Arc<GT>;
1294 
1295  private:
1296  Distance & distance;
1297  Cmp & cmp;
1298 
1299  using DistanceType = typename Distance::Type;
1300 
1301  static constexpr GraphTag TAG = GraphTag::PRIM;
1302 
1303  public:
1304  Prim(Distance & _distance, Cmp & _cmp)
1305  : distance(_distance), cmp(_cmp)
1306  {
1307  // empty
1308  }
1309 
1310  Prim(Distance && _distance = Distance(), Cmp && _cmp = Cmp())
1311  : distance(_distance), cmp(_cmp)
1312  {
1313  // empty
1314  }
1315 
1316  GT build_min_spanning_tree(const GT &, Node<GT> *);
1317 
1318  GT build_min_spanning_tree(const GT & g)
1319  {
1320  return build_min_spanning_tree(g, g.get_first_node());
1321  }
1322 
1323  void paint_min_spanning_tree(const GT & g, Node<GT> * start)
1324  {
1325  GT tree = build_min_spanning_tree(g, start);
1326 
1327  g.reset_tag(GraphTag::MIN_SPANNING_TREE);
1328 
1329  tree.for_each_node([] (Node<GT> * t_node)
1330  {
1331  Node<GT> * ptr_g_node = mapped_node<GT>(t_node);
1332  ptr_g_node->visit(GraphTag::MIN_SPANNING_TREE);
1333  ptr_g_node->cookie() = nullptr;
1334  });
1335 
1336  tree.for_each_arc([](Arc<GT> * t_arc)
1337  {
1338  Arc<GT> * ptr_g_arc = mapped_arc<GT>(t_arc);
1339  ptr_g_arc->visit(GraphTag::MIN_SPANNING_TREE);
1340  ptr_g_arc->cookie() = nullptr;
1341  });
1342  }
1343 
1344  void paint_min_spanning_tree(const GT & g)
1345  {
1346  paint_min_spanning_tree(g, g.get_first_node());
1347  }
1348  };
1349 
1350  template <class GT, class Distance, class Cmp>
1352  {
1353  g.reset_tag(TAG);
1354  g.reset_cookies();
1355 
1356  GT tree;
1357  Node<GT> * t_start = tree.insert_node(start->get_info());
1358  map_nodes<GT>(start, t_start);
1359  start->visit(TAG);
1360 
1361  ArcHeapCmp<GT, Distance, Cmp> arc_heap_cmp(distance, cmp);
1362  ArcHeap<GT, Distance, Cmp> arc_heap(arc_heap_cmp);
1363 
1364  for (AdArcIt<GT> it(g, start); it.has_current(); it.next())
1365  {
1366  Arc<GT> * a = *it;
1367  Node<GT> * t = a->get_connected_node(start);
1368  arc_heap.insert_arc(a, t);
1369  }
1370 
1371  while (not arc_heap.is_empty() and tree.get_num_nodes() < g.get_num_nodes())
1372  {
1373  Arc<GT> * a = arc_heap.get_min_arc();
1374 
1375  if (a->is_visited(TAG))
1376  continue;
1377 
1378  a->visit(TAG);
1379 
1380  Node<GT> * p = a->get_src_node()->is_visited(TAG) ?
1381  a->get_tgt_node() : a->get_src_node();
1382 
1383  if (p->is_visited(TAG))
1384  continue;
1385 
1386  p->visit(TAG);
1387 
1388  Node<GT> * pp = tree.insert_node(p->get_info());
1389  map_nodes<GT>(p, pp);
1390 
1391  Node<GT> * ts = mapped_node<GT>(a->get_src_node());
1392  Node<GT> * tt = mapped_node<GT>(a->get_tgt_node());
1393  Arc<GT> * ap = tree.insert_arc(ts, tt, a->get_info());
1394 
1395  map_arcs<GT>(a, ap);
1396 
1397  for (AdArcIt<GT> it(g, p); it.has_current(); it.next())
1398  {
1399  Arc<GT> * pa = *it;
1400  Node<GT> * pt = pa->get_connected_node(p);
1401  arc_heap.insert_arc(pa, pt);
1402  }
1403  }
1404 
1405  return tree;
1406  }
1407 
1408  template <class GT,
1409  class Distance = DefaultDistance<GT>,
1410  class Cmp = std::less<typename Distance::Type>,
1411  class Plus = std::plus<typename Distance::Type>>
1412  class Dijkstra
1413  {
1414  public:
1416  using ArcType = Arc<GT>;
1417 
1418  private:
1419  Distance & distance;
1420  Cmp & cmp;
1421  Plus & plus;
1422 
1423  using DistanceType = typename Distance::Type;
1424 
1425  static constexpr GraphTag TAG = GraphTag::DIJKSTRA;
1426 
1428 
1429  GT build_partial_min_path_tree(const GT &, Node<GT> *, Node<GT> *);
1430 
1431  public:
1432  Dijkstra(Distance & _distance, Cmp & _cmp, Plus & _plus)
1433  : distance(_distance), cmp(_cmp), plus(_plus)
1434  {
1435  // empty
1436  }
1437 
1438  Dijkstra(Distance && _distance = Distance(),
1439  Cmp && _cmp = Cmp(), Plus && _plus = Plus())
1440  : distance(_distance), cmp(_cmp), plus(_plus)
1441  {
1442  // Empty
1443  }
1444 
1445  GT build_min_path_tree(const GT &, Node<GT> *);
1446 
1447  void paint_min_path_tree(const GT & g, Node<GT> * start)
1448  {
1449  GT tree = build_min_path_tree(g, start);
1450 
1451  g.reset_tag(GraphTag::MIN_PATH_TREE);
1452 
1453  tree.for_each_node([] (Node<GT> * t_node)
1454  {
1455  Node<GT> * ptr_g_node = mapped_node<GT>(t_node);
1456  ptr_g_node->visit(GraphTag::MIN_PATH_TREE);
1457  ptr_g_node->cookie() = nullptr;
1458  });
1459 
1460  tree.for_each_arc([](Arc<GT> * t_arc)
1461  {
1462  Arc<GT> * ptr_g_arc = mapped_arc<GT>(t_arc);
1463  ptr_g_arc->visit(GraphTag::MIN_PATH_TREE);
1464  ptr_g_arc->cookie() = nullptr;
1465  });
1466  }
1467 
1468  Path<GT> search_min_path(const GT & g, Node<GT> * start, Node<GT> * end)
1469  {
1470  GT tree = build_partial_min_path_tree(g, start, end);
1471 
1472  Node<GT> * t_start = mapped_node<GT>(start);
1473  Node<GT> * t_end = mapped_node<GT>(end);
1474 
1475  Path<GT> t_path = depth_first_search_path(tree, t_start, t_end);
1476  Path<GT> path(g);
1477 
1478  if (t_path.is_empty())
1479  return path;
1480 
1481  path.init(start);
1482 
1483  t_path.for_each([&] (Node<GT> *, Arc<GT> * ptr_arc)
1484  {
1485  if (ptr_arc == nullptr)
1486  return;
1487 
1488  Arc<GT> * arc = mapped_arc<GT>(ptr_arc);
1489  path.append(arc);
1490  });
1491 
1492  return path;
1493  }
1494 
1495  void paint_min_path(const GT & g, Node<GT> * start, Node<GT> * end)
1496  {
1497  Path<GT> path = search_min_path(g, start, end);
1498 
1499  g.reset_tag(GraphTag::MIN_PATH);
1500 
1501  path.for_each([] (Node<GT> * ptr_node, Arc<GT> * ptr_arc)
1502  {
1503  ptr_node->visit(GraphTag::MIN_PATH);
1504 
1505  if (ptr_arc != nullptr)
1506  ptr_arc->visit(GraphTag::MIN_PATH);
1507  });
1508  }
1509  };
1510 
1511  template <class GT, class Distance, class Cmp, class Plus>
1513  build_partial_min_path_tree(const GT & g, Node<GT> * start, Node<GT> * end)
1514  {
1515  g.reset_tag(TAG);
1516  allocate_node_info<GT, Distance>(g);
1517  allocate_arc_info<GT, Distance>(g);
1518 
1519  GT tree;
1520 
1521  start->visit(TAG);
1522  ACC<GT, Distance>(start) = Distance::ZERO;
1523  TREE_NODE<GT, Distance>(start) = tree.insert_node(start->get_info());
1524  TREE_NODE<GT, Distance>(start)->cookie() = start;
1525 
1526  GetPot<GT, Distance> get_pot;
1527  ArcHeapCmp<GT, GetPot<GT, Distance>, Cmp> arc_heap_cmp(get_pot, cmp);
1528  PotHeap heap(arc_heap_cmp);
1529 
1530  for (AdArcIt<GT> it(g, start); it.has_current(); it.next())
1531  {
1532  Arc<GT> * arc = *it;
1533  POT<GT, Distance>(arc) = distance(arc);
1534  arc->visit(TAG);
1535  put_in_heap<GT, Distance>(arc, arc->get_connected_node(start), heap);
1536  }
1537 
1538  while (not heap.is_empty() and tree.get_num_nodes() < g.get_num_nodes())
1539  {
1540  Arc<GT> * g_arc = get_from_heap<GT, Distance>(heap);
1541  Node<GT> * g_src = g_arc->get_src_node();
1542  Node<GT> * g_tgt = g_arc->get_tgt_node();
1543 
1544  if (g_src->is_visited(TAG) and g_tgt->is_visited(TAG))
1545  continue;
1546 
1547  Node<GT> * new_node = g_src->is_visited(TAG) ? g_tgt : g_src;
1548 
1549  Node<GT> * t_tgt = tree.insert_node(new_node->get_info());
1550 
1551  TREE_NODE<GT, Distance>(new_node) = t_tgt;
1552 
1553  new_node->visit(TAG);
1554 
1555  Arc<GT> * t_arc = tree.insert_arc(TREE_NODE<GT, Distance>(g_src),
1556  TREE_NODE<GT, Distance>(g_tgt),
1557  g_arc->get_info());
1558 
1559  TREE_ARC<GT, Distance>(g_arc) = t_arc;
1560 
1561  if (new_node == end)
1562  break;
1563 
1564  ACC<GT, Distance>(new_node) = POT<GT, Distance>(g_arc);
1565 
1566  const DistanceType & acc = ACC<GT, Distance>(new_node);
1567 
1568  for (AdArcIt<GT> it(g, new_node); it.has_current(); it.next())
1569  {
1570  Arc<GT> * arc = *it;
1571 
1572  if (arc->is_visited(TAG))
1573  continue;
1574 
1575  arc->visit(TAG);
1576 
1577  Node<GT> * tgt = it.get_tgt_node();
1578 
1579  if (tgt->is_visited(TAG))
1580  continue;
1581 
1582  POT<GT, Distance>(arc) = plus(acc, distance(arc));
1583 
1584  put_in_heap<GT, Distance>(arc, tgt, heap);
1585  }
1586  }
1587 
1588  heap.clear();
1589  destroy_node_info<GT, Distance>(g);
1590  destroy_arc_info<GT, Distance>(g);
1591 
1592  return tree;
1593  }
1594 
1595  template <class GT, class Distance, class Cmp, class Plus>
1597  build_min_path_tree(const GT & g, Node<GT> * start)
1598  {
1599  g.reset_tag(TAG);
1600  allocate_node_info<GT, Distance>(g);
1601  allocate_arc_info<GT, Distance>(g);
1602 
1603  GT tree;
1604 
1605  start->visit(TAG);
1606  ACC<GT, Distance>(start) = Distance::ZERO;
1607  TREE_NODE<GT, Distance>(start) = tree.insert_node(start->get_info());
1608  TREE_NODE<GT, Distance>(start)->cookie() = start;
1609 
1610  GetPot<GT, Distance> get_pot;
1611  ArcHeapCmp<GT, GetPot<GT, Distance>, Cmp> arc_heap_cmp(get_pot, cmp);
1612  PotHeap heap(arc_heap_cmp);
1613 
1614  for (AdArcIt<GT> it(g, start); it.has_current(); it.next())
1615  {
1616  Arc<GT> * arc = *it;
1617 
1618  POT<GT, Distance>(arc) = distance(arc);
1619  arc->visit(TAG);
1620  put_in_heap<GT, Distance>(arc, arc->get_connected_node(start), heap);
1621  }
1622 
1623  while (not heap.is_empty() and tree.get_num_nodes() < g.get_num_nodes())
1624  {
1625  Arc<GT> * g_arc = get_from_heap<GT, Distance>(heap);
1626  Node<GT> * g_src = g_arc->get_src_node();
1627  Node<GT> * g_tgt = g_arc->get_tgt_node();
1628 
1629  if (g_src->is_visited(TAG) and g_tgt->is_visited(TAG))
1630  continue;
1631 
1632  Node<GT> * new_node = g_src->is_visited(TAG) ? g_tgt : g_src;
1633 
1634  Node<GT> * t_tgt = tree.insert_node(new_node->get_info());
1635 
1636  TREE_NODE<GT, Distance>(new_node) = t_tgt;
1637 
1638  new_node->visit(TAG);
1639 
1640  Arc<GT> * t_arc = tree.insert_arc(TREE_NODE<GT, Distance>(g_src),
1641  TREE_NODE<GT, Distance>(g_tgt),
1642  g_arc->get_info());
1643 
1644  TREE_ARC<GT, Distance>(g_arc) = t_arc;
1645 
1646  ACC<GT, Distance>(new_node) = POT<GT, Distance>(g_arc);
1647 
1648  const DistanceType & acc = ACC<GT, Distance>(new_node);
1649 
1650  for (AdArcIt<GT> it(g, new_node); it.has_current(); it.next())
1651  {
1652  Arc<GT> * arc = *it;
1653 
1654  if (arc->is_visited(TAG))
1655  continue;
1656 
1657  arc->visit(TAG);
1658 
1659  Node<GT> * tgt = it.get_tgt_node();
1660 
1661  if (tgt->is_visited(TAG))
1662  continue;
1663 
1664  POT<GT, Distance>(arc) = plus(acc, distance(arc));
1665 
1666  put_in_heap<GT, Distance>(arc, tgt, heap);
1667  }
1668  }
1669 
1670  heap.clear();
1671  destroy_node_info<GT, Distance>(g);
1672  destroy_arc_info<GT, Distance>(g);
1673 
1674  return tree;
1675  }
1676 
1677  template <class GT, class Distance>
1679  {
1680  public:
1681  typename Distance::Type operator () (Node<GT> *, Node<GT> *)
1682  {
1683  return Distance::ZERO;
1684  }
1685  };
1686 
1687  template <class GT,
1688  class Distance = DefaultDistance<GT>,
1689  class Heuristic = DefaultHeuristic<GT, Distance>,
1690  class Cmp = std::less<typename Distance::Type>,
1691  class Plus = std::plus<typename Distance::Type>>
1692  class Astar
1693  {
1694  public:
1696  using ArcType = Arc<GT>;
1697 
1698  private:
1699  Distance & distance;
1700  Heuristic & heuristic;
1701  Cmp & cmp;
1702  Plus & plus;
1703 
1704  using DistanceType = typename Distance::Type;
1705 
1706  static constexpr GraphTag TAG = GraphTag::ASTAR;
1707 
1709 
1710  GT build_partial_min_path_tree(const GT &, Node<GT> *, Node<GT> *);
1711 
1712  public:
1713  Astar(Distance & _distance, Heuristic & _heuristic,
1714  Cmp & _cmp, Plus & _plus)
1715  : distance(_distance), heuristic(_heuristic), cmp(_cmp),
1716  plus(_plus)
1717  {
1718  // empty
1719  }
1720 
1721  Astar(Distance && _distance = Distance(),
1722  Heuristic && _heuristic = Heuristic(), Cmp && _cmp = Cmp(),
1723  Plus && _plus = Plus())
1724  : distance(_distance), heuristic(_heuristic), cmp(_cmp),
1725  plus(_plus)
1726  {
1727  // Empty
1728  }
1729 
1730  Path<GT> search_min_path(const GT & g, Node<GT> * start, Node<GT> * end)
1731  {
1732  GT tree = build_partial_min_path_tree(g, start, end);
1733 
1734  Node<GT> * t_start = mapped_node<GT>(start);
1735  Node<GT> * t_end = mapped_node<GT>(end);
1736 
1737  Path<GT> t_path = depth_first_search_path(tree, t_start, t_end);
1738  Path<GT> path(g);
1739 
1740  if (t_path.is_empty())
1741  return path;
1742 
1743  path.init(start);
1744 
1745  t_path.for_each([&](Node<GT> *, Arc<GT> * ptr_arc)
1746  {
1747  if (ptr_arc == nullptr)
1748  return;
1749 
1750  Arc<GT> * arc = mapped_arc<GT>(ptr_arc);
1751  path.append(arc);
1752  });
1753 
1754  return path;
1755  }
1756 
1757  void paint_min_path(const GT & g, Node<GT> * start, Node<GT> * end)
1758  {
1759  Path<GT> path = search_min_path(g, start, end);
1760 
1761  g.reset_tag(GraphTag::MIN_PATH);
1762 
1763  path.for_each([](Node<GT> * ptr_node, Arc<GT> * ptr_arc)
1764  {
1765  ptr_node->visit(GraphTag::MIN_PATH);
1766 
1767  if (ptr_arc != nullptr)
1768  ptr_arc->visit(GraphTag::MIN_PATH);
1769  });
1770  }
1771  };
1772 
1773  template <class GT, class Distance, class Heuristic, class Cmp, class Plus>
1775  build_partial_min_path_tree(const GT & g, Node<GT> * start, Node<GT> * end)
1776  {
1777  g.reset_tag(TAG);
1778  allocate_node_info<GT, Distance>(g);
1779  allocate_arc_info<GT, Distance>(g);
1780 
1781  GT tree;
1782 
1783  start->visit(TAG);
1784  ACC<GT, Distance>(start) = Distance::ZERO;
1785  TREE_NODE<GT, Distance>(start) = tree.insert_node(start->get_info());
1786  TREE_NODE<GT, Distance>(start)->cookie() = start;
1787 
1788  GetPot<GT, Distance> get_pot;
1789  ArcHeapCmp<GT, GetPot<GT, Distance>, Cmp> arc_heap_cmp(get_pot, cmp);
1790  PotHeap heap(arc_heap_cmp);
1791 
1792  for (AdArcIt<GT> it(g, start); it.has_current(); it.next())
1793  {
1794  Arc<GT> * arc = *it;
1795  POT<GT, Distance>(arc) = plus(distance(arc),
1796  heuristic(it.get_tgt_node(), end));
1797  arc->visit(TAG);
1798  put_in_heap<GT, Distance>(arc, arc->get_connected_node(start), heap);
1799  }
1800 
1801  while (not heap.is_empty() and tree.get_num_nodes() < g.get_num_nodes())
1802  {
1803  Arc<GT> * g_arc = get_from_heap<GT, Distance>(heap);
1804  Node<GT> * g_src = g_arc->get_src_node();
1805  Node<GT> * g_tgt = g_arc->get_tgt_node();
1806 
1807  if (g_src->is_visited(TAG) and g_tgt->is_visited(TAG))
1808  continue;
1809 
1810  Node<GT> * new_node = g_src->is_visited(TAG) ? g_tgt : g_src;
1811 
1812  Node<GT> * t_tgt = tree.insert_node(new_node->get_info());
1813 
1814  TREE_NODE<GT, Distance>(new_node) = t_tgt;
1815 
1816  new_node->visit(TAG);
1817 
1818  Arc<GT> * t_arc = tree.insert_arc(TREE_NODE<GT, Distance>(g_src),
1819  TREE_NODE<GT, Distance>(g_tgt),
1820  g_arc->get_info());
1821 
1822  TREE_ARC<GT, Distance>(g_arc) = t_arc;
1823 
1824  if (new_node == end)
1825  break;
1826 
1827  ACC<GT, Distance>(new_node) = POT<GT, Distance>(g_arc);
1828 
1829  const DistanceType & acc = ACC<GT, Distance>(new_node);
1830 
1831  for (AdArcIt<GT> it(g, new_node); it.has_current(); it.next())
1832  {
1833  Arc<GT> * arc = *it;
1834 
1835  if (arc->is_visited(TAG))
1836  continue;
1837 
1838  arc->visit(TAG);
1839 
1840  Node<GT> * tgt = it.get_tgt_node();
1841 
1842  if (tgt->is_visited(TAG))
1843  continue;
1844 
1845  POT<GT, Distance>(arc) = plus(plus(acc, distance(arc)),
1846  heuristic(it.get_tgt_node(), end));
1847 
1848  put_in_heap<GT, Distance>(arc, tgt, heap);
1849  }
1850  }
1851 
1852  heap.clear();
1853  destroy_node_info<GT, Distance>(g);
1854  destroy_arc_info<GT, Distance>(g);
1855 
1856  return tree;
1857  }
1858 
1859  template <class GT,
1860  class Distance = DefaultDistance<GT>,
1861  class Cmp = std::less<typename Distance::Type>,
1862  class Plus = std::plus<typename Distance::Type>>
1864  {
1865  using NodeType = Node<GT>;
1866  using ArcType = Arc<GT>;
1867 
1868  Distance & distance;
1869  Cmp & cmp;
1870  Plus & plus;
1871 
1872  struct BFNodeInfo
1873  {
1874  nat_t idx;
1875  typename Distance::Type accum;
1876  };
1877 
1878  static BFNodeInfo *& BFNI(Node<GT> * p)
1879  {
1880  return (BFNodeInfo *&) p->cookie();
1881  }
1882 
1883  static typename Distance::Type & ACC(Node<GT> * p)
1884  {
1885  return BFNI(p)->accum;
1886  }
1887 
1888  static nat_t & IDX(Node<GT> * p)
1889  {
1890  return BFNI(p)->idx;
1891  }
1892 
1893  static void init_node_info(const GT & g,
1894  FixedArray<Node<GT> *> & pred,
1895  FixedArray<Arc<GT> *> & arcs)
1896  {
1897  nat_t i = 0;
1898 
1899  g.for_each_node([&] (Node<GT> * p)
1900  {
1901  pred[i] = nullptr;
1902  arcs[i] = nullptr;
1903  BFNI(p) = new BFNodeInfo;
1904  IDX(p) = i;
1905  ACC(p) = Distance::MAX;
1906  ++i;
1907  });
1908  }
1909 
1910  static void destroy_node_info(const GT & g)
1911  {
1912  g.for_each_node([] (Node<GT> * p)
1913  {
1914  delete BFNI(p);
1915  BFNI(p) = nullptr;
1916  });
1917  }
1918 
1919  bool relax(Arc<GT> * a, FixedArray<Node<GT> *> & pred,
1920  FixedArray<Arc<GT> *> & arcs)
1921  {
1922  Node<GT> * s = a->get_src_node();
1923  Node<GT> * t = a->get_tgt_node();
1924 
1925  if (ACC(s) == Distance::MAX)
1926  return false;
1927 
1928  typename Distance::Type sum = plus(ACC(s), distance(a));
1929 
1930  if (cmp(sum, ACC(t)))
1931  {
1932  const nat_t & i = IDX(t);
1933  pred[i] = s;
1934  arcs[i] = a;
1935  ACC(t) = sum;
1936  return true;
1937  }
1938 
1939  return false;
1940  }
1941 
1942  bool generic_algorithm(const GT &, FixedArray<Node<GT> *> &,
1943  FixedArray<Arc<GT> *> &);
1944 
1945  public:
1946  BellmanFord(Distance & _distance, Cmp & _cmp, Plus & _plus)
1947  : distance(_distance), cmp(_cmp), plus(_plus)
1948  {
1949  // empty
1950  }
1951 
1952  BellmanFord(Distance && _distance = Distance(), Cmp && _cmp = Cmp(),
1953  Plus && _plus = Plus())
1954  : distance(_distance), cmp(_cmp), plus(_plus)
1955  {
1956  // empty
1957  }
1958 
1959  std::tuple<bool, GT> build_min_path_tree(const GT &, Node<GT> *);
1960 
1961  bool paint_min_path_tree(const GT & g, Node<GT> * start)
1962  {
1963  auto t = build_min_path_tree(g, start);
1964 
1965  if (not std::get<0>(t))
1966  return false;
1967 
1968  g.reset_tag(GraphTag::MIN_SPANNING_TREE);
1969 
1970  const GT & tree = std::get<1>(t);
1971 
1972  tree.for_each_node([] (Node<GT> * t_node)
1973  {
1974  Node<GT> * ptr_g_node = mapped_node<GT>(t_node);
1975  ptr_g_node->visit(GraphTag::MIN_SPANNING_TREE);
1976  ptr_g_node->cookie() = nullptr;
1977  });
1978 
1979  tree.for_each_arc([](Arc<GT> * t_arc)
1980  {
1981  Arc<GT> * ptr_g_arc = mapped_arc<GT>(t_arc);
1982  ptr_g_arc->visit(GraphTag::MIN_SPANNING_TREE);
1983  ptr_g_arc->cookie() = nullptr;
1984  });
1985  return true;
1986  }
1987 
1988  std::tuple<bool, Path<GT>> search_min_path(const GT & g, Node<GT> * start,
1989  Node<GT> * end)
1990  {
1991  auto t = build_min_path_tree(g, start, end);
1992 
1993  if (not std::get<0>(t))
1994  return make_tuple(false, Path<GT>());
1995 
1996  const GT & tree = std::get<1>(t);
1997 
1998  Node<GT> * t_start = mapped_node<GT>(start);
1999  Node<GT> * t_end = mapped_node<GT>(end);
2000 
2001  Path<GT> t_path = depth_first_search_path(tree, t_start, t_end);
2002  Path<GT> path(g);
2003 
2004  if (t_path.is_empty())
2005  return path;
2006 
2007  path.init(start);
2008 
2009  t_path.for_each([&](Node<GT> *, Arc<GT> * ptr_arc)
2010  {
2011  if (ptr_arc == nullptr)
2012  return;
2013 
2014  Arc<GT> * arc = mapped_arc<GT>(ptr_arc);
2015  path.append(arc);
2016  });
2017 
2018  return make_tuple(true, path);
2019  }
2020 
2021  bool paint_min_path(const GT & g, Node<GT> * start, Node<GT> * end)
2022  {
2023  auto t = search_min_path(g, start, end);
2024 
2025  if (not std::get<0>(t))
2026  return false;
2027 
2028  Path<GT> & path = std::get<1>(t);
2029 
2030  g.reset_tag(GraphTag::MIN_PATH);
2031 
2032  path.for_each([](Node<GT> * ptr_node, Arc<GT> * ptr_arc)
2033  {
2034  ptr_node->visit(GraphTag::MIN_PATH);
2035 
2036  if (ptr_arc != nullptr)
2037  ptr_arc->visit(GraphTag::MIN_PATH);
2038  });
2039 
2040  return true;
2041  }
2042 
2043  };
2044 
2045  template <class GT, class Distance, class Cmp, class Plus>
2047  generic_algorithm(const GT & g, FixedArray<Node<GT> *> & pred,
2048  FixedArray<Arc<GT> *> & arcs)
2049  {
2050  nat_t n = g.get_num_nodes() - 1;
2051 
2052  bool had_relaxation = true;
2053 
2054  nat_t i;
2055 
2056  for (i = 0; had_relaxation and i < n; ++i)
2057  {
2058  had_relaxation = false;
2059 
2060  g.for_each_arc([&] (Arc<GT> * a)
2061  {
2062  if (relax(a, pred, arcs))
2063  had_relaxation = true;
2064  });
2065  }
2066 
2067  if (i < n)
2068  return true;
2069 
2070  had_relaxation = false;
2071 
2072  g.for_each_arc([&] (Arc<GT> * a)
2073  {
2074  if (relax(a, pred, arcs))
2075  had_relaxation = true;
2076  });
2077 
2078  return not had_relaxation;
2079  }
2080 
2081  template <class GT, class Distance, class Cmp, class Plus>
2082  std::tuple<bool, GT> BellmanFord<GT, Distance, Cmp, Plus>::
2083  build_min_path_tree(const GT & g, Node<GT> * start)
2084  {
2085  if (not g.is_digraph())
2086  throw std::domain_error("Argument must be a directed graph");
2087 
2088  FixedArray<Node<GT> *> pred(g.get_num_nodes());
2089  FixedArray<Arc<GT> *> arcs(g.get_num_nodes());
2090 
2091  init_node_info(g, pred, arcs);
2092 
2093  ACC(start) = Distance::ZERO;
2094  bool result = generic_algorithm(g, pred, arcs);
2095 
2096  destroy_node_info(g);
2097 
2098  if (not result)
2099  return std::make_tuple(false, GT());
2100 
2101  GT tree;
2102 
2103  for (nat_t i = 0; i < arcs.size(); ++i)
2104  {
2105  Arc<GT> * a = arcs[i];
2106 
2107  if (a == nullptr)
2108  continue;
2109 
2110  Node<GT> * s = a->get_src_node();
2111 
2112  Node<GT> * st = mapped_node<GT>(s);
2113 
2114  if (st == nullptr)
2115  {
2116  st = tree.insert_node(s->get_info());
2117  map_nodes<GT>(s, st);
2118  }
2119 
2120  Node<GT> * t = a->get_tgt_node();
2121 
2122  Node<GT> * tt = mapped_node<GT>(t);
2123 
2124  if (tt == nullptr)
2125  {
2126  tt = tree.insert_node(t->get_info());
2127  map_nodes<GT>(t, tt);
2128  }
2129 
2130  Arc<GT> * at = tree.insert_arc(st, tt, a->get_info());
2131  map_arcs<GT>(a, at);
2132  }
2133 
2134  return std::make_tuple(true, std::move(tree));
2135  }
2136 
2137  template <class GT>
2139  {
2140  using NodeType = Node<GT>;
2141  using ArcType = Arc<GT>;
2142  using MNodeInfo = SLList<Node<GT> *>;
2143  using MArcInfo = Arc<GT> *;
2145  using MNode = Node<MGraph>;
2146  using MArc = Arc<MGraph>;
2147  using ArcSet = TreeSet<MArc *>;
2148 
2149  static constexpr real_t SQ_TWO = 1.414213562;
2150 
2151  rng_t rng;
2152 
2153  nat_t num_iterations_hint(nat_t n)
2154  {
2155  return n * n * std::log10(n);
2156  }
2157 
2158  MGraph build_mgraph(const GT & g)
2159  {
2160  g.reset_nodes();
2161  g.reset_arcs();
2162 
2163  MGraph mg;
2164 
2165  g.for_each_node([&] (Node<GT> * p)
2166  {
2167  MNode * mp = mg.insert_node();
2168  mp->get_info().append(p);
2169  map_nodes<GT, MGraph>(p, mp);
2170  });
2171 
2172  g.for_each_arc([&] (Arc<GT> * a)
2173  {
2174  Node<GT> * p = a->get_src_node();
2175  Node<GT> * q = a->get_tgt_node();
2176 
2177  MNode * mp = mapped_node<GT, MGraph>(p);
2178  MNode * mq = mapped_node<GT, MGraph>(q);
2179 
2180  mg.insert_arc(mp, mq, a);
2181  });
2182 
2183  return mg;
2184  }
2185 
2186  ArcSet build_arcs(MGraph & mg)
2187  {
2188  ArcSet ret;
2189  mg.for_each_arc([&] (MArc * a) { ret.insert(a); });
2190  return ret;
2191  }
2192 
2193  void contract_arc(MGraph &, MNode *, MNode *, MNode *, ArcSet &);
2194 
2195  void contract(MGraph &, ArcSet &, nat_t);
2196 
2197  std::tuple<SLList<Node<GT> *>, SLList<Node<GT> *>, SLList<Arc<GT> *>>
2198  compute_min_cut(MGraph &, nat_t);
2199 
2200  std::tuple<SLList<Node<GT> *>, SLList<Node<GT> *>, SLList<Arc<GT> *>>
2201  compute_min_cut(MGraph & mg)
2202  {
2203  return compute_min_cut(mg, num_iterations_hint(mg.get_num_nodes()));
2204  }
2205 
2206  std::tuple<SLList<Node<GT> *>, SLList<Node<GT> *>, SLList<Arc<GT> *>>
2207  compute_min_cut_fast_rec(MGraph &);
2208 
2209  public:
2211  : rng(seed)
2212  {
2213  // empty
2214  }
2215 
2218  {
2219  // empty
2220  }
2221 
2222  std::tuple<SLList<Node<GT> *>, SLList<Node<GT> *>, SLList<Arc<GT> *>>
2223  compute_min_cut(const GT & g, nat_t num_it)
2224  {
2225  if (g.get_num_arcs() == 0)
2226  throw std::domain_error("Graph has not arcs");
2227 
2228  MGraph mg = build_mgraph(g);
2229  return compute_min_cut(mg, num_it);
2230  }
2231 
2232  std::tuple<SLList<Node<GT> *>, SLList<Node<GT> *>, SLList<Arc<GT> *>>
2233  compute_min_cut(const GT & g)
2234  {
2235  return compute_min_cut(g, num_iterations_hint(g.get_num_nodes()));
2236  }
2237 
2238  std::tuple<SLList<Node<GT> *>, SLList<Node<GT> *>, SLList<Arc<GT> *>>
2239  compute_min_cut_fast(const GT & g)
2240  {
2241  MGraph mg = build_mgraph(g);
2242  return compute_min_cut_fast_rec(mg);
2243  }
2244 
2245  std::tuple<SLList<Node<GT> *>, SLList<Node<GT> *>, SLList<Arc<GT> *>>
2246  operator () (const GT & g)
2247  {
2248  return compute_min_cut_fast(g);
2249  }
2250  };
2251 
2252  template <class GT>
2253  void KargerMinCut<GT>::contract_arc(MGraph & mg, MNode * p, MNode * q,
2254  MNode * r, ArcSet & arcs)
2255  {
2256  for (AdArcIt<MGraph> it(mg, p); it.has_current(); it.next())
2257  {
2258  MArc * a = it.get_current();
2259  MNode * t = it.get_tgt_node();
2260 
2261  arcs.remove(a);
2262 
2263  if (t == q)
2264  continue;
2265 
2266  MArc * aa = mg.insert_arc(t, r, a->get_info());
2267  arcs.insert(aa);
2268  }
2269  }
2270 
2271  template <class GT>
2272  void KargerMinCut<GT>::contract(MGraph & mg, ArcSet & arcs, nat_t limit)
2273  {
2274  while (mg.get_num_nodes() > limit)
2275  {
2276  auto i = random_uniform(rng, arcs.size());
2277  MArc * ma = arcs.select(i);
2278  arcs.remove(ma);
2279 
2280  MNode * x = ma->get_src_node();
2281  MNode * y = ma->get_tgt_node();
2282 
2283  MNode * z = mg.insert_node();
2284  z->get_info().swap(x->get_info());
2285  z->get_info().concat(y->get_info());
2286 
2287  contract_arc(mg, x, y, z, arcs);
2288  contract_arc(mg, y, x, z, arcs);
2289 
2290  mg.remove_node(x);
2291  mg.remove_node(y);
2292  }
2293  }
2294 
2295  template <class GT>
2296  std::tuple<SLList<Node<GT> *>, SLList<Node<GT> *>, SLList<Arc<GT> *>>
2298  {
2299  nat_t min_cut = std::numeric_limits<nat_t>::max();
2300 
2301  SLList<Node<GT> *> ss;
2302  SLList<Node<GT> *> ts;
2303  SLList<Arc<GT> *> cut;
2304 
2305  for (int i = 0; i < num_it; ++i)
2306  {
2307  MGraph mg(_mg);
2308  ArcSet arcs = build_arcs(mg);
2309 
2310  contract(mg, arcs, 2);
2311 
2312  assert(mg.get_num_nodes() == 2);
2313 
2314  nat_t cut_size = mg.get_num_arcs();
2315 
2316  if (cut_size >= min_cut)
2317  continue;
2318 
2319  SLList<Arc<GT> *> tmp_cut;
2320 
2321  for (ArcIt<MGraph> it(mg); it.has_current(); it.next())
2322  tmp_cut.append(it.get_current()->get_info());
2323 
2324  cut.swap(tmp_cut);
2325 
2326  MArc * first_arc = mg.get_first_arc();
2327 
2328  MNode * src = first_arc->get_src_node();
2329  ss.swap(src->get_info());
2330 
2331  MNode * tgt = first_arc->get_tgt_node();
2332  ts.swap(tgt->get_info());
2333  }
2334 
2335  return std::make_tuple(std::move(ss), std::move(ts), std::move(cut));
2336  }
2337 
2338  template <class GT>
2339  std::tuple<SLList<Node<GT> *>, SLList<Node<GT> *>, SLList<Arc<GT> *>>
2341  {
2342  nat_t n = mg.get_num_nodes();
2343 
2344  if (n <= 6)
2345  return compute_min_cut(mg);
2346 
2347  nat_t t = std::ceil(1 + real_t(n) / SQ_TWO);
2348 
2349  MGraph h1(mg);
2350  ArcSet arcs1 = build_arcs(h1);
2351  contract(h1, arcs1, t);
2352  auto r1 = compute_min_cut_fast_rec(h1);
2353 
2354  MGraph h2(mg);
2355  ArcSet arcs2 = build_arcs(h2);
2356  contract(h2, arcs2, t);
2357  auto r2 = compute_min_cut_fast_rec(h2);
2358 
2359  if (std::get<2>(r1).size() < std::get<2>(r2).size())
2360  return r1;
2361 
2362  return r2;
2363  }
2364 
2365  template <class GT,
2366  class NodeOutput = DftNodeOutput<GT>,
2367  class ArcOutput = DftArcOutput<GT>,
2368  class GraphOutput = DftGraphOutput<GT>>
2370  {
2371  NodeOutput & node_out;
2372  ArcOutput & arc_out;
2373  GraphOutput & graph_out;
2374 
2375  using Sz = typename GT::SetSizeType;
2376 
2377  public:
2378  OutputGraph(NodeOutput & _node_out, ArcOutput & _arc_out,
2379  GraphOutput & _graph_out)
2380  : node_out(_node_out), arc_out(_arc_out), graph_out(_graph_out)
2381  {
2382  // empty
2383  }
2384 
2385  OutputGraph(NodeOutput && _node_out = NodeOutput(),
2386  ArcOutput && _arc_out = ArcOutput(),
2387  GraphOutput && _graph_out = GraphOutput())
2388  : node_out(_node_out), arc_out(_arc_out), graph_out(_graph_out)
2389  {
2390  // empty
2391  }
2392 
2393  void write_in_text_mode(const GT &, std::ostream &);
2394 
2395  void write_in_bin_mode(const GT &, std::ofstream &);
2396 
2397  void operator () (const GT & g, std::ostream & out)
2398  {
2399  write_in_text_mode(g, out);
2400  }
2401 
2402  void operator () (const GT & g, std::ofstream & out)
2403  {
2404  write_in_bin_mode(g, out);
2405  }
2406  };
2407 
2408  template <class GT, class NodeOutput, class ArcOutput, class GraphOutput>
2410  write_in_text_mode(const GT & g, std::ostream & out)
2411  {
2412  if (g.is_digraph())
2413  out << "di";
2414  out << "graph\n";
2415 
2416  out << g.get_num_nodes() << ' ' << g.get_num_arcs() << '\n';
2417  graph_out(out, g);
2418  out << '\n';
2419 
2420  TreeMap<Node<GT> *, Sz> map_nodes_pos;
2421 
2422  Sz i = 0;
2423 
2424  g.for_each_node([&] (Node<GT> * p)
2425  {
2426  node_out(out, p);
2427  out << '\n';
2428  map_nodes_pos[p] = i++;
2429  });
2430 
2431  g.for_each_arc([&] (const Arc<GT> * a)
2432  {
2433  Sz s = map_nodes_pos[a->get_src_node()];
2434  Sz t = map_nodes_pos[a->get_tgt_node()];
2435  out << s << ' ' << t << ' ';
2436  arc_out(out, a);
2437  out << '\n';
2438  });
2439  }
2440 
2441  template <class GT, class NodeOutput, class ArcOutput, class GraphOutput>
2443  write_in_bin_mode(const GT & g, std::ofstream & out)
2444  {
2445  bool is_d = g.is_digraph();
2446  out.write(reinterpret_cast<char *>(&is_d), sizeof(bool));
2447 
2448  Sz num_nodes = g.get_num_nodes();
2449  Sz num_arcs = g.get_num_arcs();
2450 
2451  out.write(reinterpret_cast<char *>(&num_nodes), sizeof(Sz));
2452  out.write(reinterpret_cast<char *>(&num_arcs), sizeof(Sz));
2453 
2454  graph_out(out, g);
2455 
2456  TreeMap<Node<GT> *, Sz> map_nodes_pos;
2457 
2458  Sz i = 0;
2459 
2460  g.for_each_node([&] (Node<GT> * p)
2461  {
2462  node_out(out, p);
2463  map_nodes_pos[const_cast<Node<GT> *>(p)] = i++;
2464  });
2465 
2466  g.for_each_arc([&] (Arc<GT> * a)
2467  {
2468  Sz * s = &map_nodes_pos[a->get_src_node()];
2469  Sz * t = &map_nodes_pos[a->get_tgt_node()];
2470  out.write(reinterpret_cast<char *>(s), sizeof(Sz));
2471  out.write(reinterpret_cast<char *>(t), sizeof(Sz));
2472  arc_out(out, a);
2473  });
2474  }
2475 
2476  template <class GT,
2477  class NodeInput = DftNodeInput<GT>,
2478  class ArcInput = DftArcInput<GT>,
2479  class GraphInput = DftGraphInput<GT>>
2481  {
2482  NodeInput & node_in;
2483  ArcInput & arc_in;
2484  GraphInput & graph_in;
2485 
2486  using Sz = typename GT::SetSizeType;
2487 
2488  public:
2489  InputGraph(NodeInput & _node_in, ArcInput & _arc_in, GraphInput & _graph_in)
2490  : node_in(_node_in), arc_in(_arc_in), graph_in(_graph_in)
2491  {
2492  // empty
2493  }
2494 
2495  InputGraph(NodeInput && _node_in = NodeInput(),
2496  ArcInput && _arc_in = ArcInput(),
2497  GraphInput && _graph_in = GraphInput())
2498  : node_in(_node_in), arc_in(_arc_in), graph_in(_graph_in)
2499  {
2500  // empty
2501  }
2502 
2503  GT read_in_text_mode(std::istream &);
2504 
2505  GT read_in_bin_mode(std::ifstream &);
2506 
2507  GT operator () (std::istream & in)
2508  {
2509  return read_in_text_mode(in);
2510  }
2511 
2512  GT operator () (std::ifstream & in)
2513  {
2514  return read_in_bin_mode(in);
2515  }
2516  };
2517 
2518  template <class GT, class NodeInput, class ArcInput, class GraphInput>
2520  read_in_text_mode(std::istream & in)
2521  {
2522  GT g;
2523 
2524  std::string type;
2525  in >> type;
2526 
2527  if (g.is_digraph() xor (type == "digraph"))
2528  throw std::logic_error("Conflict between directed and undirected graph");
2529 
2530  Sz num_nodes;
2531  Sz num_arcs;
2532 
2533  in >> num_nodes >> num_arcs;
2534  graph_in(in, g);
2535 
2536  DynArray<Node<GT> *> nodes(num_nodes, nullptr);
2537 
2538  for (Sz i = 0; i < num_nodes; ++i)
2539  {
2540  Node<GT> * p = g.insert_node();
2541  node_in(in, p);
2542  nodes[i] = p;
2543  }
2544 
2545  for (Sz i = 0; i < num_arcs; ++i)
2546  {
2547  Sz s;
2548  in >> s;
2549  Sz t;
2550  in >> t;
2551  Node<GT> * src = nodes[s];
2552  Node<GT> * tgt = nodes[t];
2553  Arc<GT> * a = g.insert_arc(src, tgt);
2554  arc_in(in, a);
2555  }
2556 
2557  return g;
2558  }
2559 
2560  template <class GT, class NodeInput, class ArcInput, class GraphInput>
2562  read_in_bin_mode(std::ifstream & in)
2563  {
2564  GT g;
2565 
2566  bool is_d;
2567  in.read(reinterpret_cast<char *>(&is_d), sizeof(bool));
2568 
2569  if (g.is_digraph() xor is_d)
2570  throw std::logic_error("Conflict between directed and undirected graph");
2571 
2572  Sz num_nodes;
2573  Sz num_arcs;
2574 
2575  in.read(reinterpret_cast<char *>(&num_nodes), sizeof(Sz));
2576  in.read(reinterpret_cast<char *>(&num_arcs), sizeof(Sz));
2577 
2578  graph_in(in, g);
2579 
2580  DynArray<Node<GT> *> nodes(num_nodes, nullptr);
2581 
2582  for (Sz i = 0; i < num_nodes; ++i)
2583  {
2584  Node<GT> * p = g.insert_node();
2585  node_in(in, p);
2586  nodes[i] = p;
2587  }
2588 
2589  for (Sz i = 0; i < num_arcs; ++i)
2590  {
2591  Sz s;
2592  in.read(reinterpret_cast<char *>(&s), sizeof(Sz));
2593  Sz t;
2594  in.read(reinterpret_cast<char *>(&t), sizeof(Sz));
2595  Node<GT> * src = nodes[s];
2596  Node<GT> * tgt = nodes[t];
2597  Arc<GT> * a = g.insert_arc(src, tgt);
2598  arc_in(in, a);
2599  }
2600 
2601  return g;
2602  }
2603 
2604  template <class GT,
2605  class NodeAttr = DftDotNodeAttr<GT>,
2606  class ArcAttr = DftDotArcAttr<GT>,
2607  class GraphAttr = DftDotGraphAttr<GT>>
2608  class DotGraph
2609  {
2610  NodeAttr & node_attr;
2611  ArcAttr & arc_attr;
2612  GraphAttr & graph_attr;
2613 
2614  using Sz = typename GT::SetSizeType;
2615 
2616  public:
2617  DotGraph(NodeAttr & _node_attr, ArcAttr & _arc_attr,
2618  GraphAttr & _graph_attr)
2619  : node_attr(_node_attr), arc_attr(_arc_attr), graph_attr(_graph_attr)
2620  {
2621  // empty
2622  }
2623 
2624  DotGraph(NodeAttr && _node_attr = NodeAttr(),
2625  ArcAttr && _arc_attr = ArcAttr(),
2626  GraphAttr && _graph_attr = GraphAttr())
2627  : node_attr(_node_attr), arc_attr(_arc_attr), graph_attr(_graph_attr)
2628  {
2629  // empty
2630  }
2631 
2632  void write_graph(const GT &, std::ofstream &,
2633  const std::string & rankdir = "LR");
2634 
2635  void write_graph(const GT & g, const std::string & file_name)
2636  {
2637  std::ofstream file(file_name.c_str());
2638  write_graph(g, file);
2639  file.close();
2640  }
2641  };
2642 
2643  template <class GT, class NodeAttr, class ArcAttr, class GraphAttr>
2645  write_graph(const GT & g, std::ofstream & output, const std::string & rankdir)
2646  {
2647  output << "// "
2648  << "File generated automatically by write_graph in DotGraph"
2649  << "\n\n";
2650 
2651  if (g.is_digraph())
2652  output << "di";
2653 
2654  output << "graph\n"
2655  << "{\n";
2656 
2657  output << " rankdir = " << rankdir << ";\n\n";
2658 
2659  output << graph_attr(g) << "\n\n";
2660 
2661  output << " // Nodes \n\n";
2662 
2663  TreeMap<Node<GT> *, Sz> map;
2664 
2665  const std::string arc_connector = g.is_digraph() ? "->" : "--";
2666 
2667  Sz i = 0;
2668 
2669  g.for_each_node([&](Node<GT> * node)
2670  {
2671  output << " " << i << "[" << node_attr(node) << "];\n";
2672  map[node] = i;
2673  ++i;
2674  });
2675 
2676  output << "\n // Arcs \n\n";
2677 
2678  g.for_each_arc([&](Arc<GT> * arc)
2679  {
2680  Node<GT> * src_node = arc->get_src_node();
2681  Node<GT> * tgt_node = arc->get_tgt_node();
2682  Sz src_index = map[src_node];
2683  Sz tgt_index = map[tgt_node];
2684 
2685  output << " "
2686  << src_index << arc_connector << tgt_index
2687  << "["
2688  << arc_attr(arc)
2689  << "];\n";
2690  });
2691 
2692  output << "}\n";
2693  }
2694 
2695 } // end namespace Designar
2696 
2697 # endif // DSGGRAPHALGORITHMS_H
Arc< GT > ArcType
Definition: graphalgorithms.H:1696
Definition: graphutilities.H:619
void paint_cut_nodes_connected_components_rec(const GT &, Node< GT > *, lint_t)
Definition: graphalgorithms.H:617
GT read_in_text_mode(std::istream &)
Definition: graphalgorithms.H:2520
DotGraph(NodeAttr &&_node_attr=NodeAttr(), ArcAttr &&_arc_attr=ArcAttr(), GraphAttr &&_graph_attr=GraphAttr())
Definition: graphalgorithms.H:2624
bool remove(const Key &k)
Definition: map.H:372
Arc< GT > ArcType
Definition: graphalgorithms.H:1113
Definition: graph.H:36
void build_subgraph_rec(const GT &, Node< GT > *, const GT &)
Definition: graphutilities.H:749
bool depth_first_search_path_rec(const GT &, Node< GT > *, Node< GT > *, Path< GT > &)
Definition: graphalgorithms.H:231
NodeInfo & get_info()
Definition: nodesdef.H:1032
void init(NodeType *start)
Definition: graphutilities.H:191
std::tuple< SLList< Node< GT > * >, SLList< Node< GT > * >, SLList< Arc< GT > * > > compute_min_cut(const GT &g, nat_t num_it)
Definition: graphalgorithms.H:2223
SLList< GT > Kosaraju_compute_strong_connected_components(const GT &)
Definition: graphalgorithms.H:825
void write_graph(const GT &, std::ofstream &, const std::string &rankdir="LR")
Definition: graphalgorithms.H:2645
Definition: graphutilities.H:733
void depth_first_traverse_prefix(const GT &, Op &op)
Definition: graphalgorithms.H:329
void clear()
Definition: heap.H:988
void paint_min_spanning_tree(const GT &g)
Definition: graphalgorithms.H:1141
Kruskal(Distance &_distance, Cmp &_cmp)
Definition: graphalgorithms.H:1125
T & append(const T &item)
Definition: list.H:265
Definition: graphalgorithms.H:1238
SLList< Node< GT > * > df_topological_sort(const GT &)
Definition: graphalgorithms.H:861
T get()
Definition: queue.H:519
typename GT::ArcIterator ArcIt
Definition: graphutilities.H:81
T random_uniform(rng_t &, T)
Definition: random.H:54
void remove_node(GNode *)
Definition: graph.H:1515
lint_t & df(Node< GT > *p)
Definition: graphutilities.H:458
void insert(ArcType *arc)
Definition: graphutilities.H:213
DistanceCmp(Distance &&d=Distance(), Cmp &&_cmp=Cmp())
Definition: graphalgorithms.H:1094
Astar(Distance &&_distance=Distance(), Heuristic &&_heuristic=Heuristic(), Cmp &&_cmp=Cmp(), Plus &&_plus=Plus())
Definition: graphalgorithms.H:1721
double real_t
Definition: types.H:51
void remove_last_node()
Definition: graphutilities.H:285
Arc< GT > * get_min_arc()
Definition: graphalgorithms.H:1268
void for_each_arc(Op &op) const
Definition: graph.H:321
GT build_min_path_tree(const GT &, Node< GT > *)
Definition: graphalgorithms.H:1597
KargerMinCut()
Definition: graphalgorithms.H:2216
Definition: graphutilities.H:717
void breadth_first_traverse(const GT &, Node< GT > *, Op &)
Definition: graphalgorithms.H:877
void paint_from_cut_node(const GT &, Node< GT > *, lint_t &)
Definition: graphalgorithms.H:644
std::tuple< bool, GT > build_min_path_tree(const GT &, Node< GT > *)
Definition: graphalgorithms.H:2083
Definition: graphalgorithms.H:2608
bool has_cycle(const GT &, Node< GT > *)
Definition: graphalgorithms.H:290
void for_each(Op &op) const
Definition: containeralgorithms.H:62
ArcHeapCmp(Distance &&_distance=Distance(), Cmp &&_cmp=Cmp())
Definition: graphalgorithms.H:1223
Definition: graphutilities.H:685
static constexpr Type MAX
Definition: graphalgorithms.H:1068
static constexpr Type ZERO
Definition: graphalgorithms.H:1067
Path< GT > search_min_path(const GT &g, Node< GT > *start, Node< GT > *end)
Definition: graphalgorithms.H:1730
bool is_graph_acyclique(const GT &, Node< GT > *)
InputGraph(NodeInput &_node_in, ArcInput &_arc_in, GraphInput &_graph_in)
Definition: graphalgorithms.H:2489
std::mt19937_64 rng_t
Definition: types.H:52
GT build_min_spanning_tree(const GT &g)
Definition: graphalgorithms.H:1318
void depth_first_traverse(const GT &g, Op &op)
Definition: graphalgorithms.H:62
Path< GT > search_min_path(const GT &g, Node< GT > *start, Node< GT > *end)
Definition: graphalgorithms.H:1468
SLList< GT > compute_connected_components(const GT &)
Definition: graphalgorithms.H:448
Dijkstra(Distance &_distance, Cmp &_cmp, Plus &_plus)
Definition: graphalgorithms.H:1432
void append(ArcType *arc)
Definition: graphutilities.H:247
SLList< SLList< Node< GT > * > > topological_ranks(const GT &)
Definition: graphalgorithms.H:1012
void write_in_text_mode(const GT &, std::ostream &)
Definition: graphalgorithms.H:2410
void depth_first_traverse_sufix_rec(const GT &, Node< GT > *, Op &)
Definition: graphalgorithms.H:206
nat_t get_num_arcs() const
Definition: graph.H:1096
bool paint_min_path(const GT &g, Node< GT > *start, Node< GT > *end)
Definition: graphalgorithms.H:2021
BellmanFord(Distance &&_distance=Distance(), Cmp &&_cmp=Cmp(), Plus &&_plus=Plus())
Definition: graphalgorithms.H:1952
Path< GT > breadth_first_search_path(const GT &g, Node< GT > *, Node< GT > *)
Definition: graphalgorithms.H:912
Arc * get_first_arc()
Definition: graph.H:1075
typename GT::AdjacentArcIterator AdArcIt
Definition: graphutilities.H:82
std::tuple< SLList< Node< GT > * >, SLList< Node< GT > * >, SLList< Arc< GT > * > > compute_min_cut_fast(const GT &g)
Definition: graphalgorithms.H:2239
Arc< GT > ArcType
Definition: graphalgorithms.H:1416
void for_each(Op &op) const
Definition: graphutilities.H:380
void Kosaraju_build_subgraph_rec(const GT &, Node< GT > *, const GT &, nat_t)
void build_cut_nodes_subgraph_rec(const GT &, Node< GT > *, const GT &, lint_t)
InputGraph(NodeInput &&_node_in=NodeInput(), ArcInput &&_arc_in=ArcInput(), GraphInput &&_graph_in=GraphInput())
Definition: graphalgorithms.H:2495
bool is_empty() const
Definition: queue.H:462
rng_t::result_type rng_seed_t
Definition: types.H:53
rng_seed_t get_random_seed()
Definition: array.H:375
Path< GT > depth_first_search_path(const GT &, Node< GT > *, Node< GT > *)
Definition: graphalgorithms.H:361
Astar(Distance &_distance, Heuristic &_heuristic, Cmp &_cmp, Plus &_plus)
Definition: graphalgorithms.H:1713
typename GT::Node Node
Definition: graphutilities.H:78
Definition: graphalgorithms.H:1082
Definition: graphalgorithms.H:1863
SLList< GT > build_cut_nodes_subgraphs(const GT &)
Definition: graphalgorithms.H:719
T & insert(const T &item)
Definition: list.H:249
void add_nodes_to_component_rec(const GT &, Node< GT > *, SLList< Node< GT > * > &)
Definition: graphalgorithms.H:473
void swap(SLList &l)
Definition: list.H:325
Definition: graphutilities.H:669
long long lint_t
Definition: types.H:49
Definition: heap.H:435
SLList< SLList< Node< GT > * > > connected_components_node_list(const GT &)
Definition: graphalgorithms.H:499
SLList< Node< GT > * > bf_topological_sort(const GT &)
Definition: graphalgorithms.H:971
std::tuple< GT, SLList< Arc< GT > * > > build_cut_graph(const GT &, const SLList< Node< GT > * > &)
Definition: graphalgorithms.H:743
OutputGraph(NodeOutput &&_node_out=NodeOutput(), ArcOutput &&_arc_out=ArcOutput(), GraphOutput &&_graph_out=GraphOutput())
Definition: graphalgorithms.H:2385
Definition: graphalgorithms.H:1109
Definition: graphalgorithms.H:1062
void paint_min_spanning_tree(const GT &g)
Definition: graphalgorithms.H:1344
Definition: italgorithms.H:33
DotGraph(NodeAttr &_node_attr, ArcAttr &_arc_attr, GraphAttr &_graph_attr)
Definition: graphalgorithms.H:2617
Node< GT > NodeType
Definition: graphalgorithms.H:1415
GraphNode * get_src_node()
Definition: nodesdef.H:1081
Definition: graphutilities.H:777
std::tuple< SLList< Node< GT > * >, SLList< Node< GT > * >, SLList< Arc< GT > * > > compute_min_cut(const GT &g)
Definition: graphalgorithms.H:2233
void insert_arc(Arc< GT > *a, Node< GT > *t)
Definition: graphalgorithms.H:1249
Prim(Distance &_distance, Cmp &_cmp)
Definition: graphalgorithms.H:1304
KargerMinCut(rng_seed_t seed)
Definition: graphalgorithms.H:2210
ArcHeapCmp(Distance &_distance, Cmp &_cmp)
Definition: graphalgorithms.H:1218
void paint_min_path(const GT &g, Node< GT > *start, Node< GT > *end)
Definition: graphalgorithms.H:1495
DistanceCmp(Distance &d, Cmp &_cmp)
Definition: graphalgorithms.H:1088
Arc * insert_arc(Node *s, Node *t)
Definition: graph.H:1119
std::tuple< SLList< GT >, GT, SLList< Arc< GT > * > > compute_cut_nodes_connected_components(const GT &, const SLList< Node< GT > * > &)
Definition: graphalgorithms.H:778
Node * insert_node()
Definition: graph.H:1101
Node< GT > NodeType
Definition: graphalgorithms.H:1292
Definition: map.H:466
Node< GT > NodeType
Definition: graphalgorithms.H:1112
Definition: array.H:182
void reset_nodes() const
Definition: graph.H:816
Definition: graphutilities.H:765
GT build_min_spanning_tree(const GT &)
Definition: graphalgorithms.H:1162
Definition: graphutilities.H:789
void paint_min_path(const GT &g, Node< GT > *start, Node< GT > *end)
Definition: graphalgorithms.H:1757
Definition: graphutilities.H:123
void destroy_node_info(const GT &g)
Definition: graphutilities.H:561
Definition: graphalgorithms.H:1289
Definition: array.H:32
Dijkstra(Distance &&_distance=Distance(), Cmp &&_cmp=Cmp(), Plus &&_plus=Plus())
Definition: graphalgorithms.H:1438
Definition: graphalgorithms.H:1692
Prim(Distance &&_distance=Distance(), Cmp &&_cmp=Cmp())
Definition: graphalgorithms.H:1310
Definition: set.H:562
void depth_first_traverse_prefix_rec(const GT &, Node< GT > *, Op &)
Definition: graphalgorithms.H:182
Arc< GT > ArcType
Definition: graphalgorithms.H:1293
void write_graph(const GT &g, const std::string &file_name)
Definition: graphalgorithms.H:2635
unsigned long int nat_t
Definition: types.H:50
Definition: graphalgorithms.H:2369
typename GT::NodeIterator NodeIt
Definition: graphutilities.H:80
bool test_cycle_rec(const GT &, Node< GT > *, bool)
Definition: graphalgorithms.H:264
void write_in_bin_mode(const GT &, std::ofstream &)
Definition: graphalgorithms.H:2443
Node< GT > NodeType
Definition: graphalgorithms.H:1695
Definition: relation.H:54
typename GT::ArcInfoType Type
Definition: graphalgorithms.H:1065
Value * search(const Key &k)
Definition: map.H:254
Definition: graphalgorithms.H:2480
GT read_in_bin_mode(std::ifstream &)
Definition: graphalgorithms.H:2562
Definition: graphalgorithms.H:1212
void join(const T &tp, const T &tq)
Definition: relation.H:103
Distance::Type & ACC(Node< GT > *p)
Definition: graphutilities.H:513
Definition: graphalgorithms.H:2138
Definition: graphalgorithms.H:1678
GraphTag
Definition: graphutilities.H:37
void for_each_node(Op &op) const
Definition: graph.H:112
void compute_cut_nodes_rec(const GT &, Node< GT > *, Arc< GT > &, SLList< Node< GT > * > &, lint_t &)
void paint_min_spanning_tree(const GT &g, Node< GT > *start)
Definition: graphalgorithms.H:1323
void paint_min_path_tree(const GT &g, Node< GT > *start)
Definition: graphalgorithms.H:1447
typename GT::Arc Arc
Definition: graphutilities.H:79
Definition: graphutilities.H:701
nat_t get_num_nodes() const
Definition: graph.H:1091
Definition: queue.H:418
SLList< Node< GT > * > compute_cut_nodes(const GT &)
Definition: graphalgorithms.H:570
std::tuple< bool, Path< GT > > search_min_path(const GT &g, Node< GT > *start, Node< GT > *end)
Definition: graphalgorithms.H:1988
bool paint_min_path_tree(const GT &g, Node< GT > *start)
Definition: graphalgorithms.H:1961
BellmanFord(Distance &_distance, Cmp &_cmp, Plus &_plus)
Definition: graphalgorithms.H:1946
OutputGraph(NodeOutput &_node_out, ArcOutput &_arc_out, GraphOutput &_graph_out)
Definition: graphalgorithms.H:2378
void depth_first_traverse_sufix(const GT &, Op &op)
Definition: graphalgorithms.H:345
GT build_min_spanning_tree(const GT &, Node< GT > *)
Definition: graphalgorithms.H:1351
T & put(const T &item)
Definition: queue.H:509
lint_t paint_cut_nodes_subgraphs(const GT &, const SLList< Node< GT > * > &)
Definition: graphalgorithms.H:670
Definition: graphalgorithms.H:1412
Kruskal(Distance &&_distance=Distance(), Cmp &&_cmp=Cmp())
Definition: graphalgorithms.H:1131
GT invert_digraph(const GT &, bool)
Type & operator()(Arc< GT > &a)
Definition: graphalgorithms.H:1070
bool is_acyclique(const GT &g, Node< GT > *start)
Definition: graphalgorithms.H:310