lemongraph 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (161) hide show
  1. checksums.yaml +7 -0
  2. data/.yardopts +8 -0
  3. data/LICENSE +674 -0
  4. data/README.md +6 -0
  5. data/ext/lemon-1.3.1/AUTHORS +26 -0
  6. data/ext/lemon-1.3.1/CMakeLists.txt +371 -0
  7. data/ext/lemon-1.3.1/INSTALL +167 -0
  8. data/ext/lemon-1.3.1/LICENSE +32 -0
  9. data/ext/lemon-1.3.1/NEWS +337 -0
  10. data/ext/lemon-1.3.1/README +50 -0
  11. data/ext/lemon-1.3.1/cmake/FindCOIN.cmake +110 -0
  12. data/ext/lemon-1.3.1/cmake/FindGLPK.cmake +55 -0
  13. data/ext/lemon-1.3.1/cmake/FindGhostscript.cmake +10 -0
  14. data/ext/lemon-1.3.1/cmake/FindILOG.cmake +102 -0
  15. data/ext/lemon-1.3.1/cmake/FindSOPLEX.cmake +23 -0
  16. data/ext/lemon-1.3.1/cmake/LEMONConfig.cmake.in +13 -0
  17. data/ext/lemon-1.3.1/cmake/nsis/lemon.ico +0 -0
  18. data/ext/lemon-1.3.1/cmake/nsis/uninstall.ico +0 -0
  19. data/ext/lemon-1.3.1/cmake/version.cmake +1 -0
  20. data/ext/lemon-1.3.1/cmake/version.cmake.in +1 -0
  21. data/ext/lemon-1.3.1/contrib/CMakeLists.txt +19 -0
  22. data/ext/lemon-1.3.1/lemon/CMakeLists.txt +91 -0
  23. data/ext/lemon-1.3.1/lemon/adaptors.h +3638 -0
  24. data/ext/lemon-1.3.1/lemon/arg_parser.cc +474 -0
  25. data/ext/lemon-1.3.1/lemon/arg_parser.h +440 -0
  26. data/ext/lemon-1.3.1/lemon/assert.h +214 -0
  27. data/ext/lemon-1.3.1/lemon/base.cc +37 -0
  28. data/ext/lemon-1.3.1/lemon/bellman_ford.h +1116 -0
  29. data/ext/lemon-1.3.1/lemon/bfs.h +1754 -0
  30. data/ext/lemon-1.3.1/lemon/bin_heap.h +347 -0
  31. data/ext/lemon-1.3.1/lemon/binomial_heap.h +445 -0
  32. data/ext/lemon-1.3.1/lemon/bits/alteration_notifier.h +472 -0
  33. data/ext/lemon-1.3.1/lemon/bits/array_map.h +351 -0
  34. data/ext/lemon-1.3.1/lemon/bits/bezier.h +174 -0
  35. data/ext/lemon-1.3.1/lemon/bits/default_map.h +182 -0
  36. data/ext/lemon-1.3.1/lemon/bits/edge_set_extender.h +627 -0
  37. data/ext/lemon-1.3.1/lemon/bits/enable_if.h +131 -0
  38. data/ext/lemon-1.3.1/lemon/bits/graph_adaptor_extender.h +401 -0
  39. data/ext/lemon-1.3.1/lemon/bits/graph_extender.h +1332 -0
  40. data/ext/lemon-1.3.1/lemon/bits/lock.h +65 -0
  41. data/ext/lemon-1.3.1/lemon/bits/map_extender.h +332 -0
  42. data/ext/lemon-1.3.1/lemon/bits/path_dump.h +177 -0
  43. data/ext/lemon-1.3.1/lemon/bits/solver_bits.h +194 -0
  44. data/ext/lemon-1.3.1/lemon/bits/traits.h +388 -0
  45. data/ext/lemon-1.3.1/lemon/bits/variant.h +494 -0
  46. data/ext/lemon-1.3.1/lemon/bits/vector_map.h +244 -0
  47. data/ext/lemon-1.3.1/lemon/bits/windows.cc +166 -0
  48. data/ext/lemon-1.3.1/lemon/bits/windows.h +44 -0
  49. data/ext/lemon-1.3.1/lemon/bucket_heap.h +594 -0
  50. data/ext/lemon-1.3.1/lemon/capacity_scaling.h +1014 -0
  51. data/ext/lemon-1.3.1/lemon/cbc.cc +460 -0
  52. data/ext/lemon-1.3.1/lemon/cbc.h +129 -0
  53. data/ext/lemon-1.3.1/lemon/christofides_tsp.h +254 -0
  54. data/ext/lemon-1.3.1/lemon/circulation.h +807 -0
  55. data/ext/lemon-1.3.1/lemon/clp.cc +464 -0
  56. data/ext/lemon-1.3.1/lemon/clp.h +164 -0
  57. data/ext/lemon-1.3.1/lemon/color.cc +44 -0
  58. data/ext/lemon-1.3.1/lemon/color.h +204 -0
  59. data/ext/lemon-1.3.1/lemon/concept_check.h +77 -0
  60. data/ext/lemon-1.3.1/lemon/concepts/bpgraph.h +1029 -0
  61. data/ext/lemon-1.3.1/lemon/concepts/digraph.h +491 -0
  62. data/ext/lemon-1.3.1/lemon/concepts/graph.h +788 -0
  63. data/ext/lemon-1.3.1/lemon/concepts/graph_components.h +2134 -0
  64. data/ext/lemon-1.3.1/lemon/concepts/heap.h +324 -0
  65. data/ext/lemon-1.3.1/lemon/concepts/maps.h +223 -0
  66. data/ext/lemon-1.3.1/lemon/concepts/path.h +312 -0
  67. data/ext/lemon-1.3.1/lemon/config.h.in +22 -0
  68. data/ext/lemon-1.3.1/lemon/connectivity.h +1688 -0
  69. data/ext/lemon-1.3.1/lemon/core.h +2506 -0
  70. data/ext/lemon-1.3.1/lemon/cost_scaling.h +1607 -0
  71. data/ext/lemon-1.3.1/lemon/counter.h +249 -0
  72. data/ext/lemon-1.3.1/lemon/cplex.cc +994 -0
  73. data/ext/lemon-1.3.1/lemon/cplex.h +292 -0
  74. data/ext/lemon-1.3.1/lemon/cycle_canceling.h +1230 -0
  75. data/ext/lemon-1.3.1/lemon/dfs.h +1637 -0
  76. data/ext/lemon-1.3.1/lemon/dheap.h +352 -0
  77. data/ext/lemon-1.3.1/lemon/dijkstra.h +1303 -0
  78. data/ext/lemon-1.3.1/lemon/dim2.h +726 -0
  79. data/ext/lemon-1.3.1/lemon/dimacs.h +448 -0
  80. data/ext/lemon-1.3.1/lemon/edge_set.h +1420 -0
  81. data/ext/lemon-1.3.1/lemon/edmonds_karp.h +556 -0
  82. data/ext/lemon-1.3.1/lemon/elevator.h +982 -0
  83. data/ext/lemon-1.3.1/lemon/error.h +276 -0
  84. data/ext/lemon-1.3.1/lemon/euler.h +287 -0
  85. data/ext/lemon-1.3.1/lemon/fib_heap.h +475 -0
  86. data/ext/lemon-1.3.1/lemon/fractional_matching.h +2139 -0
  87. data/ext/lemon-1.3.1/lemon/full_graph.h +1082 -0
  88. data/ext/lemon-1.3.1/lemon/glpk.cc +1012 -0
  89. data/ext/lemon-1.3.1/lemon/glpk.h +263 -0
  90. data/ext/lemon-1.3.1/lemon/gomory_hu.h +568 -0
  91. data/ext/lemon-1.3.1/lemon/graph_to_eps.h +1186 -0
  92. data/ext/lemon-1.3.1/lemon/greedy_tsp.h +251 -0
  93. data/ext/lemon-1.3.1/lemon/grid_graph.h +699 -0
  94. data/ext/lemon-1.3.1/lemon/grosso_locatelli_pullan_mc.h +840 -0
  95. data/ext/lemon-1.3.1/lemon/hao_orlin.h +1015 -0
  96. data/ext/lemon-1.3.1/lemon/hartmann_orlin_mmc.h +654 -0
  97. data/ext/lemon-1.3.1/lemon/howard_mmc.h +651 -0
  98. data/ext/lemon-1.3.1/lemon/hypercube_graph.h +459 -0
  99. data/ext/lemon-1.3.1/lemon/insertion_tsp.h +533 -0
  100. data/ext/lemon-1.3.1/lemon/karp_mmc.h +590 -0
  101. data/ext/lemon-1.3.1/lemon/kruskal.h +324 -0
  102. data/ext/lemon-1.3.1/lemon/lemon.pc.in +10 -0
  103. data/ext/lemon-1.3.1/lemon/lgf_reader.h +3854 -0
  104. data/ext/lemon-1.3.1/lemon/lgf_writer.h +2687 -0
  105. data/ext/lemon-1.3.1/lemon/list_graph.h +2510 -0
  106. data/ext/lemon-1.3.1/lemon/lp.h +95 -0
  107. data/ext/lemon-1.3.1/lemon/lp_base.cc +30 -0
  108. data/ext/lemon-1.3.1/lemon/lp_base.h +2147 -0
  109. data/ext/lemon-1.3.1/lemon/lp_skeleton.cc +143 -0
  110. data/ext/lemon-1.3.1/lemon/lp_skeleton.h +234 -0
  111. data/ext/lemon-1.3.1/lemon/maps.h +4057 -0
  112. data/ext/lemon-1.3.1/lemon/matching.h +3505 -0
  113. data/ext/lemon-1.3.1/lemon/math.h +77 -0
  114. data/ext/lemon-1.3.1/lemon/max_cardinality_search.h +794 -0
  115. data/ext/lemon-1.3.1/lemon/min_cost_arborescence.h +808 -0
  116. data/ext/lemon-1.3.1/lemon/nagamochi_ibaraki.h +702 -0
  117. data/ext/lemon-1.3.1/lemon/nauty_reader.h +113 -0
  118. data/ext/lemon-1.3.1/lemon/nearest_neighbor_tsp.h +238 -0
  119. data/ext/lemon-1.3.1/lemon/network_simplex.h +1659 -0
  120. data/ext/lemon-1.3.1/lemon/opt2_tsp.h +367 -0
  121. data/ext/lemon-1.3.1/lemon/pairing_heap.h +474 -0
  122. data/ext/lemon-1.3.1/lemon/path.h +1164 -0
  123. data/ext/lemon-1.3.1/lemon/planarity.h +2754 -0
  124. data/ext/lemon-1.3.1/lemon/preflow.h +985 -0
  125. data/ext/lemon-1.3.1/lemon/quad_heap.h +343 -0
  126. data/ext/lemon-1.3.1/lemon/radix_heap.h +438 -0
  127. data/ext/lemon-1.3.1/lemon/radix_sort.h +487 -0
  128. data/ext/lemon-1.3.1/lemon/random.cc +29 -0
  129. data/ext/lemon-1.3.1/lemon/random.h +1005 -0
  130. data/ext/lemon-1.3.1/lemon/smart_graph.h +1344 -0
  131. data/ext/lemon-1.3.1/lemon/soplex.cc +465 -0
  132. data/ext/lemon-1.3.1/lemon/soplex.h +158 -0
  133. data/ext/lemon-1.3.1/lemon/static_graph.h +476 -0
  134. data/ext/lemon-1.3.1/lemon/suurballe.h +776 -0
  135. data/ext/lemon-1.3.1/lemon/time_measure.h +610 -0
  136. data/ext/lemon-1.3.1/lemon/tolerance.h +242 -0
  137. data/ext/lemon-1.3.1/lemon/unionfind.h +1824 -0
  138. data/ext/lemon-1.3.1/scripts/unify-sources.sh +390 -0
  139. data/ext/lemon-1.3.1/scripts/valgrind-wrapper.sh +22 -0
  140. data/ext/lemongraph/arc_map.cc +1007 -0
  141. data/ext/lemongraph/digraph.cc +282 -0
  142. data/ext/lemongraph/digraph_arc.cc +153 -0
  143. data/ext/lemongraph/digraph_node.cc +277 -0
  144. data/ext/lemongraph/edge_map.cc +770 -0
  145. data/ext/lemongraph/extconf.rb +53 -0
  146. data/ext/lemongraph/graph.cc +351 -0
  147. data/ext/lemongraph/graph_arc.cc +95 -0
  148. data/ext/lemongraph/graph_edge.cc +153 -0
  149. data/ext/lemongraph/graph_item.cc +76 -0
  150. data/ext/lemongraph/graph_node.cc +321 -0
  151. data/ext/lemongraph/lemongraph.cc +260 -0
  152. data/ext/lemongraph/lemongraph.hh +295 -0
  153. data/ext/lemongraph/lemongraph.map +6 -0
  154. data/ext/lemongraph/lemongraph_export.hh +31 -0
  155. data/ext/lemongraph/node_map.cc +1011 -0
  156. data/lemongraph.gemspec +176 -0
  157. data/lib/lemongraph/graphviz.rb +240 -0
  158. data/lib/lemongraph/version.rb +4 -0
  159. data/lib/lemongraph.rb +21 -0
  160. data/samples/lemondeps.rb +38 -0
  161. metadata +202 -0
