@@ -37,55 +37,16 @@ class GenericGraph {
37
37
38
38
// order: by labels
39
39
// TODO: think about ordering here
40
- virtual void setVertexWeights (const WeightArray& weights) {
41
- ensure (
42
- static_cast <int >(weights.size ()) == n (),
43
- " The argument of setVertexWeights must have exactly n elements" );
44
- vertexWeights_.resize (n ());
45
- for (int i = 0 ; i < n (); ++i) {
46
- vertexWeights_[i] = weights[vertexByLabel (i)];
47
- }
48
- }
49
-
40
+ virtual void setVertexWeights (const WeightArray& weights);
50
41
// v: label
51
- virtual void setVertexWeight (int v, const Weight& weight) {
52
- ensure (v < n (), " setVertexWeight" );
53
- v = vertexByLabel (v);
54
-
55
- vertexWeights_.extend (v + 1 );
56
- vertexWeights_[v] = weight;
57
- }
58
-
59
- virtual void setEdgeWeights (const WeightArray& weights) {
60
- ensure (
61
- static_cast <int >(weights.size ()) == m (),
62
- " The argument of setEdgeWeights must have exactly m elements" );
63
- edgeWeights_ = weights;
64
- }
42
+ virtual void setVertexWeight (int v, const Weight& weight);
65
43
66
- virtual void setEdgeWeight (size_t index, const Weight& weight) {
67
- ensure (static_cast <int >(index ) < m (), " setEdgeWeight" );
68
- edgeWeights_.extend (index + 1 );
69
- edgeWeights_[index ] = weight;
70
- }
44
+ virtual void setEdgeWeights (const WeightArray& weights);
45
+ virtual void setEdgeWeight (size_t index, const Weight& weight);
71
46
72
47
// v: label
73
- virtual Weight vertexWeight (int v) const {
74
- ensure (v < n (), " vertexWeight" );
75
- size_t index = vertexByLabel (v);
76
- if (index >= vertexWeights_.size ()) {
77
- return Weight{};
78
- }
79
- return vertexWeights_[index ];
80
- }
81
-
82
- virtual Weight edgeWeight (size_t index) const {
83
- ensure (static_cast <int >(index ) < m (), " edgeWeight" );
84
- if (index >= edgeWeights_.size ()) {
85
- return Weight{};
86
- }
87
- return edgeWeights_[index ];
88
- }
48
+ virtual Weight vertexWeight (int v) const ;
49
+ virtual Weight edgeWeight (size_t index) const ;
89
50
90
51
// TODO: should it really be public?
91
52
virtual void doPrintEdges (
@@ -116,7 +77,13 @@ class GenericGraph {
116
77
117
78
void permuteEdges (const Array& order);
118
79
119
- void normalizeEdges ();
80
+ void normalizeEdges () {
81
+ #ifndef JNGEN_NO_NORMALIZE_EDGES
82
+ doNormalizeEdges ();
83
+ #endif
84
+ }
85
+
86
+ void doNormalizeEdges ();
120
87
121
88
int compareTo (const GenericGraph& other) const ;
122
89
@@ -145,254 +112,12 @@ struct Hash<GenericGraph> {
145
112
}
146
113
};
147
114
148
- #ifndef JNGEN_DECLARE_ONLY
149
-
150
- Array GenericGraph::edges (int v) const {
151
- ensure (v < n (), " Graph::edges(v)" );
152
- v = vertexByLabel (v);
153
-
154
- Array result = internalEdges (v);
155
- for (auto & x: result) {
156
- x = vertexLabel (x);
157
- }
158
-
159
- return result;
160
- }
161
-
162
- Arrayp GenericGraph::edges () const {
163
- auto edges = edges_;
164
- for (auto & e: edges) {
165
- e.first = vertexLabel (e.first );
166
- e.second = vertexLabel (e.second );
167
- }
168
- return edges;
169
- }
170
-
171
- void GenericGraph::doShuffle () {
172
- // this if is to be removed after all checks pass
173
- if (vertexLabel_.size () < static_cast <size_t >(n ())) {
174
- ENSURE (false , " GenericGraph::doShuffle" );
175
- vertexLabel_ = Array::id (n ());
176
- }
177
-
178
- vertexLabel_.shuffle ();
179
- vertexByLabel_ = vertexLabel_.inverse ();
180
-
181
- if (!directed_) {
182
- for (auto & edge: edges_) {
183
- if (rnd.next (2 )) {
184
- std::swap (edge.first , edge.second );
185
- }
186
- }
187
- }
188
-
189
- permuteEdges (Array::id (numEdges_).shuffled ());
190
- }
191
-
192
- void GenericGraph::extend (size_t size) {
193
- checkLargeParameter (size);
194
- size_t oldSize = n ();
195
- if (size > oldSize) {
196
- adjList_.resize (size);
197
- vertexLabel_ += Array::id (size - oldSize, oldSize);
198
- vertexByLabel_ += Array::id (size - oldSize, oldSize);
199
- dsu_.extend (size);
200
- }
201
- }
202
-
203
- Array GenericGraph::internalEdges (int v) const {
204
- Array result;
205
- std::transform (
206
- adjList_[v].begin (),
207
- adjList_[v].end (),
208
- std::back_inserter (result),
209
- [this , v](int x) { return edgeOtherEnd (v, x); }
210
- );
211
- return result;
212
- }
213
-
214
- void GenericGraph::addEdgeUnsafe (int u, int v) {
215
- int id = numEdges_++;
216
- edges_.emplace_back (u, v);
217
-
218
- ENSURE (u < n () && v < n (), " GenericGraph::addEdgeUnsafe" );
219
-
220
- adjList_[u].push_back (id);
221
- if (!directed_ && u != v) {
222
- adjList_[v].push_back (id);
223
- }
224
- }
225
-
226
- int GenericGraph::edgeOtherEnd (int v, int edgeId) const {
227
- ENSURE (edgeId < numEdges_);
228
- const auto & edge = edges_[edgeId];
229
- if (edge.first == v) {
230
- return edge.second ;
231
- }
232
- ENSURE (!directed_);
233
- ENSURE (edge.second == v);
234
- return edge.first ;
235
- }
236
-
237
- void GenericGraph::permuteEdges (const Array& order) {
238
- ENSURE (static_cast <int >(order.size ()) == m (), " GenericGraph::permuteEdges" );
239
-
240
- edges_ = edges_.subseq (order);
241
-
242
- auto newByOld = order.inverse ();
243
- for (int v = 0 ; v < n (); ++v) {
244
- for (auto & x: adjList_[v]) {
245
- x = newByOld[x];
246
- }
247
- }
248
-
249
- if (edgeWeights_.hasNonEmpty ()) {
250
- edgeWeights_.extend (m ());
251
- edgeWeights_ = edgeWeights_.subseq (order);
252
- }
253
- }
254
-
255
- void GenericGraph::normalizeEdges () {
256
- #ifndef JNGEN_NO_NORMALIZE_EDGES
257
- ENSURE (
258
- vertexLabel_ == Array::id (n ()),
259
- " Can call normalizeEdges() only on newly created graph" );
260
-
261
- if (!directed_) {
262
- for (auto & edge: edges_) {
263
- if (edge.first > edge.second ) {
264
- std::swap (edge.first , edge.second );
265
- }
266
- }
267
- }
268
-
269
- auto order = Array::id (numEdges_).sorted (
270
- [this ](int i, int j) {
271
- return edges_[i] < edges_[j];
272
- });
273
-
274
- permuteEdges (order);
275
- #endif // JNGEN_NO_NORMALIZE_EDGES
276
- }
277
-
278
- void GenericGraph::addEdge (int u, int v, const Weight& w) {
279
- extend (std::max (u, v) + 1 );
280
-
281
- u = vertexByLabel (u);
282
- v = vertexByLabel (v);
283
-
284
- dsu_.unite (u, v);
285
- addEdgeUnsafe (u, v);
286
-
287
- if (!w.empty ()) {
288
- setEdgeWeight (m () - 1 , w);
289
- }
290
- }
291
-
292
- namespace {
293
-
294
- WeightArray prepareWeightArray (WeightArray a, int requiredSize) {
295
- ENSURE (a.hasNonEmpty (), " Attempt to print empty weight array" );
296
-
297
- a.extend (requiredSize);
298
- int type = a.anyType ();
299
- for (auto & x: a) {
300
- if (x.empty ()) {
301
- x.setType (type);
302
- }
303
- }
304
-
305
- return a;
306
- }
307
-
308
- } // namespace
309
-
310
- void GenericGraph::doPrintEdges (
311
- std::ostream& out, const OutputModifier& mod) const
312
- {
313
- if (mod.printN ) {
314
- out << n ();
315
- if (mod.printM ) {
316
- out << " " << m ();
317
- }
318
- out << " \n " ;
319
- } else if (mod.printM ) {
320
- out << m () << " \n " ;
321
- }
322
-
323
- if (vertexWeights_.hasNonEmpty ()) {
324
- auto vertexWeights = prepareWeightArray (vertexWeights_, n ());
325
- for (int i = 0 ; i < n (); ++i) {
326
- if (i > 0 ) {
327
- out << " " ;
328
- }
329
- JNGEN_PRINT_NO_MOD (vertexWeights[vertexByLabel (i)]);
330
- }
331
- out << " \n " ;
332
- }
333
-
334
- auto t (mod);
335
- {
336
- auto mod (t);
337
-
338
- Arrayp edges = this ->edges ();
339
- mod.printN = false ;
340
- if (edgeWeights_.hasNonEmpty ()) {
341
- auto edgeWeights = prepareWeightArray (edgeWeights_, m ());
342
- for (int i = 0 ; i < m (); ++i) {
343
- if (i > 0 ) {
344
- out << " \n " ;
345
- }
346
- JNGEN_PRINT (edges[i]);
347
- out << " " ;
348
- JNGEN_PRINT_NO_MOD (edgeWeights[i]);
349
- }
350
- } else {
351
- JNGEN_PRINT (edges);
352
- }
353
- }
354
- }
355
-
356
- bool GenericGraph::operator ==(const GenericGraph& other) const {
357
- return compareTo (other) == 0 ;
358
- }
359
-
360
- bool GenericGraph::operator !=(const GenericGraph& other) const {
361
- return compareTo (other) != 0 ;
362
- }
363
-
364
- bool GenericGraph::operator <(const GenericGraph& other) const {
365
- return compareTo (other) == -1 ;
366
- }
367
-
368
- bool GenericGraph::operator >(const GenericGraph& other) const {
369
- return compareTo (other) == 1 ;
370
- }
371
-
372
- bool GenericGraph::operator <=(const GenericGraph& other) const {
373
- return compareTo (other) != 1 ;
374
- }
375
-
376
- bool GenericGraph::operator >=(const GenericGraph& other) const {
377
- return compareTo (other) != -1 ;
378
- }
379
-
380
- int GenericGraph::compareTo (const GenericGraph& other) const {
381
- if (n () != other.n ()) {
382
- return n () < other.n () ? -1 : 1 ;
383
- }
384
- for (int i = 0 ; i < n (); ++i) {
385
- auto e1 = edges (i).sorted ();
386
- auto e2 = other.edges (i).sorted ();
387
- if (e1 != e2 ) {
388
- return e1 < e2 ? -1 : 1 ;
389
- }
390
- }
391
- return 0 ;
392
- }
393
-
394
- #endif // JNGEN_DECLARE_ONLY
395
-
396
115
} // namespace jngen
397
116
398
117
JNGEN_DEFINE_STD_HASH (jngen::GenericGraph);
118
+
119
+ #ifndef JNGEN_DECLARE_ONLY
120
+ #define JNGEN_INCLUDE_GENERIC_GRAPH_INL_H
121
+ #include " impl/generic_graph_inl.h"
122
+ #undef JNGEN_INCLUDE_GENERIC_GRAPH_INL_H
123
+ #endif // JNGEN_DECLARE_ONLY
0 commit comments