Aleph-w  1.9
General library for algorithms and data structures
generate_graph.H
1 
2 /* Aleph-w
3 
4  / \ | | ___ _ __ | |__ __ __
5  / _ \ | |/ _ \ '_ \| '_ \ ____\ \ /\ / / Data structures & Algorithms
6  / ___ \| | __/ |_) | | | |_____\ V V / version 1.9b
7  /_/ \_\_|\___| .__/|_| |_| \_/\_/ https://github.com/lrleon/Aleph-w
8  |_|
9 
10  This file is part of Aleph-w library
11 
12  Copyright (c) 2002-2018 Leandro Rabindranath Leon & Alejandro Mujica
13 
14  This program is free software: you can redistribute it and/or modify
15  it under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  This program is distributed in the hope that it will be useful, but
20  WITHOUT ANY WARRANTY; without even the implied warranty of
21  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22  General Public License for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with this program. If not, see <https://www.gnu.org/licenses/>.
26 */
27 # ifndef GENERATE_GRAPH_H
28 # define GENERATE_GRAPH_H
29 
30 # include <fstream>
31 # include <tpl_dynArray.H>
32 # include <tpl_sort_utils.H>
33 # include <tpl_graph.H>
34 # include <topological_sort.H>
35 
36 using namespace std;
37 using namespace Aleph;
38 
39 namespace Aleph {
40 
41 
42  template <class GT, class SA> inline static
43 bool is_there_a_double_arc(const GT * g,
44  typename GT::Node * src,
45  typename GT::Node * tgt) noexcept
46 {
47  if (not g->is_digraph())
48  return false;
49 
50  return search_arc<GT,SA>(*g, src, tgt) != nullptr and
51  search_arc<GT,SA>(*g, tgt, src) != nullptr;
52 }
53 
54 
55  template <class GT>
56 static int search_node(DynArray<typename GT::Node *> & nodes,
57  typename GT::Node * p) noexcept
58 {
59  return sequential_search(nodes, p, 0, nodes.size() - 1);
60 }
61 
62 
99 template <class GT,
100  class Write_Node, class Write_Arc,
101  class Shade_Node, class Shade_Arc, class SA>
102 void generate_graphpic(const GT & g,
103  const double & xdist,
104  const double & /* ydist no usado por ahora */,
105  std::ostream & output)
106 {
108  typename GT::Node_Iterator it(g);
109  for (int i = 0; it.has_curr(); it.next_ne(), ++i)
110  {
111  auto p = it.get_current_node_ne();
112 
113  nodes[i] = p;
114 
115  if (Shade_Node() (p).size() != 0)
116  output << Shade_Node() (p) << " " << i << endl;
117 
118  const string text_node = Write_Node () (p);
119 
120  if (text_node.size() == 0)
121  continue;
122 
123  output << "NODE-TEXT " << i << " \"" << text_node << "\" 0 0" << endl;
124  }
125 
126  for (Arc_Iterator<GT, SA> it(g); it.has_curr(); it.next_ne())
127  {
128  auto a = it.get_current_arc_ne();
129  auto src = g.get_src_node(a);
130  auto tgt = g.get_tgt_node(a);
131 
132  const auto src_idx = search_node <GT> (nodes, src);
133  const auto tgt_idx = search_node <GT> (nodes, tgt);
134 
135  if (is_there_a_double_arc <GT, SA> (&g, src, tgt))
136  output << "CURVE-ARC " << src_idx << " " << tgt_idx << " "
137  << xdist/5 << " L" << endl;
138  else
139  output << "ARC " << src_idx << " " << tgt_idx << endl;
140 
141  if ( Shade_Arc()(a).size() != 0)
142  output << Shade_Arc()(a) << " "
143  << src_idx << " " << tgt_idx << " " << endl;
144 
145  const string text_arc = Write_Arc() (a);
146 
147  if (text_arc.size() == 0)
148  continue;
149 
150  output << "ARC-TEXT " << src_idx << " " << tgt_idx << " \""
151  << text_arc << "\" 0 0 " << endl;
152  }
153 }
154 
192 template <class GT,
193  class Write_Node,
194  class Write_Arc,
195  class Shade_Node,
196  class Shade_Arc,
197  class Dashed_Node,
198  class Dashed_Arc,
199  class SA,
200  class SN>
201 void generate_graphviz(const GT & g, std::ostream & output,
202  const string & rankdir = "TB",
203  float ranksep = 0.2,
204  float nodesep = 0.2)
205 {
206  output << "// Generated by generate_graphviz() from Aleph-w library. See at:" << endl
207  << "// http://webdelprofesor.ula.ve/ingenieria/lrleon/aleph/html/index.html" << endl
208  << "// for documentation" << endl
209  << "// Copyleft Leandro Rabindranath Leon lrleon@ula.ve" << endl
210  << "// for using of graphviz system. See at http://graphviz.org/"
211  << endl << endl;
212  string arc_str;
213  if (g.is_digraph())
214  {
215  arc_str = " -> ";
216  output << "digraph {" << endl;
217  }
218  else
219  {
220  arc_str = " -- ";
221  output << "graph {" << endl;
222  }
223  output << endl
224  << "rankdir = " << rankdir << endl
225  << "style = none" << endl
226  << "truecolor=false" << endl
227  << "ranksep = " << ranksep << endl
228  << "nodesep = " << nodesep << endl << endl;
229 
231 
232  Node_Iterator<GT, SN> it(g);
233  for (int i = 0; it.has_curr(); it.next_ne(), ++i)
234  {
235  output << i << " [ ";
236 
237  auto p = it.get_current_node_ne();
238  nodes[i] = p;
239 
240  if (Shade_Node () (p))
241  output << "style = bold ";
242 
243  const string text_node = Write_Node () (p);
244 
245  if (text_node.size() != 0)
246  output << "label = \"" << text_node << "\"";
247  output << "]" << endl;
248  }
249 
250  output << endl;
251 
252  for (Arc_Iterator<GT, SA> it(g); it.has_curr(); it.next_ne())
253  {
254  auto a = it.get_current_arc_ne();
255  auto src = g.get_src_node(a);
256  auto tgt = g.get_tgt_node(a);
257 
258  auto src_idx = search_node <GT> (nodes, src);
259  auto tgt_idx = search_node <GT> (nodes, tgt);
260 
261  output << src_idx << arc_str << tgt_idx << " [";
262 
263  if (Shade_Arc () (a))
264  output << "style = bold ";
265 
266  const string text_arc = Write_Arc() (a);
267 
268  if (text_arc.size() != 0)
269  output << "label = \"" << text_arc << "\"";
270  output <<"]" << endl;
271  }
272 
273  output << "}" << endl;
274 }
275 
276 
306 template <class GT,
307  class Node_Attr,
308  class Arc_Attr,
309  class SN,
310  class SA>
311 void generate_graphviz(const GT & g, std::ostream & out,
312  Node_Attr node_attr = Node_Attr(),
313  Arc_Attr arc_attr = Arc_Attr(),
314  const string & rankdir = "TB")
315 {
316  out << "// Generated by generate_graphviz() from Aleph-w library" << endl
317  << "// See at:"
318  << "// http://webdelprofesor.ula.ve/ingenieria/lrleon/aleph/html/index.html" << endl
319  << "// for documentation of Aleph-w library" << endl
320  << "// Copyleft Leandro Rabindranath Leon lrleon@ula.ve" << endl
321  << "// for using of graphviz system. See at http://graphviz.org/"
322  << endl << endl
323  << (g.is_digraph() ? "digraph {" : "graph {") << endl
324  << endl
325  << "rankdir = " << rankdir << endl
326  << endl
327  << "// Node list" << endl
328  << endl;
329 
331 
332  Node_Iterator<GT, SN> it(g);
333  for (int i = 0; it.has_curr(); it.next_ne(), ++i)
334  {
335  auto p = it.get_current_node_ne();
336 
337  nodes_table.insert(p, i);
338 
339  out << i << " [ ";
340 
341  node_attr (g, p, out);
342 
343  out << "]" << endl;
344  }
345 
346  out << endl
347  << endl
348  << "// Arc list" << endl
349  << endl;
350 
351  const string arrow = g.is_digraph() ? "->" : "--";
352 
353  for (Arc_Iterator<GT, SA> it(g); it.has_curr(); it.next_ne())
354  {
355  auto a = it.get_current_arc_ne();
356  auto src = g.get_src_node(a);
357  auto tgt = g.get_tgt_node(a);
358 
359  const auto src_idx = nodes_table.find(src);
360  const auto tgt_idx = nodes_table.find(tgt);
361 
362  out << src_idx << arrow << tgt_idx << " [";
363  arc_attr (g, a, out) ;
364  out << "]" << endl;
365  }
366 
367  out << "}" << endl;
368 }
369 
399 template <class GT,
400  class Node_Attr,
401  class Arc_Attr,
402  class SN,
403  class SA>
404 void digraph_graphviz(const GT & g, std::ostream & out,
405  Node_Attr node_attr = Node_Attr(),
406  Arc_Attr arc_attr = Arc_Attr(),
407  const string & rankdir = "LR")
408 {
409  out << "// Generated by generate_graphviz() from Aleph-w library" << endl
410  << "// See at:"
411  << "// http://webdelprofesor.ula.ve/ingenieria/lrleon/aleph/html/index.html" << endl
412  << "// for documentation of Aleph-w library" << endl
413  << "// Copyleft Leandro Rabindranath Leon lrleon@ula.ve" << endl
414  << "// for using of graphviz system. See at http://graphviz.org/"
415  << endl << endl
416  << "digraph {" << endl
417  << endl
418  << "rankdir = " << rankdir << endl
419  << endl
420  << "// Node list" << endl
421  << endl;
422 
424 
425  Node_Iterator<GT, SN> it(g);
426  for (int i = 0; it.has_curr(); it.next_ne(), ++i)
427  {
428  auto p = it.get_current_node_ne();
429  nodes_table.insert(p, i);
430 
431  out << i << " [ ";
432 
433  node_attr (g, p, out);
434 
435  out << "]" << endl;
436  }
437 
438  out << endl
439  << endl
440  << "// Arc list" << endl
441  << endl;
442 
443  const string arrow = "->";
444 
445  for (Arc_Iterator<GT, SA> it(g); it.has_curr(); it.next_ne())
446  {
447  auto a = it.get_current_arc_ne();
448  auto src = g.get_src_node(a);
449  auto tgt = g.get_tgt_node(a);
450 
451  const auto src_idx = nodes_table.find(src);
452  const auto tgt_idx = nodes_table.find(tgt);
453 
454  out << src_idx << arrow << tgt_idx << " [";
455  arc_attr (g, a, out) ;
456  out << "]" << endl;
457  }
458 
459  out << "}" << endl;
460 }
461 
491 template <class GT,
492  class Node_Attr,
493  class Arc_Attr,
494  class SN,
495  class SA>
496 size_t rank_graphviz(const GT & g, std::ostream & out,
497  Node_Attr node_attr = Node_Attr(),
498  Arc_Attr arc_attr = Arc_Attr(),
499  const string & rankdir = "LR")
500 {
501  out << "// Generated by generate_graphviz() from Aleph-w library" << endl
502  << "// See at:"
503  << "// http://webdelprofesor.ula.ve/ingenieria/lrleon/aleph/html/index.html" << endl
504  << "// for documentation of Aleph-w library" << endl
505  << "// Copyleft Leandro Rabindranath Leon lrleon@ula.ve" << endl
506  << "// for using of graphviz system. See at http://graphviz.org/"
507  << endl << endl
508  << "digraph {" << endl
509  << endl
510  << "rankdir = " << rankdir << endl
511  << "rank = same" << endl
512  << endl
513  << "// Node list" << endl
514  << endl;
515 
518  size_t rank = 0, i = 0;
519  for (auto rank_it = ranks.get_it(); rank_it.has_curr();
520  rank_it.next_ne(), ++rank)
521  {
522  out << "subgraph rank_" << rank << endl
523  << "{" << endl
524  << "label = \"rank " << rank << "\"" << endl;
525  for (auto it = rank_it.get_curr_ne().get_it(); it.has_curr();
526  it.next_ne(), ++i)
527  {
528  auto p = it.get_curr_ne();
529  nodes_table.insert(p, i);
530  out << i << " [ ";
531  node_attr(g, p, out);
532  out << "]" << endl;
533  }
534  out << "}" << endl;
535  }
536 
537  out << endl
538  << endl
539  << "// Arc list" << endl
540  << endl;
541 
542  const string arrow = "->";
543  for (Arc_Iterator<GT, SA> it(g); it.has_curr(); it.next_ne())
544  {
545  auto a = it.get_current_arc_ne();
546  auto src = g.get_src_node(a);
547  auto tgt = g.get_tgt_node(a);
548 
549  const auto src_idx = nodes_table.find(src);
550  const auto tgt_idx = nodes_table.find(tgt);
551 
552  out << src_idx << arrow << tgt_idx << " [";
553  arc_attr (g, a, out) ;
554  out << "]" << endl;
555  }
556  out << "}" << endl;
557 }
558 
559  template <class GT>
560 struct Dft_Node_Attr
561 {
562  void operator () (const GT&, typename GT::Node * p, std::ostream & out)
563  {
564  out << "label = \"" << p->get_info() << "\"";
565  }
566 };
567 
568  template <class GT>
569 struct Dft_Arc_Attr
570 {
571  void operator () (const GT&, typename GT::Arc * a, std::ostream & out)
572  {
573  out << "label = \"" << a->get_info() << "\"";
574  }
575 };
576 
625 template <class GT,
626  class Node_Attr = Dft_Node_Attr<GT>,
627  class Arc_Attr = Dft_Arc_Attr<GT>,
628  class SN = Dft_Show_Node<GT>,
629  class SA = Dft_Show_Arc<GT>>
631 {
641  void operator () (const GT & g, std::ostream & out,
642  const Node_Attr & node_attr = Node_Attr(),
643  const Arc_Attr & arc_attr = Arc_Attr(),
644  const string & rankdir = "LR")
645  {
646  generate_graphviz <GT, Node_Attr, Arc_Attr, SN, SA>
647  (g, out, node_attr, arc_attr, rankdir);
648  }
649 
650  void digraph(const GT & g, std::ostream & out,
651  const Node_Attr & node_attr = Node_Attr(),
652  const Arc_Attr & arc_attr = Arc_Attr(),
653  const string & rankdir = "LR")
654  {
655  digraph_graphviz <GT, Node_Attr, Arc_Attr, SN, SA>
656  (g, out, node_attr, arc_attr, rankdir);
657  }
658 
659  void ranks(const GT & g, std::ostream & out,
660  const Node_Attr & node_attr = Node_Attr(),
661  const Arc_Attr & arc_attr = Arc_Attr(),
662  const string & rankdir = "LR")
663  {
664  rank_graphviz <GT, Node_Attr, Arc_Attr, SN, SA>
665  (g, out, node_attr, arc_attr, rankdir);
666  }
667 };
668 
669 
670 
671  template <class GT>
672 struct Dummy_Attr
673 {
674  bool operator () (typename GT::Node *) const { return false; }
675 
676  bool operator () (typename GT::Arc *) const { return false; }
677 };
678 
679 
710 template <class GT,
711  class Write_Node,
712  class Write_Arc,
713  class Shade_Node = Dummy_Attr<GT>,
714  class Shade_Arc = Dummy_Attr<GT>,
715  class Dashed_Node = Dummy_Attr<GT>,
716  class Dashed_Arc = Dummy_Attr<GT>,
717  class SA = Dft_Show_Arc<GT>,
718  class SN = Dft_Show_Node<GT> >
720 {
730  void operator () (GT & g, std::ostream & out,
731  const string & rankdir = "TB",
732  float ranksep = 0.4, float nodesep = 0.4)
733  {
734  generate_graphviz <GT, Write_Node, Write_Arc, Shade_Node,
735  Shade_Arc, Dashed_Node, Dashed_Arc, SA, SN>
736  (g, out, rankdir, ranksep, nodesep);
737  }
738 };
739 
778  template <class GT,
779  class Write_Node, class Write_Arc,
780  class Shade_Node, class Shade_Arc, class SA>
781 void generate_cross_graph(GT & g,
782  const size_t & nodes_by_level,
783  const double & xdist,
784  const double & ydist,
785  std::ostream & out)
786 {
787  if (g.is_digraph())
788  out << "cross-net-digraph ";
789  else
790  out << "cross-net-graph ";
791 
792  out << g.get_num_nodes() << " " << nodes_by_level << " "
793  << xdist << " " << ydist << endl
794  << endl;
795 
796  generate_graphpic<GT, Write_Node, Write_Arc, Shade_Node, Shade_Arc, SA>
797  (g, xdist, ydist, out);
798 }
799 
800  template <class GT,
801  class Write_Node, class Write_Arc,
802  class Shade_Node, class Shade_Arc>
803 void generate_cross_graph(GT & g,
804  const size_t & nodes_by_level,
805  const double & xdist,
806  const double & ydist,
807  std::ostream & out)
808 {
809  typedef Dft_Show_Arc<GT> DSA;
810  generate_cross_graph<GT, Write_Node, Write_Arc, Shade_Node, Shade_Arc, DSA>
811  (g, nodes_by_level, xdist, ydist, out);
812 }
813 
852  template <class GT,
853  class Write_Node, class Write_Arc,
854  class Shade_Node, class Shade_Arc, class SA>
855 void generate_net_graph(GT & g,
856  const size_t & nodes_by_level,
857  const double & xdist,
858  const double & ydist,
859  std::ostream & out)
860 {
861  if (g.is_digraph())
862  out << "net-digraph ";
863  else
864  out << "net-graph ";
865 
866  out << g.get_num_nodes() << " " << nodes_by_level << " "
867  << xdist << " " << ydist << endl
868  << endl;
869 
870  generate_graphpic<GT, Write_Node, Write_Arc, Shade_Node, Shade_Arc, SA>
871  (g, xdist, ydist, out);
872 }
873 
874  template <class GT,
875  class Write_Node, class Write_Arc,
876  class Shade_Node, class Shade_Arc>
877 void generate_net_graph(GT & g,
878  const size_t & nodes_by_level,
879  const double & xdist,
880  const double & ydist,
881  std::ostream & out)
882 {
883  typedef Dft_Show_Arc<GT> DSA;
884  generate_net_graph<GT, Write_Node, Write_Arc, Shade_Node, Shade_Arc, DSA>
885  (g, nodes_by_level, xdist, ydist, out);
886 
887 }
888 
889 template <class GT> struct __Shade_Node
890 {
891  string operator () (typename GT::Node *) const
892  {
893  return "";
894  }
895 };
896 
897 
898 template <class GT> struct __Shade_Arc
899 {
900  string operator () (typename GT::Arc *) const
901  {
902  return "";
903  }
904 };
905 
906 
907  template <class GT, class Write_Node, class Write_Arc, class SA>
908 void generate_cross_graph(GT & g,
909  const size_t & nodes_by_level,
910  const double & xdist,
911  const double & ydist,
912  std::ostream & out)
913 {
915  <GT, Write_Node, Write_Arc, __Shade_Node<GT>, __Shade_Arc<GT>, SA>
916  (g, nodes_by_level, xdist, ydist, out);
917 }
918 
919  template <class GT, class Write_Node, class Write_Arc, class SA>
920 void generate_net_graph(GT & g,
921  const size_t & nodes_by_level,
922  const double & xdist,
923  const double & ydist,
924  std::ostream & out)
925 {
927  <GT, Write_Node, Write_Arc, __Shade_Node<GT>, __Shade_Arc<GT>, SA>
928  (g, nodes_by_level, xdist, ydist, out);
929 }
930 
931 
932  template <class GT, class Write_Node, class Write_Arc>
933 void generate_cross_graph(GT & g,
934  const size_t & nodes_by_level,
935  const double & xdist,
936  const double & ydist,
937  std::ostream & out)
938 {
939  typedef Dft_Show_Arc<GT> DSA;
941  <GT, Write_Node, Write_Arc, __Shade_Node<GT>, __Shade_Arc<GT>, DSA>
942  (g, nodes_by_level, xdist, ydist, out);
943 }
944 
945  template <class GT, class Write_Node, class Write_Arc>
946 void generate_net_graph(GT & g,
947  const size_t & nodes_by_level,
948  const double & xdist,
949  const double & ydist,
950  std::ostream & out)
951 {
952  typedef Dft_Show_Arc<GT> DSA;
954  <GT, Write_Node, Write_Arc, __Shade_Node<GT>, __Shade_Arc<GT>, DSA>
955  (g, nodes_by_level, xdist, ydist, out);
956 }
957 
958 
959 } // end namespace Aleph
960 
961 
962 # endif // GENERATE_GRAPH_H
Definition: tpl_graph.H:1225
Pair * insert(const Key &key, const Type &data)
Definition: tpl_dynMapTree.H:112
Definition: topological_sort.H:136
auto get_it() const
Definition: htlist.H:151
Definition: generate_graph.H:719
void generate_graphviz(const GT &g, std::ostream &out, Node_Attr node_attr=Node_Attr(), Arc_Attr arc_attr=Arc_Attr(), const string &rankdir="TB")
Definition: generate_graph.H:311
Definition: tpl_graph.H:1257
Definition: generate_graph.H:630
Definition: ah-comb.H:35
void generate_graphpic(const GT &g, const double &xdist, const double &, std::ostream &output)
Definition: generate_graph.H:102
Definition: tpl_graph.H:1063
size_t rank_graphviz(const GT &g, std::ostream &out, Node_Attr node_attr=Node_Attr(), Arc_Attr arc_attr=Arc_Attr(), const string &rankdir="LR")
Definition: generate_graph.H:496
Definition: tpl_dynMapTree.H:357
void generate_net_graph(GT &g, const size_t &nodes_by_level, const double &xdist, const double &ydist, std::ostream &out)
Definition: generate_graph.H:855
Definition: tpl_graph.H:1270
Definition: tpl_dynArray.H:159
Definition: ahDry.H:41
void generate_cross_graph(GT &g, const size_t &nodes_by_level, const double &xdist, const double &ydist, std::ostream &out)
Definition: generate_graph.H:781
void digraph_graphviz(const GT &g, std::ostream &out, Node_Attr node_attr=Node_Attr(), Arc_Attr arc_attr=Arc_Attr(), const string &rankdir="LR")
Definition: generate_graph.H:404
Type & find(const Key &key)
Definition: tpl_dynMapTree.H:242

Leandro Rabindranath León