@@ -0,0 +1,282 @@
1
+ /* Copyright (C) 2022 Théotime Bollengier <theotime.bollengier@ensta-bretagne.fr>
2
+ *
3
+ * This file is part of LemonGraph. <https://gitlab.ensta-bretagne.fr/bollenth/lemongraph>
4
+ *
5
+ * LemonGraph is free software: you can redistribute it and/or modify it
6
+ * under the terms of the GNU General Public License as published
7
+ * by the Free Software Foundation, either version 3 of the License,
8
+ * or (at your option) any later version.
9
+ *
10
+ * LemonGraph 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.
13
+ * See the GNU General Public License for more details.
14
+ *
15
+ * You should have received a copy of the GNU General Public License
16
+ * along with LemonGraph. If not, see <https://www.gnu.org/licenses/>. 
17
+ */
18
+
19
+
20
+ #include "lemongraph.hh"
21
+
22
+
23
+ VALUE c_Digraph;
24
+
25
+
26
+ /* Document-class: LemonGraph::Digraph
27
+ * Directed graph.
28
+ */
29
+
30
+
31
+ static void lemongraph_digraph_free(void *p)
32
+ {
33
+ lemon::ListDigraph *g = (lemon::ListDigraph*)p;
34
+ delete g;
35
+ }
36
+
37
+
38
+ static size_t lemongraph_digraph_size(const void* p)
39
+ {
40
+ return 0;
41
+ }
42
+
43
+
44
+ const rb_data_type_t lemongraph_digraph_type = {
45
+ .wrap_struct_name = "LemonGraph::Digraph",
46
+ .function = {
47
+ .dmark = NULL,
48
+ .dfree = lemongraph_digraph_free,
49
+ .dsize = lemongraph_digraph_size,
50
+ },
51
+ .parent = NULL,
52
+ .data = NULL,
53
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY
54
+ };
55
+
56
+
57
+ VALUE lemongraph_digraph_alloc(VALUE klass)
58
+ {
59
+ lemon::ListDigraph *g = new lemon::ListDigraph();
60
+ return TypedData_Wrap_Struct(klass, &lemongraph_digraph_type, g);
61
+ }
62
+
63
+
64
+ /* Adds a new node to the graph
65
+ * @return [Node] the newly created node
66
+ */
67
+ VALUE lemongraph_digraph_add_node(VALUE self)
68
+ {
69
+ lemon::ListDigraph::Node n = lemongraph_digraph_rb2ref(self).addNode();
70
+ return lemongraph_make_dinode(n, self);
71
+ }
72
+
73
+
74
+ void lemongraph_digraph_raise_if_not_valid_node(const lemon::ListDigraph& digraph, VALUE rbdigraph, VALUE node)
75
+ {
76
+ if (rb_class_of(node) != c_DiNode) {
77
+ rb_raise(rb_eTypeError, "expecting a %" PRIsVALUE ", not a %s",
78
+ rb_class_name(c_DiNode), rb_obj_classname(node));
79
+ }
80
+ if (rb_iv_get(node, "@graph") != rbdigraph)
81
+ rb_raise(rb_eRuntimeError, "this node does not belong to the graph");
82
+ if (!digraph.valid(lemongraph_rbdinode2dinode(node)))
83
+ rb_raise(rb_eRuntimeError, "node is not valid for the graph");
84
+ }
85
+
86
+
87
+ /* Adds a new arc to the graph with source node _s_ and target node _t_.
88
+ * @param s [Node] source node of the arc
89
+ * @param t [Node] target node of the arc
90
+ * @return [Arc] the newly created arc
91
+ */
92
+ VALUE lemongraph_digraph_add_arc(VALUE self, VALUE s, VALUE t)
93
+ {
94
+ lemon::ListDigraph &g = lemongraph_digraph_rb2ref(self);
95
+ lemongraph_digraph_raise_if_not_valid_node(g, self, s);
96
+ lemongraph_digraph_raise_if_not_valid_node(g, self, t);
97
+ lemon::ListDigraph::Arc a = g.addArc(
98
+ lemongraph_rbdinode2dinode(s),
99
+ lemongraph_rbdinode2dinode(t));
100
+ return lemongraph_make_diarc(a, self);
101
+ }
102
+
103
+
104
+ /* Test if the given node/arc is valid, i.e. it is a real node/arc of the graph.
105
+ * @param item [Node, Arc]
106
+ * @return [Boolean]
107
+ */
108
+ VALUE lemongraph_digraph_item_is_valid(VALUE self, VALUE item)
109
+ {
110
+ bool r = false;
111
+ VALUE klass = rb_class_of(item);
112
+ if (klass == c_DiNode) {
113
+ if (rb_iv_get(item, "@graph") == self)
114
+ r = lemongraph_digraph_rb2ref(self).valid(lemongraph_rbdinode2dinode(item));
115
+ }
116
+ else if (klass == c_DiArc) {
117
+ if (rb_iv_get(item, "@graph") == self)
118
+ r = lemongraph_digraph_rb2ref(self).valid(lemongraph_rbdiarc2diarc(item));
119
+ }
120
+ else
121
+ rb_raise(rb_eTypeError, "expecting a %" PRIsVALUE " or a %" PRIsVALUE ", not a %s",
122
+ rb_class_name(c_DiNode), rb_class_name(c_DiArc), rb_obj_classname(item));
123
+ return r ? Qtrue : Qfalse;
124
+ }
125
+
126
+
127
+ /* Erases the node or arc from the graph.
128
+ * @return [self]
129
+ * @overload erase(node)
130
+ * Erases the given node along with its outgoing and incoming arcs from the graph.
131
+ * @param node [Node] the node to erase
132
+ * @overload erase(arc)
133
+ * Erases the given arc from the graph.
134
+ * @param arc [Arc] the arc to erase
135
+ */
136
+ VALUE lemongraph_digraph_erase_nodearc(VALUE self, VALUE item)
137
+ {
138
+ VALUE klass = rb_class_of(item);
139
+ if (klass == c_DiNode) {
140
+ if (rb_iv_get(item, "@graph") != self)
141
+ rb_raise(rb_eRuntimeError, "this node does not belong to the graph");
142
+ lemongraph_digraph_rb2ref(self).erase(lemongraph_rbdinode2dinode(item));
143
+ }
144
+ else if (klass == c_DiArc) {
145
+ if (rb_iv_get(item, "@graph") != self)
146
+ rb_raise(rb_eRuntimeError, "this arc does not belong to the graph");
147
+ lemongraph_digraph_rb2ref(self).erase(lemongraph_rbdiarc2diarc(item));
148
+ }
149
+ else
150
+ rb_raise(rb_eTypeError, "expecting a %" PRIsVALUE " or a %" PRIsVALUE ", not a %s",
151
+ rb_class_name(c_DiNode), rb_class_name(c_DiArc), rb_obj_classname(item));
152
+ return self;
153
+ }
154
+
155
+
156
+ /* Erases all nodes and arcs from the graph
157
+ * @return [self]
158
+ */
159
+ VALUE lemongraph_digraph_clear(VALUE self)
160
+ {
161
+ lemongraph_digraph_rb2ref(self).clear();
162
+ return self;
163
+ }
164
+
165
+
166
+ /* Number of nodes in the graph.
167
+ * @return [Integer]
168
+ */
169
+ VALUE lemongraph_digraph_nb_nodes(VALUE self)
170
+ {
171
+ lemon::ListDigraph& g = lemongraph_digraph_rb2ref(self);
172
+ return INT2NUM(lemon::countNodes(g));
173
+ }
174
+
175
+
176
+ /* Returns an array containing all the nodes of the graph.
177
+ * @return [Array<Node>]
178
+ */
179
+ VALUE lemongraph_digraph_nodes(VALUE self)
180
+ {
181
+ lemon::ListDigraph& g = lemongraph_digraph_rb2ref(self);
182
+ VALUE a = rb_ary_new_capa(lemon::countNodes(g));
183
+ for (lemon::ListDigraph::NodeIt n(g); n != lemon::INVALID; ++n)
184
+ rb_ary_push(a, lemongraph_make_dinode(n, self));
185
+ return a;
186
+ }
187
+
188
+
189
+ static VALUE lemongraph_digraph_nodeenum_nbnodes(VALUE obj, VALUE args, VALUE eobj)
190
+ {
191
+ (void)args;
192
+ (void)eobj;
193
+ return lemongraph_digraph_nb_nodes(obj);
194
+ }
195
+
196
+
197
+ /* Calls the block, if given, once for each {Node} in the graph.
198
+ * The nodes are passed as parameters to the block.
199
+ *
200
+ * Returns _self_, or, if no block is given, an Enumerator is returned.
201
+ * @return [self, Enumerator]
202
+ * @overload each_node
203
+ * @yieldparam node [Node]
204
+ * @return [self]
205
+ * @overload each_node
206
+ * @return [Enumerator]
207
+ */
208
+ VALUE lemongraph_digraph_each_node(VALUE self)
209
+ {
210
+ RETURN_SIZED_ENUMERATOR(self, 0, 0, lemongraph_digraph_nodeenum_nbnodes);
211
+ lemon::ListDigraph& g = lemongraph_digraph_rb2ref(self);
212
+ for (lemon::ListDigraph::NodeIt n(g); n != lemon::INVALID; ++n)
213
+ rb_yield(lemongraph_make_dinode(n, self));
214
+ return self;
215
+ }
216
+
217
+
218
+ /* Number of arcs in the graph.
219
+ * @return [Integer]
220
+ */
221
+ VALUE lemongraph_digraph_nb_arcs(VALUE self)
222
+ {
223
+ lemon::ListDigraph& g = lemongraph_digraph_rb2ref(self);
224
+ return INT2NUM(lemon::countArcs(g));
225
+ }
226
+
227
+
228
+ /* Returns an array containing all the arcs of the graph.
229
+ * @return [Array<Arc>]
230
+ */
231
+ VALUE lemongraph_digraph_arcs(VALUE self)
232
+ {
233
+ lemon::ListDigraph& g = lemongraph_digraph_rb2ref(self);
234
+ VALUE ar = rb_ary_new_capa(lemon::countArcs(g));
235
+ for (lemon::ListDigraph::ArcIt a(g); a != lemon::INVALID; ++a)
236
+ rb_ary_push(ar, lemongraph_make_diarc(a, self));
237
+ return ar;
238
+ }
239
+
240
+
241
+ static VALUE lemongraph_digraph_arcenum_nbarcs(VALUE obj, VALUE args, VALUE eobj)
242
+ {
243
+ (void)args;
244
+ (void)eobj;
245
+ return lemongraph_digraph_nb_arcs(obj);
246
+ }
247
+
248
+
249
+ /* Calls the block, if given, once for each {Arc} in the graph.
250
+ * The arcs are passed as parameters to the block.
251
+ *
252
+ * Returns _self_, or, if no block is given, an Enumerator is returned.
253
+ * @return [self, Enumerator]
254
+ * @overload each_arc
255
+ * @yieldparam arc [Arc]
256
+ * @return [self]
257
+ * @overload each_arc
258
+ * @return [Enumerator]
259
+ */
260
+ VALUE lemongraph_digraph_each_arc(VALUE self)
261
+ {
262
+ RETURN_SIZED_ENUMERATOR(self, 0, 0, lemongraph_digraph_arcenum_nbarcs);
263
+ lemon::ListDigraph& g = lemongraph_digraph_rb2ref(self);
264
+ for (lemon::ListDigraph::ArcIt a(g); a != lemon::INVALID; ++a)
265
+ rb_yield(lemongraph_make_diarc(a, self));
266
+ return self;
267
+ }
268
+
269
+
270
+ /* Method called by _dup_ and _clone_ methods.
271
+ * @return [self]
272
+ */
273
+ VALUE lemongraph_digraph_initialize_copy(VALUE self, VALUE orig)
274
+ {
275
+ rb_call_super(1, &orig);
276
+ lemon::ListDigraph& from = lemongraph_digraph_rb2ref(orig);
277
+ lemon::ListDigraph& to = lemongraph_digraph_rb2ref(self);
278
+ lemon::digraphCopy(from, to).run();
279
+ return self;
280
+ }
281
+
282
+
@@ -0,0 +1,153 @@
1
+ /* Copyright (C) 2022 Théotime Bollengier <theotime.bollengier@ensta-bretagne.fr>
2
+ *
3
+ * This file is part of LemonGraph. <https://gitlab.ensta-bretagne.fr/bollenth/lemongraph>
4
+ *
5
+ * LemonGraph is free software: you can redistribute it and/or modify it
6
+ * under the terms of the GNU General Public License as published
7
+ * by the Free Software Foundation, either version 3 of the License,
8
+ * or (at your option) any later version.
9
+ *
10
+ * LemonGraph 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.
13
+ * See the GNU General Public License for more details.
14
+ *
15
+ * You should have received a copy of the GNU General Public License
16
+ * along with LemonGraph. If not, see <https://www.gnu.org/licenses/>. 
17
+ */
18
+
19
+
20
+ #include "lemongraph.hh"
21
+
22
+
23
+ VALUE c_DiArc;
24
+
25
+
26
+ /* Document-class: LemonGraph::Digraph::Arc
27
+ * Arc of a {Digraph}, from a source {Node} to a target {Node}.
28
+ */
29
+
30
+
31
+ VALUE lemongraph_make_diarc(const lemon::ListDigraph::Arc& arc, VALUE graph)
32
+ {
33
+ if (arc == lemon::INVALID)
34
+ return Qnil;
35
+ VALUE args[2] = {INT2NUM(lemon::ListDigraph::id(arc)), graph};
36
+ return rb_class_new_instance(2, args, c_DiArc);
37
+ }
38
+
39
+
40
+ /* @!visibility private
41
+ */
42
+ VALUE lemongraph_diarc_initialize(VALUE self, VALUE id, VALUE graph)
43
+ {
44
+ if (rb_obj_is_kind_of(graph, c_Digraph) != Qtrue) {
45
+ rb_raise(rb_eRuntimeError, "expecting a %" PRIsVALUE " as graph, not a %s",
46
+ rb_class_name(c_Digraph), rb_obj_classname(graph));
47
+ }
48
+ VALUE args[2] = {id, graph};
49
+ return rb_call_super(2, args);
50
+ }
51
+
52
+
53
+ /* Erases the arc from the graph it belongs to.
54
+ * @return [self]
55
+ */
56
+ VALUE lemongraph_diarc_erase(VALUE self)
57
+ {
58
+ lemongraph_digraph_rb2ref(rb_iv_get(self, "@graph")).erase(lemongraph_rbdiarc2diarc(self));
59
+ return self;
60
+ }
61
+
62
+
63
+ /* Test if the arc is valid, i.e. it is a real arc of the graph it belons to.
64
+ * @return [Boolean]
65
+ */
66
+ VALUE lemongraph_diarc_is_valid(VALUE self)
67
+ {
68
+ return lemongraph_digraph_rb2ref(rb_iv_get(self, "@graph")).valid(lemongraph_rbdiarc2diarc(self)) ? Qtrue : Qfalse;
69
+ }
70
+
71
+
72
+ /* Changes the target node of the arc a to _node_.
73
+ * @param node [Node] the arc's new target node
74
+ * @return [self]
75
+ */
76
+ VALUE lemongraph_diarc_change_target(VALUE self, VALUE node)
77
+ {
78
+ if (rb_class_of(node) != c_DiNode) {
79
+ rb_raise(rb_eTypeError, "expecting a %" PRIsVALUE ", not a %s",
80
+ rb_class_name(c_DiNode), rb_obj_classname(node));
81
+ }
82
+ VALUE graph = rb_iv_get(self, "@graph");
83
+ if (rb_iv_get(node, "@graph") != graph)
84
+ rb_raise(rb_eRuntimeError, "arc and node not from the sams graph");
85
+ lemongraph_digraph_rb2ref(graph).changeTarget(lemongraph_rbdiarc2diarc(self), lemongraph_rbdinode2dinode(node));
86
+ return self;
87
+ }
88
+
89
+
90
+ /* Changes the source node of the arc a to _node_.
91
+ * @param node [Node] the arc's new source node
92
+ * @return [self]
93
+ */
94
+ VALUE lemongraph_diarc_change_source(VALUE self, VALUE node)
95
+ {
96
+ if (rb_class_of(node) != c_DiNode) {
97
+ rb_raise(rb_eTypeError, "expecting a %" PRIsVALUE ", not a %s",
98
+ rb_class_name(c_DiNode), rb_obj_classname(node));
99
+ }
100
+ VALUE graph = rb_iv_get(self, "@graph");
101
+ if (rb_iv_get(node, "@graph") != graph)
102
+ rb_raise(rb_eRuntimeError, "arc and node not from the sams graph");
103
+ lemongraph_digraph_rb2ref(graph).changeSource(lemongraph_rbdiarc2diarc(self), lemongraph_rbdinode2dinode(node));
104
+ return self;
105
+ }
106
+
107
+
108
+ /* Returns the source node of the arc.
109
+ * @return [Node]
110
+ */
111
+ VALUE lemongraph_diarc_source(VALUE self)
112
+ {
113
+ VALUE g = rb_iv_get(self, "@graph");
114
+ lemon::ListDigraph::Node n = lemongraph_digraph_rb2ref(g).source(lemongraph_rbdiarc2diarc(self));
115
+ return lemongraph_make_dinode(n, g);
116
+ }
117
+
118
+
119
+ /* Returns the target node of the arc.
120
+ * @return [Node]
121
+ */
122
+ VALUE lemongraph_diarc_target(VALUE self)
123
+ {
124
+ VALUE g = rb_iv_get(self, "@graph");
125
+ lemon::ListDigraph::Node n = lemongraph_digraph_rb2ref(g).target(lemongraph_rbdiarc2diarc(self));
126
+ return lemongraph_make_dinode(n, g);
127
+ }
128
+
129
+
130
+ /* Reverses the direction of the given arc.
131
+ * @return [self]
132
+ */
133
+ VALUE lemongraph_diarc_reverse(VALUE self)
134
+ {
135
+ lemongraph_digraph_rb2ref(rb_iv_get(self, "@graph")).reverseArc(lemongraph_rbdiarc2diarc(self));
136
+ return self;
137
+ }
138
+
139
+
140
+ /* Splits the arc.
141
+ * First, a new node _v_ is added to the graph,
142
+ * then the target node of the original arc is set to _v_.
143
+ * Finally, an arc from _v_ to the original target is added.
144
+ * @return [Node] the newly created node
145
+ */
146
+ VALUE lemongraph_diarc_split(VALUE self)
147
+ {
148
+ VALUE g = rb_iv_get(self, "@graph");
149
+ lemon::ListDigraph::Node n = lemongraph_digraph_rb2ref(g).split(lemongraph_rbdiarc2diarc(self));
150
+ return lemongraph_make_dinode(n, g);
151
+ }
152
+
153
+
@@ -0,0 +1,277 @@
1
+ /* Copyright (C) 2022 Théotime Bollengier <theotime.bollengier@ensta-bretagne.fr>
2
+ *
3
+ * This file is part of LemonGraph. <https://gitlab.ensta-bretagne.fr/bollenth/lemongraph>
4
+ *
5
+ * LemonGraph is free software: you can redistribute it and/or modify it
6
+ * under the terms of the GNU General Public License as published
7
+ * by the Free Software Foundation, either version 3 of the License,
8
+ * or (at your option) any later version.
9
+ *
10
+ * LemonGraph 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.
13
+ * See the GNU General Public License for more details.
14
+ *
15
+ * You should have received a copy of the GNU General Public License
16
+ * along with LemonGraph. If not, see <https://www.gnu.org/licenses/>. 
17
+ */
18
+
19
+
20
+ #include "lemongraph.hh"
21
+
22
+
23
+ VALUE c_DiNode;
24
+
25
+
26
+ /* Document-class: LemonGraph::Digraph::Node
27
+ * Node of a {Digraph}.
28
+ */
29
+
30
+
31
+ VALUE lemongraph_make_dinode(const lemon::ListDigraph::Node& node, VALUE graph)
32
+ {
33
+ if (node == lemon::INVALID)
34
+ return Qnil;
35
+ VALUE args[2] = {INT2NUM(lemon::ListDigraph::id(node)), graph};
36
+ return rb_class_new_instance(2, args, c_DiNode);
37
+ }
38
+
39
+
40
+ /* @!visibility private
41
+ */
42
+ VALUE lemongraph_dinode_initialize(VALUE self, VALUE id, VALUE graph)
43
+ {
44
+ if (rb_obj_is_kind_of(graph, c_Digraph) != Qtrue) {
45
+ rb_raise(rb_eRuntimeError, "expecting a %" PRIsVALUE " as graph, not a %s",
46
+ rb_class_name(c_Digraph), rb_obj_classname(graph));
47
+ }
48
+ VALUE args[2] = {id, graph};
49
+ return rb_call_super(2, args);
50
+ }
51
+
52
+
53
+ /* Test if the node is valid, i.e. it is a real node of the graph it belongs to.
54
+ * @return [Boolean]
55
+ */
56
+ VALUE lemongraph_dinode_is_valid(VALUE self)
57
+ {
58
+ return lemongraph_digraph_rb2ref(rb_iv_get(self, "@graph")).valid(lemongraph_rbdinode2dinode(self)) ? Qtrue : Qfalse;
59
+ }
60
+
61
+
62
+ /* Erases the node from the graph it belongs to.
63
+ * @return [self]
64
+ */
65
+ VALUE lemongraph_dinode_erase(VALUE self)
66
+ {
67
+ lemongraph_digraph_rb2ref(rb_iv_get(self, "@graph")).erase(lemongraph_rbdinode2dinode(self));
68
+ return self;
69
+ }
70
+
71
+
72
+ /* Splits the node.
73
+ * First, a new node is added to the digraph,
74
+ * then the source of each outgoing arc of _self_ is moved to this new node.
75
+ * If the parameter _connect_ is _true_ (this is the default),
76
+ * then a new arc from _self_ to the newly created node is also added.
77
+ * @overload split(connect = true)
78
+ * @param connect [Boolean] whether to connect _self_ to the new node
79
+ * @return [Node] the newly created node.
80
+ */
81
+ VALUE lemongraph_dinode_split(int argc, VALUE *argv, VALUE self)
82
+ {
83
+ bool connect = true;
84
+ if (argc == 1)
85
+ connect = (argv[0] != Qnil && argv[0] != Qfalse);
86
+ else if (argc > 1)
87
+ rb_raise(rb_eArgError, "wrong number of arguments (given %d, expected 0..1)", argc);
88
+ VALUE rbgraph = rb_iv_get(self, "@graph");
89
+ lemon::ListDigraph& g = lemongraph_digraph_rb2ref(rbgraph);
90
+ lemon::ListDigraph::Node n = g.split(lemongraph_rbdinode2dinode(self), connect);
91
+ return lemongraph_make_dinode(n, rbgraph);
92
+ }
93
+
94
+
95
+ /* Contracts _self_ into the given node.
96
+ * _self_ is removed, but instead of deleting its incident arcs, they are joined to node _other_.
97
+ * If _remove_new_loops_ is _true_ (this is the default), then the newly created loops are removed.
98
+ * @return [Node] _other_ is returned, _self_ is erased
99
+ * @overload contract_in(other, remove_new_loops = true)
100
+ * @param other [Node] the node in which to contract _self_
101
+ * @param remove_new_loops [Boolean] whether or not to remove newly created loops
102
+ */
103
+ VALUE lemongraph_dinode_contract(int argc, VALUE *argv, VALUE self)
104
+ {
105
+ if (argc < 1 || argc > 2)
106
+ rb_raise(rb_eArgError, "wrong number of arguments (given %d, expected 1..2)", argc);
107
+ bool remove_new_loops = true;
108
+ VALUE other = argv[0];
109
+ if (argc == 2)
110
+ remove_new_loops = (argv[1] != Qnil && argv[1] != Qfalse);
111
+ VALUE rbg = rb_iv_get(self, "@graph");
112
+ lemon::ListDigraph &g = lemongraph_digraph_rb2ref(rbg);
113
+ lemongraph_digraph_raise_if_not_valid_node(g, rbg, self);
114
+ lemongraph_digraph_raise_if_not_valid_node(g, rbg, other);
115
+ g.contract(lemongraph_rbdinode2dinode(other), lemongraph_rbdinode2dinode(self), remove_new_loops);
116
+ return other;
117
+ }
118
+
119
+
120
+ /* Number of incoming arcs to the node.
121
+ * @return [Integer]
122
+ */
123
+ VALUE lemongraph_dinode_nb_inarcs(VALUE self)
124
+ {
125
+ VALUE rbg = rb_iv_get(self, "@graph");
126
+ lemon::ListDigraph& g = lemongraph_digraph_rb2ref(rbg);
127
+ lemon::ListDigraph::Node n = lemongraph_rbdinode2dinode(self);
128
+ return INT2NUM(lemon::countInArcs(g, n));
129
+ }
130
+
131
+
132
+ /* Returns an array containing all the incoming arcs to the node.
133
+ * @return [Array<Arc>]
134
+ */
135
+ VALUE lemongraph_dinode_inarcs(VALUE self)
136
+ {
137
+ VALUE rbg = rb_iv_get(self, "@graph");
138
+ lemon::ListDigraph& g = lemongraph_digraph_rb2ref(rbg);
139
+ lemon::ListDigraph::Node n = lemongraph_rbdinode2dinode(self);
140
+ VALUE ar = rb_ary_new_capa(lemon::countInArcs(g, n));
141
+ for (lemon::ListDigraph::InArcIt a(g, n); a != lemon::INVALID; ++a)
142
+ rb_ary_push(ar, lemongraph_make_diarc(a, rbg));
143
+ return ar;
144
+ }
145
+
146
+
147
+ static VALUE lemongraph_dinode_inarcenum_nbinarcs(VALUE obj, VALUE args, VALUE eobj)
148
+ {
149
+ (void)args;
150
+ (void)eobj;
151
+ return lemongraph_dinode_nb_inarcs(obj);
152
+ }
153
+
154
+
155
+ /* Calls the block, if given, once for each incoming {Arc} to the node.
156
+ * The arcs are passed as parameters to the block.
157
+ *
158
+ * Returns _self_, or, if no block is given, an Enumerator is returned.
159
+ * @return [self, Enumerator]
160
+ * @overload each_inarc
161
+ * @yieldparam arc [Arc]
162
+ * @return [self]
163
+ * @overload each_inarc
164
+ * @return [Enumerator]
165
+ */
166
+ VALUE lemongraph_dinode_each_inarc(VALUE self)
167
+ {
168
+ RETURN_SIZED_ENUMERATOR(self, 0, 0, lemongraph_dinode_inarcenum_nbinarcs);
169
+ VALUE rbg = rb_iv_get(self, "@graph");
170
+ lemon::ListDigraph& g = lemongraph_digraph_rb2ref(rbg);
171
+ lemon::ListDigraph::Node n = lemongraph_rbdinode2dinode(self);
172
+ for (lemon::ListDigraph::InArcIt a(g, n); a != lemon::INVALID; ++a)
173
+ rb_yield(lemongraph_make_diarc(a, rbg));
174
+ return self;
175
+ }
176
+
177
+
178
+
179
+ /* Number of outgoing arcs from the node.
180
+ * @return [Integer]
181
+ */
182
+ VALUE lemongraph_dinode_nb_outarcs(VALUE self)
183
+ {
184
+ VALUE rbg = rb_iv_get(self, "@graph");
185
+ lemon::ListDigraph& g = lemongraph_digraph_rb2ref(rbg);
186
+ lemon::ListDigraph::Node n = lemongraph_rbdinode2dinode(self);
187
+ return INT2NUM(lemon::countOutArcs(g, n));
188
+ }
189
+
190
+
191
+ /* Returns an array containing all the outgoing arcs from the node.
192
+ * @return [Array<Arc>]
193
+ */
194
+ VALUE lemongraph_dinode_outarcs(VALUE self)
195
+ {
196
+ VALUE rbg = rb_iv_get(self, "@graph");
197
+ lemon::ListDigraph& g = lemongraph_digraph_rb2ref(rbg);
198
+ lemon::ListDigraph::Node n = lemongraph_rbdinode2dinode(self);
199
+ VALUE ar = rb_ary_new_capa(lemon::countOutArcs(g, n));
200
+ for (lemon::ListDigraph::OutArcIt a(g, n); a != lemon::INVALID; ++a)
201
+ rb_ary_push(ar, lemongraph_make_diarc(a, rbg));
202
+ return ar;
203
+ }
204
+
205
+
206
+ static VALUE lemongraph_dinode_outarcenum_nboutarcs(VALUE obj, VALUE args, VALUE eobj)
207
+ {
208
+ (void)args;
209
+ (void)eobj;
210
+ return lemongraph_dinode_nb_outarcs(obj);
211
+ }
212
+
213
+
214
+ /* Calls the block, if given, once for each outgoing {Arc} from the node.
215
+ * The arcs are passed as parameters to the block.
216
+ *
217
+ * Returns _self_, or, if no block is given, an Enumerator is returned.
218
+ * @return [self, Enumerator]
219
+ * @overload each_outarc
220
+ * @yieldparam arc [Arc]
221
+ * @return [self]
222
+ * @overload each_outarc
223
+ * @return [Enumerator]
224
+ */
225
+ VALUE lemongraph_dinode_each_outarc(VALUE self)
226
+ {
227
+ RETURN_SIZED_ENUMERATOR(self, 0, 0, lemongraph_dinode_outarcenum_nboutarcs);
228
+ VALUE rbg = rb_iv_get(self, "@graph");
229
+ lemon::ListDigraph& g = lemongraph_digraph_rb2ref(rbg);
230
+ lemon::ListDigraph::Node n = lemongraph_rbdinode2dinode(self);
231
+ for (lemon::ListDigraph::OutArcIt a(g, n); a != lemon::INVALID; ++a)
232
+ rb_yield(lemongraph_make_diarc(a, rbg));
233
+ return self;
234
+ }
235
+
236
+
237
+ /* Creates an {Arc} from source _self_ to target _target_.
238
+ * @param target [Node] target node of the arc
239
+ * @return [Arc]
240
+ */
241
+ VALUE lemongraph_dinode_arc_to(VALUE self, VALUE target)
242
+ {
243
+ VALUE rbg = rb_iv_get(self, "@graph");
244
+ return lemongraph_digraph_add_arc(rbg, self, target);
245
+ }
246
+
247
+
248
+ /* Creates an {Arc} from source _source_ to target _self_.
249
+ * @param source [Node] source node of the arc
250
+ * @return [Arc]
251
+ */
252
+ VALUE lemongraph_dinode_arc_from(VALUE self, VALUE source)
253
+ {
254
+ VALUE rbg = rb_iv_get(self, "@graph");
255
+ return lemongraph_digraph_add_arc(rbg, source, self);
256
+ }
257
+
258
+
259
+ /* Returns the node opposite to _self_ on _arc_.
260
+ * Returns _nil_ if _arc_ is not incident to _self_.
261
+ * @param arc [Arc]
262
+ * @return [Node]
263
+ */
264
+ VALUE lemongraph_dinode_opposite(VALUE self, VALUE arc)
265
+ {
266
+ VALUE rbg = rb_iv_get(self, "@graph");
267
+ lemon::ListDigraph& g = lemongraph_digraph_rb2ref(rbg);
268
+ if (rb_class_of(arc) != c_DiArc) {
269
+ rb_raise(rb_eTypeError, "expecting a %" PRIsVALUE ", not a %s",
270
+ rb_class_name(c_DiArc), rb_obj_classname(arc));
271
+ }
272
+ if (rb_iv_get(arc, "@graph") != rbg)
273
+ rb_raise(rb_eRuntimeError, "node and arc are not from the same graph");
274
+ return lemongraph_make_dinode(g.oppositeNode(lemongraph_rbdinode2dinode(self), lemongraph_rbdiarc2diarc(arc)), rbg);
275
+ }
276
+
277
+