Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
generate_graph.H
Go to the documentation of this file.
1
2/*
3 Aleph_w
4
5 Data structures & Algorithms
6 version 2.0.0b
7 https://github.com/lrleon/Aleph-w
8
9 This file is part of Aleph-w library
10
11 Copyright (c) 2002-2026 Leandro Rabindranath Leon
12
13 Permission is hereby granted, free of charge, to any person obtaining a copy
14 of this software and associated documentation files (the "Software"), to deal
15 in the Software without restriction, including without limitation the rights
16 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
17 copies of the Software, and to permit persons to whom the Software is
18 furnished to do so, subject to the following conditions:
19
20 The above copyright notice and this permission notice shall be included in all
21 copies or substantial portions of the Software.
22
23 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
29 SOFTWARE.
30*/
31
32
98# ifndef GENERATE_GRAPH_H
99# define GENERATE_GRAPH_H
100
101# include <fstream>
102# include <tpl_dynArray.H>
103# include <tpl_sort_utils.H>
104# include <tpl_graph.H>
105# include <topological_sort.H>
106
107using namespace Aleph;
108
109namespace Aleph {
110
111
112 template <class GT, class SA> inline static
113 bool is_there_a_double_arc(const GT * g,
114 typename GT::Node * src,
115 typename GT::Node * tgt) noexcept
116 {
117 if (not g->is_digraph())
118 return false;
119
120 return search_arc<GT,SA>(*g, src, tgt) != nullptr and
121 search_arc<GT,SA>(*g, tgt, src) != nullptr;
122 }
123
124
125 template <class GT>
127 typename GT::Node * p) noexcept
128 {
129 return sequential_search(nodes, p, 0, nodes.size() - 1);
130 }
131
132
156 template <class GT,
157 class Write_Node, class Write_Arc,
158 class Shade_Node, class Shade_Arc, class SA>
159 void generate_graphpic(const GT & g,
160 const double & xdist,
161 const double & ydist,
162 std::ostream & output)
163 {
165 typename GT::Node_Iterator it(g);
166 for (int i = 0; it.has_curr(); it.next_ne(), ++i)
167 {
168 auto p = it.get_current_node_ne();
169
170 nodes[i] = p;
171
172 if (Shade_Node() (p).size() != 0)
173 output << Shade_Node() (p) << " " << i << std::endl;
174
175 const std::string text_node = Write_Node () (p);
176
177 if (text_node.size() == 0)
178 continue;
179
180 output << "NODE-TEXT " << i << " \"" << text_node << "\" 0 0" << std::endl;
181 }
182
183 for (Arc_Iterator<GT, SA> it(g); it.has_curr(); it.next_ne())
184 {
185 auto a = it.get_current_arc_ne();
186 auto src = g.get_src_node(a);
187 auto tgt = g.get_tgt_node(a);
188
189 const auto src_idx = search_node <GT> (nodes, src);
190 const auto tgt_idx = search_node <GT> (nodes, tgt);
191
192 if (is_there_a_double_arc <GT, SA> (&g, src, tgt))
193 output << "CURVE-ARC " << src_idx << " " << tgt_idx << " "
194 << xdist/5 << " L" << std::endl;
195 else
196 output << "ARC " << src_idx << " " << tgt_idx << std::endl;
197
198 if ( Shade_Arc()(a).size() != 0)
199 output << Shade_Arc()(a) << " "
200 << src_idx << " " << tgt_idx << " " << std::endl;
201
202 const std::string text_arc = Write_Arc() (a);
203
204 if (text_arc.size() == 0)
205 continue;
206
207 output << "ARC-TEXT " << src_idx << " " << tgt_idx << " \""
208 << text_arc << "\" 0 0 " << std::endl;
209 }
210 }
211
238 template <class GT,
239 class Write_Node,
240 class Write_Arc,
241 class Shade_Node,
242 class Shade_Arc,
243 class Dashed_Node,
244 class Dashed_Arc,
245 class SA,
246 class SN>
247 void generate_graphviz(const GT & g, std::ostream & output,
248 const std::string & rankdir = "TB",
249 float ranksep = 0.2,
250 float nodesep = 0.2)
251 {
252 output << "// Generated by generate_graphviz() from Aleph-w library. See at:" << std::endl
253 << "// http://webdelprofesor.ula.ve/ingenieria/lrleon/aleph/html/index.html" << std::endl
254 << "// for documentation" << std::endl
255 << "// Copyleft Leandro Rabindranath Leon lrleon@ula.ve" << std::endl
256 << "// for using of graphviz system. See at http://graphviz.org/"
257 << std::endl << std::endl;
258 std::string arc_str;
259 if (g.is_digraph())
260 {
261 arc_str = " -> ";
262 output << "digraph {" << std::endl;
263 }
264 else
265 {
266 arc_str = " -- ";
267 output << "graph {" << std::endl;
268 }
269 output << std::endl
270 << "rankdir = " << rankdir << std::endl
271 << "style = none" << std::endl
272 << "truecolor=false" << std::endl
273 << "ranksep = " << ranksep << std::endl
274 << "nodesep = " << nodesep << std::endl << std::endl;
275
277
279 for (int i = 0; it.has_curr(); it.next_ne(), ++i)
280 {
281 output << i << " [ ";
282
283 auto p = it.get_current_node_ne();
284 nodes[i] = p;
285
286 if (Shade_Node () (p))
287 output << "style = bold ";
288
289 const std::string text_node = Write_Node () (p);
290
291 if (text_node.size() != 0)
292 output << "label = \"" << text_node << "\"";
293 output << "]" << std::endl;
294 }
295
296 output << std::endl;
297
298 for (Arc_Iterator<GT, SA> it(g); it.has_curr(); it.next_ne())
299 {
300 auto a = it.get_current_arc_ne();
301 auto src = g.get_src_node(a);
302 auto tgt = g.get_tgt_node(a);
303
304 auto src_idx = search_node <GT> (nodes, src);
305 auto tgt_idx = search_node <GT> (nodes, tgt);
306
307 output << src_idx << arc_str << tgt_idx << " [";
308
309 if (Shade_Arc () (a))
310 output << "style = bold ";
311
312 const std::string text_arc = Write_Arc() (a);
313
314 if (text_arc.size() != 0)
315 output << "label = \"" << text_arc << "\"";
316 output <<"]" << std::endl;
317 }
318
319 output << "}" << std::endl;
320 }
321
322
358 template <class GT,
359 class Node_Attr,
360 class Arc_Attr,
361 class SN,
362 class SA>
363 void generate_graphviz(const GT & g, std::ostream & out,
366 const std::string & rankdir = "TB")
367 {
368 out << "// Generated by generate_graphviz() from Aleph-w library" << std::endl
369 << "// See at:"
370 << "// http://webdelprofesor.ula.ve/ingenieria/lrleon/aleph/html/index.html" << std::endl
371 << "// for documentation of Aleph-w library" << std::endl
372 << "// Copyleft Leandro Rabindranath Leon lrleon@ula.ve" << std::endl
373 << "// for using of graphviz system. See at http://graphviz.org/"
374 << std::endl << std::endl
375 << (g.is_digraph() ? "digraph {" : "graph {") << std::endl
376 << std::endl
377 << "rankdir = " << rankdir << std::endl
378 << std::endl
379 << "// Node list" << std::endl
380 << std::endl;
381
383
385 for (int i = 0; it.has_curr(); it.next_ne(), ++i)
386 {
387 auto p = it.get_current_node_ne();
388
389 nodes_table.insert(p, i);
390
391 out << i << " [ ";
392
393 node_attr (g, p, out);
394
395 out << "]" << std::endl;
396 }
397
398 out << std::endl
399 << std::endl
400 << "// Arc list" << std::endl
401 << std::endl;
402
403 const std::string arrow = g.is_digraph() ? "->" : "--";
404
405 for (Arc_Iterator<GT, SA> it(g); it.has_curr(); it.next_ne())
406 {
407 auto a = it.get_current_arc_ne();
408 auto src = g.get_src_node(a);
409 auto tgt = g.get_tgt_node(a);
410
411 const auto src_idx = nodes_table.find(src);
412 const auto tgt_idx = nodes_table.find(tgt);
413
414 out << src_idx << arrow << tgt_idx << " [";
415 arc_attr (g, a, out) ;
416 out << "]" << std::endl;
417 }
418
419 out << "}" << std::endl;
420 }
421
443 template <class GT,
444 class Node_Attr,
445 class Arc_Attr,
446 class SN,
447 class SA>
448 void digraph_graphviz(const GT & g, std::ostream & out,
451 const std::string & rankdir = "LR")
452 {
453 out << "// Generated by generate_graphviz() from Aleph-w library" << std::endl
454 << "// See at:"
455 << "// http://webdelprofesor.ula.ve/ingenieria/lrleon/aleph/html/index.html" << std::endl
456 << "// for documentation of Aleph-w library" << std::endl
457 << "// Copyleft Leandro Rabindranath Leon lrleon@ula.ve" << std::endl
458 << "// for using of graphviz system. See at http://graphviz.org/"
459 << std::endl << std::endl
460 << "digraph {" << std::endl
461 << std::endl
462 << "rankdir = " << rankdir << std::endl
463 << std::endl
464 << "// Node list" << std::endl
465 << std::endl;
466
468
470 for (int i = 0; it.has_curr(); it.next_ne(), ++i)
471 {
472 auto p = it.get_current_node_ne();
473 nodes_table.insert(p, i);
474
475 out << i << " [ ";
476
477 node_attr (g, p, out);
478
479 out << "]" << std::endl;
480 }
481
482 out << std::endl
483 << std::endl
484 << "// Arc list" << std::endl
485 << std::endl;
486
487 const std::string arrow = "->";
488
489 for (Arc_Iterator<GT, SA> it(g); it.has_curr(); it.next_ne())
490 {
491 auto a = it.get_current_arc_ne();
492 auto src = g.get_src_node(a);
493 auto tgt = g.get_tgt_node(a);
494
495 const auto src_idx = nodes_table.find(src);
496 const auto tgt_idx = nodes_table.find(tgt);
497
498 out << src_idx << arrow << tgt_idx << " [";
499 arc_attr (g, a, out) ;
500 out << "]" << std::endl;
501 }
502
503 out << "}" << std::endl;
504 }
505
531 template <class GT,
532 class Node_Attr,
533 class Arc_Attr,
534 class SN,
535 class SA>
536 size_t rank_graphviz(const GT & g, std::ostream & out,
539 const std::string & rankdir = "LR")
540 {
541 out << "// Generated by generate_graphviz() from Aleph-w library" << std::endl
542 << "// See at:"
543 << "// http://webdelprofesor.ula.ve/ingenieria/lrleon/aleph/html/index.html" << std::endl
544 << "// for documentation of Aleph-w library" << std::endl
545 << "// Copyleft Leandro Rabindranath Leon lrleon@ula.ve" << std::endl
546 << "// for using of graphviz system. See at http://graphviz.org/"
547 << std::endl << std::endl
548 << "digraph {" << std::endl
549 << std::endl
550 << "rankdir = " << rankdir << std::endl
551 << "rank = same" << std::endl
552 << std::endl
553 << "// Node list" << std::endl
554 << std::endl;
555
558 size_t rank = 0, i = 0;
559 for (auto rank_it = ranks.get_it(); rank_it.has_curr();
560 rank_it.next_ne(), ++rank)
561 {
562 out << "subgraph rank_" << rank << std::endl
563 << "{" << std::endl
564 << "label = \"rank " << rank << "\"" << std::endl;
565 for (auto it = rank_it.get_curr().get_it(); it.has_curr();
566 it.next_ne(), ++i)
567 {
568 auto p = it.get_curr();
569 nodes_table.insert(p, i);
570 out << i << " [ ";
571 node_attr(g, p, out);
572 out << "]" << std::endl;
573 }
574 out << "}" << std::endl;
575 }
576
577 out << std::endl
578 << std::endl
579 << "// Arc list" << std::endl
580 << std::endl;
581
582 const std::string arrow = "->";
583 for (Arc_Iterator<GT, SA> it(g); it.has_curr(); it.next_ne())
584 {
585 auto a = it.get_current_arc_ne();
586 auto src = g.get_src_node(a);
587 auto tgt = g.get_tgt_node(a);
588
589 const auto src_idx = nodes_table.find(src);
590 const auto tgt_idx = nodes_table.find(tgt);
591
592 out << src_idx << arrow << tgt_idx << " [";
593 arc_attr (g, a, out) ;
594 out << "]" << std::endl;
595 }
596 out << "}" << std::endl;
597
598 return rank;
599 }
600
601 template <class GT>
603 {
604 void operator () (const GT&, typename GT::Node * p, std::ostream & out)
605 {
606 out << "label = \"" << p->get_info() << "\"";
607 }
608 };
609
610 template <class GT>
612 {
613 void operator () (const GT&, typename GT::Arc * a, std::ostream & out)
614 {
615 out << "label = \"" << a->get_info() << "\"";
616 }
617 };
618
667 template <class GT,
670 class SN = Dft_Show_Node<GT>,
671 class SA = Dft_Show_Arc<GT>>
673 {
682 void operator () (const GT & g, std::ostream & out,
683 const Node_Attr & node_attr = Node_Attr(),
684 const Arc_Attr & arc_attr = Arc_Attr(),
685 const std::string & rankdir = "LR")
686 {
689 }
690
691 void digraph(const GT & g, std::ostream & out,
692 const Node_Attr & node_attr = Node_Attr(),
693 const Arc_Attr & arc_attr = Arc_Attr(),
694 const std::string & rankdir = "LR")
695 {
698 }
699
700 void ranks(const GT & g, std::ostream & out,
701 const Node_Attr & node_attr = Node_Attr(),
702 const Arc_Attr & arc_attr = Arc_Attr(),
703 const std::string & rankdir = "LR")
704 {
707 }
708 };
709
710
711
712 template <class GT>
714 {
715 bool operator () (typename GT::Node *) const { return false; }
716
717 bool operator () (typename GT::Arc *) const { return false; }
718 };
719
720
739 template <class GT,
740 class Write_Node,
741 class Write_Arc,
742 class Shade_Node = Dummy_Attr<GT>,
743 class Shade_Arc = Dummy_Attr<GT>,
745 class Dashed_Arc = Dummy_Attr<GT>,
746 class SA = Dft_Show_Arc<GT>,
747 class SN = Dft_Show_Node<GT> >
749 {
758 void operator () (GT & g, std::ostream & out,
759 const std::string & rankdir = "TB",
760 float ranksep = 0.4, float nodesep = 0.4)
761 {
764 (g, out, rankdir, ranksep, nodesep);
765 }
766 };
767
789 template <class GT,
790 class Write_Node, class Write_Arc,
791 class Shade_Node, class Shade_Arc, class SA>
793 const size_t & nodes_by_level,
794 const double & xdist,
795 const double & ydist,
796 std::ostream & out)
797 {
798 if (g.is_digraph())
799 out << "cross-net-digraph ";
800 else
801 out << "cross-net-graph ";
802
803 out << g.get_num_nodes() << " " << nodes_by_level << " "
804 << xdist << " " << ydist << std::endl
805 << std::endl;
806
808 (g, xdist, ydist, out);
809 }
810
811 template <class GT,
812 class Write_Node, class Write_Arc,
813 class Shade_Node, class Shade_Arc>
815 const size_t & nodes_by_level,
816 const double & xdist,
817 const double & ydist,
818 std::ostream & out)
819 {
820 typedef Dft_Show_Arc<GT> DSA;
823 }
824
845 template <class GT,
846 class Write_Node, class Write_Arc,
847 class Shade_Node, class Shade_Arc, class SA>
849 const size_t & nodes_by_level,
850 const double & xdist,
851 const double & ydist,
852 std::ostream & out)
853 {
854 if (g.is_digraph())
855 out << "net-digraph ";
856 else
857 out << "net-graph ";
858
859 out << g.get_num_nodes() << " " << nodes_by_level << " "
860 << xdist << " " << ydist << std::endl
861 << std::endl;
862
864 (g, xdist, ydist, out);
865 }
866
867 template <class GT,
868 class Write_Node, class Write_Arc,
869 class Shade_Node, class Shade_Arc>
871 const size_t & nodes_by_level,
872 const double & xdist,
873 const double & ydist,
874 std::ostream & out)
875 {
876 typedef Dft_Show_Arc<GT> DSA;
879
880 }
881
882 template <class GT> struct __Shade_Node
883 {
884 std::string operator () (typename GT::Node *) const
885 {
886 return "";
887 }
888 };
889
890
891 template <class GT> struct __Shade_Arc
892 {
893 std::string operator () (typename GT::Arc *) const
894 {
895 return "";
896 }
897 };
898
899
900 template <class GT, class Write_Node, class Write_Arc, class SA>
902 const size_t & nodes_by_level,
903 const double & xdist,
904 const double & ydist,
905 std::ostream & out)
906 {
910 }
911
912 template <class GT, class Write_Node, class Write_Arc, class SA>
914 const size_t & nodes_by_level,
915 const double & xdist,
916 const double & ydist,
917 std::ostream & out)
918 {
922 }
923
924
925 template <class GT, class Write_Node, class Write_Arc>
927 const size_t & nodes_by_level,
928 const double & xdist,
929 const double & ydist,
930 std::ostream & out)
931 {
932 typedef Dft_Show_Arc<GT> DSA;
936 }
937
938 template <class GT, class Write_Node, class Write_Arc>
940 const size_t & nodes_by_level,
941 const double & xdist,
942 const double & ydist,
943 std::ostream & out)
944 {
945 typedef Dft_Show_Arc<GT> DSA;
949 }
950
951
952} // end namespace Aleph
953
954
955# endif // GENERATE_GRAPH_H
Dynamic singly linked list with functional programming support.
Definition htlist.H:1423
T & insert(const T &item)
Insert a new item by copy.
Definition htlist.H:1502
Dynamic map implemented with a treap.
void next_ne() noexcept
Advances the iterator to the next filtered element (noexcept version).
size_t size() const noexcept
Count the number of elements of the list.
Definition htlist.H:1319
_Graph_Node Node
The graph type.
Definition tpl_graph.H:432
Filtered iterator on the nodes of a graph.
Definition tpl_graph.H:1206
ArcInfo & get_info() noexcept
Return a modifiable reference to the arc data.
Definition graph-dry.H:595
NodeInfo & get_info() noexcept
Return a modifiable reference to the data contained in the node.
Definition graph-dry.H:494
Node * get_src_node(Arc *arc) const noexcept
Return the source node of arc (only for directed graphs)
Definition graph-dry.H:731
constexpr size_t get_num_nodes() const noexcept
Return the total of nodes of graph.
Definition graph-dry.H:695
bool is_digraph() const noexcept
Return true if the graph this is directed.
Definition graph-dry.H:657
Node * get_tgt_node(Arc *arc) const noexcept
Return the target node of arc (only for directed graphs)
Definition graph-dry.H:737
auto get_it() const
Return a properly initialized iterator positioned at the first item on the container.
Definition ah-dry.H:190
List_Graph< Graph_Node< int >, Graph_Arc< int > > GT
DynArray< Graph::Node * > nodes
Definition graphpic.C:406
size_t rank_graphviz(const GT &g, std::ostream &out, Node_Attr node_attr=Node_Attr(), Arc_Attr arc_attr=Arc_Attr(), const std::string &rankdir="LR")
Generate Graphviz DOT output with topological ranking.
void digraph_graphviz(const GT &g, std::ostream &out, Node_Attr node_attr=Node_Attr(), Arc_Attr arc_attr=Arc_Attr(), const std::string &rankdir="LR")
Generate Graphviz DOT output specifically for digraphs.
void generate_graphpic(const GT &g, const double &xdist, const double &ydist, std::ostream &output)
Generate a graphpic specification for graph visualization.
void generate_cross_graph(GT &g, const size_t &nodes_by_level, const double &xdist, const double &ydist, std::ostream &out)
Generate a cross-graph layout specification for graphpic.
void generate_graphviz(const GT &g, std::ostream &output, const std::string &rankdir="TB", float ranksep=0.2, float nodesep=0.2)
Generate a Graphviz DOT specification for graph visualization.
void generate_net_graph(GT &g, const size_t &nodes_by_level, const double &xdist, const double &ydist, std::ostream &out)
Generate a net-graph layout specification for graphpic.
Main namespace for Aleph-w library functions.
Definition ah-arena.H:89
size_t size(Node *root) noexcept
static int search_node(DynArray< typename GT::Node * > &nodes, typename GT::Node *p) noexcept
Array< size_t > ranks(const Array< T > &array)
Computes the rank of each element in an Array.
Definition ahSort.H:524
long sequential_search(T *a, const T &x, const long l, const long r, Equal eq=Equal())
Linear search for an element in an array.
DynList< T > maps(const C &c, Op op)
Classic map operation.
static bool is_there_a_double_arc(const GT *g, typename GT::Node *src, typename GT::Node *tgt) noexcept
Filtered iterator on all the arcs of a graph.
Definition tpl_graph.H:1164
void operator()(const GT &, typename GT::Arc *a, std::ostream &out)
void operator()(const GT &, typename GT::Node *p, std::ostream &out)
Default filter for filtered iterators on arcs.
Definition tpl_graph.H:1000
Default filter for the graph nodes.
Definition tpl_graph.H:1192
bool operator()(typename GT::Node *) const
Functor for generating Graphviz specifications.
void operator()(GT &g, std::ostream &out, const std::string &rankdir="TB", float ranksep=0.4, float nodesep=0.4)
Generate DOT specification for the graph.
Arc of graph implemented with double-linked adjacency lists.
Definition tpl_graph.H:222
Functor class for generating Graphviz DOT specifications.
void operator()(const GT &g, std::ostream &out, const Node_Attr &node_attr=Node_Attr(), const Arc_Attr &arc_attr=Arc_Attr(), const std::string &rankdir="LR")
Generate DOT specification for a graph.
void ranks(const GT &g, std::ostream &out, const Node_Attr &node_attr=Node_Attr(), const Arc_Attr &arc_attr=Arc_Attr(), const std::string &rankdir="LR")
void digraph(const GT &g, std::ostream &out, const Node_Attr &node_attr=Node_Attr(), const Arc_Attr &arc_attr=Arc_Attr(), const std::string &rankdir="LR")
std::string operator()(typename GT::Arc *) const
std::string operator()(typename GT::Node *) const
Writer that outputs only the node key.
Topological sorting algorithms for directed acyclic graphs (DAGs).
Lazy and scalable dynamic array implementation.
Generic graph and digraph implementations.
Comprehensive sorting algorithms and search utilities for Aleph-w.
ofstream output
Definition writeHeap.C:213