gravatar
deba@inf.elte.hu
deba@inf.elte.hu
Item validity checking for ListGraph and SmartGraph
0 3 0
default
3 files changed with 212 insertions and 47 deletions:
↑ Collapse diff ↑
Ignore white space 192 line context
... ...
@@ -59,390 +59,421 @@
59 59
    typedef ListDigraphBase Digraph;
60 60
    
61 61
    class Node {
62 62
      friend class ListDigraphBase;
63 63
    protected:
64 64

	
65 65
      int id;
66 66
      explicit Node(int pid) { id = pid;}
67 67

	
68 68
    public:
69 69
      Node() {}
70 70
      Node (Invalid) { id = -1; }
71 71
      bool operator==(const Node& node) const {return id == node.id;}
72 72
      bool operator!=(const Node& node) const {return id != node.id;}
73 73
      bool operator<(const Node& node) const {return id < node.id;}
74 74
    };
75 75

	
76 76
    class Arc {
77 77
      friend class ListDigraphBase;
78 78
    protected:
79 79

	
80 80
      int id;
81 81
      explicit Arc(int pid) { id = pid;}
82 82

	
83 83
    public:
84 84
      Arc() {}
85 85
      Arc (Invalid) { id = -1; }
86 86
      bool operator==(const Arc& arc) const {return id == arc.id;}
87 87
      bool operator!=(const Arc& arc) const {return id != arc.id;}
88 88
      bool operator<(const Arc& arc) const {return id < arc.id;}
89 89
    };
90 90

	
91 91

	
92 92

	
93 93
    ListDigraphBase()
94 94
      : nodes(), first_node(-1),
95 95
	first_free_node(-1), arcs(), first_free_arc(-1) {}
96 96

	
97 97
    
98 98
    int maxNodeId() const { return nodes.size()-1; } 
99 99
    int maxArcId() const { return arcs.size()-1; }
100 100

	
101 101
    Node source(Arc e) const { return Node(arcs[e.id].source); }
102 102
    Node target(Arc e) const { return Node(arcs[e.id].target); }
103 103

	
104 104

	
105 105
    void first(Node& node) const { 
106 106
      node.id = first_node;
107 107
    }
108 108

	
109 109
    void next(Node& node) const {
110 110
      node.id = nodes[node.id].next;
111 111
    }
112 112

	
113 113

	
114 114
    void first(Arc& arc) const { 
115 115
      int n;
116 116
      for(n = first_node; 
117 117
	  n!=-1 && nodes[n].first_in == -1; 
118 118
	  n = nodes[n].next);
119 119
      arc.id = (n == -1) ? -1 : nodes[n].first_in;
120 120
    }
121 121

	
122 122
    void next(Arc& arc) const {
123 123
      if (arcs[arc.id].next_in != -1) {
124 124
	arc.id = arcs[arc.id].next_in;
125 125
      } else {
126 126
	int n;
127 127
	for(n = nodes[arcs[arc.id].target].next;
128 128
	  n!=-1 && nodes[n].first_in == -1; 
129 129
	  n = nodes[n].next);
130 130
	arc.id = (n == -1) ? -1 : nodes[n].first_in;
131 131
      }      
132 132
    }
133 133

	
134 134
    void firstOut(Arc &e, const Node& v) const {
135 135
      e.id = nodes[v.id].first_out;
136 136
    }
137 137
    void nextOut(Arc &e) const {
138 138
      e.id=arcs[e.id].next_out;
139 139
    }
140 140

	
141 141
    void firstIn(Arc &e, const Node& v) const {
142 142
      e.id = nodes[v.id].first_in;
143 143
    }
144 144
    void nextIn(Arc &e) const {
145 145
      e.id=arcs[e.id].next_in;
146 146
    }
147 147

	
148 148
    
149 149
    static int id(Node v) { return v.id; }
150 150
    static int id(Arc e) { return e.id; }
151 151

	
152 152
    static Node nodeFromId(int id) { return Node(id);}
153 153
    static Arc arcFromId(int id) { return Arc(id);}
154 154

	
155
    bool valid(Node n) const { 
156
      return n.id >= 0 && n.id < static_cast<int>(nodes.size()) && 
157
	nodes[n.id].prev != -2;
158
    }
159

	
160
    bool valid(Arc a) const { 
161
      return a.id >= 0 && a.id < static_cast<int>(arcs.size()) && 
162
	arcs[a.id].prev_in != -2;
163
    }
164

	
155 165
    Node addNode() {     
156 166
      int n;
157 167
      
158 168
      if(first_free_node==-1) {
159 169
	n = nodes.size();
160 170
	nodes.push_back(NodeT());
161 171
      } else {
162 172
	n = first_free_node;
163 173
	first_free_node = nodes[n].next;
164 174
      }
165 175
      
166 176
      nodes[n].next = first_node;
167 177
      if(first_node != -1) nodes[first_node].prev = n;
168 178
      first_node = n;
169 179
      nodes[n].prev = -1;
170 180
      
171 181
      nodes[n].first_in = nodes[n].first_out = -1;
172 182
      
173 183
      return Node(n);
174 184
    }
175 185
    
176 186
    Arc addArc(Node u, Node v) {
177 187
      int n;      
178 188

	
179 189
      if (first_free_arc == -1) {
180 190
	n = arcs.size();
181 191
	arcs.push_back(ArcT());
182 192
      } else {
183 193
	n = first_free_arc;
184 194
	first_free_arc = arcs[n].next_in;
185 195
      }
186 196
      
187 197
      arcs[n].source = u.id; 
188 198
      arcs[n].target = v.id;
189 199

	
190 200
      arcs[n].next_out = nodes[u.id].first_out;
191 201
      if(nodes[u.id].first_out != -1) {
192 202
	arcs[nodes[u.id].first_out].prev_out = n;
193 203
      }
194 204
      
195 205
      arcs[n].next_in = nodes[v.id].first_in;
196 206
      if(nodes[v.id].first_in != -1) {
197 207
	arcs[nodes[v.id].first_in].prev_in = n;
198 208
      }
199 209
      
200 210
      arcs[n].prev_in = arcs[n].prev_out = -1;
201 211
	
202 212
      nodes[u.id].first_out = nodes[v.id].first_in = n;
203 213

	
204 214
      return Arc(n);
205 215
    }
206 216
    
207 217
    void erase(const Node& node) {
208 218
      int n = node.id;
209 219
      
210 220
      if(nodes[n].next != -1) {
211 221
	nodes[nodes[n].next].prev = nodes[n].prev;
212 222
      }
213 223
      
214 224
      if(nodes[n].prev != -1) {
215 225
	nodes[nodes[n].prev].next = nodes[n].next;
216 226
      } else {
217 227
	first_node = nodes[n].next;
218 228
      }
219 229
      
220 230
      nodes[n].next = first_free_node;
221 231
      first_free_node = n;
232
      nodes[n].prev = -2;
222 233

	
223 234
    }
224 235
    
225 236
    void erase(const Arc& arc) {
226 237
      int n = arc.id;
227 238
      
228 239
      if(arcs[n].next_in!=-1) {
229 240
	arcs[arcs[n].next_in].prev_in = arcs[n].prev_in;
230 241
      }
231 242

	
232 243
      if(arcs[n].prev_in!=-1) {
233 244
	arcs[arcs[n].prev_in].next_in = arcs[n].next_in;
234 245
      } else {
235 246
	nodes[arcs[n].target].first_in = arcs[n].next_in;
236 247
      }
237 248

	
238 249
      
239 250
      if(arcs[n].next_out!=-1) {
240 251
	arcs[arcs[n].next_out].prev_out = arcs[n].prev_out;
241 252
      } 
242 253

	
243 254
      if(arcs[n].prev_out!=-1) {
244 255
	arcs[arcs[n].prev_out].next_out = arcs[n].next_out;
245 256
      } else {
246 257
	nodes[arcs[n].source].first_out = arcs[n].next_out;
247 258
      }
248 259
      
249 260
      arcs[n].next_in = first_free_arc;
250
      first_free_arc = n;      
251

	
261
      first_free_arc = n;
262
      arcs[n].prev_in = -2;
252 263
    }
253 264

	
254 265
    void clear() {
255 266
      arcs.clear();
256 267
      nodes.clear();
257 268
      first_node = first_free_node = first_free_arc = -1;
258 269
    }
259 270

	
260 271
  protected:
261 272
    void changeTarget(Arc e, Node n) 
262 273
    {
263 274
      if(arcs[e.id].next_in != -1)
264 275
	arcs[arcs[e.id].next_in].prev_in = arcs[e.id].prev_in;
265 276
      if(arcs[e.id].prev_in != -1)
266 277
	arcs[arcs[e.id].prev_in].next_in = arcs[e.id].next_in;
267 278
      else nodes[arcs[e.id].target].first_in = arcs[e.id].next_in;
268 279
      if (nodes[n.id].first_in != -1) {
269 280
	arcs[nodes[n.id].first_in].prev_in = e.id;
270 281
      }
271 282
      arcs[e.id].target = n.id;
272 283
      arcs[e.id].prev_in = -1;
273 284
      arcs[e.id].next_in = nodes[n.id].first_in;
274 285
      nodes[n.id].first_in = e.id;
275 286
    }
276 287
    void changeSource(Arc e, Node n) 
277 288
    {
278 289
      if(arcs[e.id].next_out != -1)
279 290
	arcs[arcs[e.id].next_out].prev_out = arcs[e.id].prev_out;
280 291
      if(arcs[e.id].prev_out != -1)
281 292
	arcs[arcs[e.id].prev_out].next_out = arcs[e.id].next_out;
282 293
      else nodes[arcs[e.id].source].first_out = arcs[e.id].next_out;
283 294
      if (nodes[n.id].first_out != -1) {
284 295
	arcs[nodes[n.id].first_out].prev_out = e.id;
285 296
      }
286 297
      arcs[e.id].source = n.id;
287 298
      arcs[e.id].prev_out = -1;
288 299
      arcs[e.id].next_out = nodes[n.id].first_out;
289 300
      nodes[n.id].first_out = e.id;
290 301
    }
291 302

	
292 303
  };
293 304

	
294 305
  typedef DigraphExtender<ListDigraphBase> ExtendedListDigraphBase;
295 306

	
296 307
  /// \addtogroup graphs
297 308
  /// @{
298 309

	
299 310
  ///A general directed graph structure. 
300 311

	
301 312
  ///\ref ListDigraph is a simple and fast <em>directed graph</em> 
302 313
  ///implementation based on static linked lists that are stored in 
303 314
  ///\c std::vector structures.   
304 315
  ///
305 316
  ///It conforms to the \ref concepts::Digraph "Digraph concept" and it
306 317
  ///also provides several useful additional functionalities.
307 318
  ///Most of the member functions and nested classes are documented
308 319
  ///only in the concept class.
309 320
  ///
310 321
  ///An important extra feature of this digraph implementation is that
311 322
  ///its maps are real \ref concepts::ReferenceMap "reference map"s.
312 323
  ///
313 324
  ///\sa concepts::Digraph
314 325

	
315 326
  class ListDigraph : public ExtendedListDigraphBase {
316 327
  private:
317 328
    ///ListDigraph is \e not copy constructible. Use copyDigraph() instead.
318 329
    
319 330
    ///ListDigraph is \e not copy constructible. Use copyDigraph() instead.
320 331
    ///
321 332
    ListDigraph(const ListDigraph &) :ExtendedListDigraphBase() {};
322 333
    ///\brief Assignment of ListDigraph to another one is \e not allowed.
323 334
    ///Use copyDigraph() instead.
324 335

	
325 336
    ///Assignment of ListDigraph to another one is \e not allowed.
326 337
    ///Use copyDigraph() instead.
327 338
    void operator=(const ListDigraph &) {}
328 339
  public:
329 340

	
330 341
    typedef ExtendedListDigraphBase Parent;
331 342

	
332 343
    /// Constructor
333 344
    
334 345
    /// Constructor.
335 346
    ///
336 347
    ListDigraph() {}
337 348

	
338 349
    ///Add a new node to the digraph.
339 350
    
340 351
    ///Add a new node to the digraph.
341 352
    ///\return the new node.
342 353
    Node addNode() { return Parent::addNode(); }
343 354

	
344 355
    ///Add a new arc to the digraph.
345 356
    
346 357
    ///Add a new arc to the digraph with source node \c s
347 358
    ///and target node \c t.
348 359
    ///\return the new arc.
349 360
    Arc addArc(const Node& s, const Node& t) { 
350 361
      return Parent::addArc(s, t); 
351 362
    }
352 363

	
364
    /// Node validity check
365

	
366
    /// This function gives back true if the given node is valid,
367
    /// ie. it is a real node of the graph.  
368
    ///
369
    /// \warning A Node pointing to a removed item
370
    /// could become valid again later if new nodes are
371
    /// added to the graph.
372
    bool valid(Node n) const { return Parent::valid(n); }
373

	
374
    /// Arc validity check
375

	
376
    /// This function gives back true if the given arc is valid,
377
    /// ie. it is a real arc of the graph.  
378
    ///
379
    /// \warning An Arc pointing to a removed item
380
    /// could become valid again later if new nodes are
381
    /// added to the graph.
382
    bool valid(Arc a) const { return Parent::valid(a); }
383

	
353 384
    /// Change the target of \c e to \c n
354 385

	
355 386
    /// Change the target of \c e to \c n
356 387
    ///
357 388
    ///\note The <tt>ArcIt</tt>s and <tt>OutArcIt</tt>s referencing
358 389
    ///the changed arc remain valid. However <tt>InArcIt</tt>s are
359 390
    ///invalidated.
360 391
    ///
361 392
    ///\warning This functionality cannot be used together with the Snapshot
362 393
    ///feature.
363 394
    void changeTarget(Arc e, Node n) { 
364 395
      Parent::changeTarget(e,n); 
365 396
    }
366 397
    /// Change the source of \c e to \c n
367 398

	
368 399
    /// Change the source of \c e to \c n
369 400
    ///
370 401
    ///\note The <tt>ArcIt</tt>s and <tt>InArcIt</tt>s referencing
371 402
    ///the changed arc remain valid. However <tt>OutArcIt</tt>s are
372 403
    ///invalidated.
373 404
    ///
374 405
    ///\warning This functionality cannot be used together with the Snapshot
375 406
    ///feature.
376 407
    void changeSource(Arc e, Node n) { 
377 408
      Parent::changeSource(e,n);
378 409
    }
379 410

	
380 411
    /// Invert the direction of an arc.
381 412

	
382 413
    ///\note The <tt>ArcIt</tt>s referencing the changed arc remain
383 414
    ///valid. However <tt>OutArcIt</tt>s and <tt>InArcIt</tt>s are
384 415
    ///invalidated.
385 416
    ///
386 417
    ///\warning This functionality cannot be used together with the Snapshot
387 418
    ///feature.
388 419
    void reverseArc(Arc e) {
389 420
      Node t=target(e);
390 421
      changeTarget(e,source(e));
391 422
      changeSource(e,t);
392 423
    }
393 424

	
394 425
    /// Reserve memory for nodes.
395 426

	
396 427
    /// Using this function it is possible to avoid the superfluous memory
397 428
    /// allocation: if you know that the digraph you want to build will
398 429
    /// be very large (e.g. it will contain millions of nodes and/or arcs)
399 430
    /// then it is worth reserving space for this amount before starting
400 431
    /// to build the digraph.
401 432
    /// \sa reserveArc
402 433
    void reserveNode(int n) { nodes.reserve(n); };
403 434

	
404 435
    /// Reserve memory for arcs.
405 436

	
406 437
    /// Using this function it is possible to avoid the superfluous memory
407 438
    /// allocation: if you know that the digraph you want to build will
408 439
    /// be very large (e.g. it will contain millions of nodes and/or arcs)
409 440
    /// then it is worth reserving space for this amount before starting
410 441
    /// to build the digraph.
411 442
    /// \sa reserveNode
412 443
    void reserveArc(int m) { arcs.reserve(m); };
413 444

	
414 445
    ///Contract two nodes.
415 446

	
416 447
    ///This function contracts two nodes.
417 448
    ///Node \p b will be removed but instead of deleting
418 449
    ///incident arcs, they will be joined to \p a.
419 450
    ///The last parameter \p r controls whether to remove loops. \c true
420 451
    ///means that loops will be removed.
421 452
    ///
422 453
    ///\note The <tt>ArcIt</tt>s referencing a moved arc remain
423 454
    ///valid. However <tt>InArcIt</tt>s and <tt>OutArcIt</tt>s
424 455
    ///may be invalidated.
425 456
    ///
426 457
    ///\warning This functionality cannot be used together with the Snapshot
427 458
    ///feature.
428 459
    void contract(Node a, Node b, bool r = true) 
429 460
    {
430 461
      for(OutArcIt e(*this,b);e!=INVALID;) {
431 462
	OutArcIt f=e;
432 463
	++f;
433 464
	if(r && target(e)==a) erase(e);
434 465
	else changeSource(e,a);
435 466
	e=f;
436 467
      }
437 468
      for(InArcIt e(*this,b);e!=INVALID;) {
438 469
	InArcIt f=e;
439 470
	++f;
440 471
	if(r && source(e)==a) erase(e);
441 472
	else changeTarget(e,a);
442 473
	e=f;
443 474
      }
444 475
      erase(b);
445 476
    }
446 477

	
447 478
    ///Split a node.
448 479

	
... ...
@@ -852,404 +883,448 @@
852 883
	e.id = arcs[e.id].next_out;
853 884
      } else {
854 885
	int n = nodes[arcs[e.id ^ 1].target].next;
855 886
        while(n != -1 && nodes[n].first_out == -1) {
856 887
          n = nodes[n].next;
857 888
        }
858 889
	e.id = (n == -1) ? -1 : nodes[n].first_out;
859 890
      }      
860 891
    }
861 892

	
862 893
    void first(Edge& e) const { 
863 894
      int n = first_node;
864 895
      while (n != -1) {
865 896
        e.id = nodes[n].first_out;
866 897
        while ((e.id & 1) != 1) {
867 898
          e.id = arcs[e.id].next_out;
868 899
        }
869 900
        if (e.id != -1) {
870 901
          e.id /= 2;
871 902
          return;
872 903
        } 
873 904
        n = nodes[n].next;
874 905
      }
875 906
      e.id = -1;
876 907
    }
877 908

	
878 909
    void next(Edge& e) const {
879 910
      int n = arcs[e.id * 2].target;
880 911
      e.id = arcs[(e.id * 2) | 1].next_out;
881 912
      while ((e.id & 1) != 1) {
882 913
        e.id = arcs[e.id].next_out;
883 914
      }
884 915
      if (e.id != -1) {
885 916
        e.id /= 2;
886 917
        return;
887 918
      } 
888 919
      n = nodes[n].next;
889 920
      while (n != -1) {
890 921
        e.id = nodes[n].first_out;
891 922
        while ((e.id & 1) != 1) {
892 923
          e.id = arcs[e.id].next_out;
893 924
        }
894 925
        if (e.id != -1) {
895 926
          e.id /= 2;
896 927
          return;
897 928
        } 
898 929
        n = nodes[n].next;
899 930
      }
900 931
      e.id = -1;
901 932
    }
902 933

	
903 934
    void firstOut(Arc &e, const Node& v) const {
904 935
      e.id = nodes[v.id].first_out;
905 936
    }
906 937
    void nextOut(Arc &e) const {
907 938
      e.id = arcs[e.id].next_out;
908 939
    }
909 940

	
910 941
    void firstIn(Arc &e, const Node& v) const {
911 942
      e.id = ((nodes[v.id].first_out) ^ 1);
912 943
      if (e.id == -2) e.id = -1;
913 944
    }
914 945
    void nextIn(Arc &e) const {
915 946
      e.id = ((arcs[e.id ^ 1].next_out) ^ 1);
916 947
      if (e.id == -2) e.id = -1;
917 948
    }
918 949

	
919 950
    void firstInc(Edge &e, bool& d, const Node& v) const {
920 951
      int a = nodes[v.id].first_out;
921 952
      if (a != -1 ) {
922 953
        e.id = a / 2;
923 954
        d = ((a & 1) == 1);
924 955
      } else {
925 956
        e.id = -1;
926 957
        d = true;
927 958
      }
928 959
    }
929 960
    void nextInc(Edge &e, bool& d) const {
930 961
      int a = (arcs[(e.id * 2) | (d ? 1 : 0)].next_out);
931 962
      if (a != -1 ) {
932 963
        e.id = a / 2;
933 964
        d = ((a & 1) == 1);
934 965
      } else {
935 966
        e.id = -1;
936 967
        d = true;
937 968
      }
938 969
    }
939 970
    
940 971
    static int id(Node v) { return v.id; }
941 972
    static int id(Arc e) { return e.id; }
942 973
    static int id(Edge e) { return e.id; }
943 974

	
944 975
    static Node nodeFromId(int id) { return Node(id);}
945 976
    static Arc arcFromId(int id) { return Arc(id);}
946 977
    static Edge edgeFromId(int id) { return Edge(id);}
947 978

	
979
    bool valid(Node n) const { 
980
      return n.id >= 0 && n.id < static_cast<int>(nodes.size()) && 
981
	nodes[n.id].prev != -2;
982
    }
983

	
984
    bool valid(Arc a) const { 
985
      return a.id >= 0 && a.id < static_cast<int>(arcs.size()) && 
986
	arcs[a.id].prev_out != -2;
987
    }
988

	
989
    bool valid(Edge e) const { 
990
      return e.id >= 0 && 2 * e.id < static_cast<int>(arcs.size()) && 
991
	arcs[2 * e.id].prev_out != -2;
992
    }
993

	
948 994
    Node addNode() {     
949 995
      int n;
950 996
      
951 997
      if(first_free_node==-1) {
952 998
	n = nodes.size();
953 999
	nodes.push_back(NodeT());
954 1000
      } else {
955 1001
	n = first_free_node;
956 1002
	first_free_node = nodes[n].next;
957 1003
      }
958 1004
      
959 1005
      nodes[n].next = first_node;
960 1006
      if (first_node != -1) nodes[first_node].prev = n;
961 1007
      first_node = n;
962 1008
      nodes[n].prev = -1;
963 1009
      
964 1010
      nodes[n].first_out = -1;
965 1011
      
966 1012
      return Node(n);
967 1013
    }
968 1014
    
969 1015
    Edge addEdge(Node u, Node v) {
970 1016
      int n;      
971 1017

	
972 1018
      if (first_free_arc == -1) {
973 1019
	n = arcs.size();
974 1020
	arcs.push_back(ArcT());
975 1021
	arcs.push_back(ArcT());
976 1022
      } else {
977 1023
	n = first_free_arc;
978 1024
	first_free_arc = arcs[n].next_out;
979 1025
      }
980 1026
      
981 1027
      arcs[n].target = u.id;
982 1028
      arcs[n | 1].target = v.id;
983 1029

	
984 1030
      arcs[n].next_out = nodes[v.id].first_out;
985 1031
      if (nodes[v.id].first_out != -1) {
986 1032
	arcs[nodes[v.id].first_out].prev_out = n;
987 1033
      }      
988 1034
      arcs[n].prev_out = -1;
989 1035
      nodes[v.id].first_out = n;
990 1036
      
991 1037
      arcs[n | 1].next_out = nodes[u.id].first_out;
992 1038
      if (nodes[u.id].first_out != -1) {
993 1039
	arcs[nodes[u.id].first_out].prev_out = (n | 1);
994 1040
      }
995 1041
      arcs[n | 1].prev_out = -1;      
996 1042
      nodes[u.id].first_out = (n | 1);
997 1043

	
998 1044
      return Edge(n / 2);
999 1045
    }
1000 1046
    
1001 1047
    void erase(const Node& node) {
1002 1048
      int n = node.id;
1003 1049
      
1004 1050
      if(nodes[n].next != -1) {
1005 1051
	nodes[nodes[n].next].prev = nodes[n].prev;
1006 1052
      }
1007 1053
      
1008 1054
      if(nodes[n].prev != -1) {
1009 1055
	nodes[nodes[n].prev].next = nodes[n].next;
1010 1056
      } else {
1011 1057
	first_node = nodes[n].next;
1012 1058
      }
1013 1059
      
1014 1060
      nodes[n].next = first_free_node;
1015 1061
      first_free_node = n;
1016

	
1062
      nodes[n].prev = -2;
1017 1063
    }
1018 1064
    
1019 1065
    void erase(const Edge& edge) {
1020 1066
      int n = edge.id * 2;
1021 1067
      
1022 1068
      if (arcs[n].next_out != -1) {
1023 1069
	arcs[arcs[n].next_out].prev_out = arcs[n].prev_out;
1024 1070
      } 
1025 1071

	
1026 1072
      if (arcs[n].prev_out != -1) {
1027 1073
	arcs[arcs[n].prev_out].next_out = arcs[n].next_out;
1028 1074
      } else {
1029 1075
	nodes[arcs[n | 1].target].first_out = arcs[n].next_out;
1030 1076
      }
1031 1077

	
1032 1078
      if (arcs[n | 1].next_out != -1) {
1033 1079
	arcs[arcs[n | 1].next_out].prev_out = arcs[n | 1].prev_out;
1034 1080
      } 
1035 1081

	
1036 1082
      if (arcs[n | 1].prev_out != -1) {
1037 1083
	arcs[arcs[n | 1].prev_out].next_out = arcs[n | 1].next_out;
1038 1084
      } else {
1039 1085
	nodes[arcs[n].target].first_out = arcs[n | 1].next_out;
1040 1086
      }
1041 1087
      
1042 1088
      arcs[n].next_out = first_free_arc;
1043 1089
      first_free_arc = n;      
1090
      arcs[n].prev_out = -2;
1091
      arcs[n | 1].prev_out = -2;
1044 1092

	
1045 1093
    }
1046 1094

	
1047 1095
    void clear() {
1048 1096
      arcs.clear();
1049 1097
      nodes.clear();
1050 1098
      first_node = first_free_node = first_free_arc = -1;
1051 1099
    }
1052 1100

	
1053 1101
  protected:
1054 1102

	
1055 1103
    void changeTarget(Edge e, Node n) {
1056 1104
      if(arcs[2 * e.id].next_out != -1) {
1057 1105
	arcs[arcs[2 * e.id].next_out].prev_out = arcs[2 * e.id].prev_out;
1058 1106
      }
1059 1107
      if(arcs[2 * e.id].prev_out != -1) {
1060 1108
	arcs[arcs[2 * e.id].prev_out].next_out = 
1061 1109
          arcs[2 * e.id].next_out;
1062 1110
      } else {
1063 1111
        nodes[arcs[(2 * e.id) | 1].target].first_out = 
1064 1112
          arcs[2 * e.id].next_out;
1065 1113
      }
1066 1114

	
1067 1115
      if (nodes[n.id].first_out != -1) {
1068 1116
	arcs[nodes[n.id].first_out].prev_out = 2 * e.id;
1069 1117
      }
1070 1118
      arcs[(2 * e.id) | 1].target = n.id;
1071 1119
      arcs[2 * e.id].prev_out = -1;
1072 1120
      arcs[2 * e.id].next_out = nodes[n.id].first_out;
1073 1121
      nodes[n.id].first_out = 2 * e.id;
1074 1122
    }
1075 1123

	
1076 1124
    void changeSource(Edge e, Node n) {
1077 1125
      if(arcs[(2 * e.id) | 1].next_out != -1) {
1078 1126
	arcs[arcs[(2 * e.id) | 1].next_out].prev_out = 
1079 1127
          arcs[(2 * e.id) | 1].prev_out;
1080 1128
      }
1081 1129
      if(arcs[(2 * e.id) | 1].prev_out != -1) {
1082 1130
	arcs[arcs[(2 * e.id) | 1].prev_out].next_out = 
1083 1131
          arcs[(2 * e.id) | 1].next_out;
1084 1132
      } else {
1085 1133
        nodes[arcs[2 * e.id].target].first_out = 
1086 1134
          arcs[(2 * e.id) | 1].next_out;
1087 1135
      }
1088 1136

	
1089 1137
      if (nodes[n.id].first_out != -1) {
1090 1138
	arcs[nodes[n.id].first_out].prev_out = ((2 * e.id) | 1);
1091 1139
      }
1092 1140
      arcs[2 * e.id].target = n.id;
1093 1141
      arcs[(2 * e.id) | 1].prev_out = -1;
1094 1142
      arcs[(2 * e.id) | 1].next_out = nodes[n.id].first_out;
1095 1143
      nodes[n.id].first_out = ((2 * e.id) | 1);
1096 1144
    }
1097 1145

	
1098 1146
  };
1099 1147

	
1100 1148
  typedef GraphExtender<ListGraphBase> ExtendedListGraphBase;
1101 1149

	
1102 1150

	
1103 1151
  /// \addtogroup graphs
1104 1152
  /// @{
1105 1153

	
1106 1154
  ///A general undirected graph structure.
1107 1155

	
1108 1156
  ///\ref ListGraph is a simple and fast <em>undirected graph</em> 
1109 1157
  ///implementation based on static linked lists that are stored in 
1110 1158
  ///\c std::vector structures. 
1111 1159
  ///
1112 1160
  ///It conforms to the \ref concepts::Graph "Graph concept" and it
1113 1161
  ///also provides several useful additional functionalities.
1114 1162
  ///Most of the member functions and nested classes are documented
1115 1163
  ///only in the concept class.
1116 1164
  ///
1117 1165
  ///An important extra feature of this graph implementation is that
1118 1166
  ///its maps are real \ref concepts::ReferenceMap "reference map"s.
1119 1167
  ///
1120 1168
  ///\sa concepts::Graph
1121 1169

	
1122 1170
  class ListGraph : public ExtendedListGraphBase {
1123 1171
  private:
1124 1172
    ///ListGraph is \e not copy constructible. Use copyGraph() instead.
1125 1173

	
1126 1174
    ///ListGraph is \e not copy constructible. Use copyGraph() instead.
1127 1175
    ///
1128 1176
    ListGraph(const ListGraph &) :ExtendedListGraphBase()  {};
1129 1177
    ///\brief Assignment of ListGraph to another one is \e not allowed.
1130 1178
    ///Use copyGraph() instead.
1131 1179

	
1132 1180
    ///Assignment of ListGraph to another one is \e not allowed.
1133 1181
    ///Use copyGraph() instead.
1134 1182
    void operator=(const ListGraph &) {}
1135 1183
  public:
1136 1184
    /// Constructor
1137 1185
    
1138 1186
    /// Constructor.
1139 1187
    ///
1140 1188
    ListGraph() {}
1141 1189

	
1142 1190
    typedef ExtendedListGraphBase Parent;
1143 1191

	
1144 1192
    typedef Parent::OutArcIt IncEdgeIt;
1145 1193

	
1146 1194
    /// \brief Add a new node to the graph.
1147 1195
    ///
1148 1196
    /// Add a new node to the graph.
1149 1197
    /// \return the new node.
1150 1198
    Node addNode() { return Parent::addNode(); }
1151 1199

	
1152 1200
    /// \brief Add a new edge to the graph.
1153 1201
    ///
1154 1202
    /// Add a new edge to the graph with source node \c s
1155 1203
    /// and target node \c t.
1156 1204
    /// \return the new edge.
1157 1205
    Edge addEdge(const Node& s, const Node& t) { 
1158 1206
      return Parent::addEdge(s, t); 
1159 1207
    }
1208
    /// Node validity check
1209

	
1210
    /// This function gives back true if the given node is valid,
1211
    /// ie. it is a real node of the graph.  
1212
    ///
1213
    /// \warning A Node pointing to a removed item
1214
    /// could become valid again later if new nodes are
1215
    /// added to the graph.
1216
    bool valid(Node n) const { return Parent::valid(n); }
1217
    /// Arc validity check
1218

	
1219
    /// This function gives back true if the given arc is valid,
1220
    /// ie. it is a real arc of the graph.  
1221
    ///
1222
    /// \warning An Arc pointing to a removed item
1223
    /// could become valid again later if new edges are
1224
    /// added to the graph.
1225
    bool valid(Arc a) const { return Parent::valid(a); }
1226
    /// Edge validity check
1227

	
1228
    /// This function gives back true if the given edge is valid,
1229
    /// ie. it is a real arc of the graph.  
1230
    ///
1231
    /// \warning A Edge pointing to a removed item
1232
    /// could become valid again later if new edges are
1233
    /// added to the graph.
1234
    bool valid(Edge e) const { return Parent::valid(e); }
1160 1235
    /// \brief Change the source of \c e to \c n
1161 1236
    ///
1162 1237
    /// This function changes the source of \c e to \c n.
1163 1238
    ///
1164 1239
    ///\note The <tt>ArcIt</tt>s and <tt>InArcIt</tt>s
1165 1240
    ///referencing the changed arc remain
1166 1241
    ///valid. However <tt>OutArcIt</tt>s are invalidated.
1167 1242
    ///
1168 1243
    ///\warning This functionality cannot be used together with the
1169 1244
    ///Snapshot feature.
1170 1245
    void changeSource(Edge e, Node n) { 
1171 1246
      Parent::changeSource(e,n); 
1172 1247
    }    
1173 1248
    /// \brief Change the target of \c e to \c n
1174 1249
    ///
1175 1250
    /// This function changes the target of \c e to \c n.
1176 1251
    ///
1177 1252
    /// \note The <tt>ArcIt</tt>s referencing the changed arc remain
1178 1253
    /// valid. However the other iterators may be invalidated.
1179 1254
    ///
1180 1255
    ///\warning This functionality cannot be used together with the
1181 1256
    ///Snapshot feature.
1182 1257
    void changeTarget(Edge e, Node n) { 
1183 1258
      Parent::changeTarget(e,n); 
1184 1259
    }
1185 1260
    /// \brief Change the source of \c e to \c n
1186 1261
    ///
1187 1262
    /// This function changes the source of \c e to \c n. 
1188 1263
    /// It also changes the proper node of the represented edge.
1189 1264
    ///
1190 1265
    ///\note The <tt>ArcIt</tt>s and <tt>InArcIt</tt>s
1191 1266
    ///referencing the changed arc remain
1192 1267
    ///valid. However <tt>OutArcIt</tt>s are invalidated.
1193 1268
    ///
1194 1269
    ///\warning This functionality cannot be used together with the
1195 1270
    ///Snapshot feature.
1196 1271
    void changeSource(Arc e, Node n) { 
1197 1272
      if (Parent::direction(e)) {
1198 1273
        Parent::changeSource(e,n);
1199 1274
      } else {
1200 1275
        Parent::changeTarget(e,n);
1201 1276
      } 
1202 1277
    }
1203 1278
    /// \brief Change the target of \c e to \c n
1204 1279
    ///
1205 1280
    /// This function changes the target of \c e to \c n. 
1206 1281
    /// It also changes the proper node of the represented edge.
1207 1282
    ///
1208 1283
    ///\note The <tt>ArcIt</tt>s and <tt>OutArcIt</tt>s
1209 1284
    ///referencing the changed arc remain
1210 1285
    ///valid. However <tt>InArcIt</tt>s are invalidated.
1211 1286
    ///
1212 1287
    ///\warning This functionality cannot be used together with the
1213 1288
    ///Snapshot feature.
1214 1289
    void changeTarget(Arc e, Node n) { 
1215 1290
      if (Parent::direction(e)) {
1216 1291
        Parent::changeTarget(e,n);
1217 1292
      } else {
1218 1293
        Parent::changeSource(e,n);
1219 1294
      } 
1220 1295
    }
1221 1296
    /// \brief Contract two nodes.
1222 1297
    ///
1223 1298
    /// This function contracts two nodes.
1224 1299
    /// Node \p b will be removed but instead of deleting
1225 1300
    /// its neighboring arcs, they will be joined to \p a.
1226 1301
    /// The last parameter \p r controls whether to remove loops. \c true
1227 1302
    /// means that loops will be removed.
1228 1303
    ///
1229 1304
    /// \note The <tt>ArcIt</tt>s referencing a moved arc remain
1230 1305
    /// valid.
1231 1306
    ///
1232 1307
    ///\warning This functionality cannot be used together with the
1233 1308
    ///Snapshot feature.
1234 1309
    void contract(Node a, Node b, bool r = true) {
1235 1310
      for(IncEdgeIt e(*this, b); e!=INVALID;) {
1236 1311
	IncEdgeIt f = e; ++f;
1237 1312
	if (r && runningNode(e) == a) {
1238 1313
	  erase(e);
1239 1314
	} else if (source(e) == b) {
1240 1315
	  changeSource(e, a);
1241 1316
	} else {
1242 1317
	  changeTarget(e, a);
1243 1318
	}
1244 1319
	e = f;
1245 1320
      }
1246 1321
      erase(b);
1247 1322
    }
1248 1323

	
1249 1324

	
1250 1325
    /// \brief Class to make a snapshot of the graph and restore
1251 1326
    /// it later.
1252 1327
    ///
1253 1328
    /// Class to make a snapshot of the graph and restore it later.
1254 1329
    ///
1255 1330
    /// The newly added nodes and edges can be removed
Ignore white space 192 line context
... ...
@@ -22,338 +22,363 @@
22 22
///\ingroup graphs
23 23
///\file
24 24
///\brief SmartDigraph and SmartGraph classes.
25 25

	
26 26
#include <vector>
27 27

	
28 28
#include <lemon/bits/invalid.h>
29 29

	
30 30
#include <lemon/bits/base_extender.h>
31 31
#include <lemon/bits/graph_extender.h>
32 32

	
33 33
#include <lemon/bits/utility.h>
34 34
#include <lemon/error.h>
35 35

	
36 36
#include <lemon/bits/graph_extender.h>
37 37

	
38 38
namespace lemon {
39 39

	
40 40
  class SmartDigraph;
41 41
  ///Base of SmartDigraph
42 42

	
43 43
  ///Base of SmartDigraph
44 44
  ///
45 45
  class SmartDigraphBase {
46 46
  protected:
47 47

	
48 48
    struct NodeT 
49 49
    {
50 50
      int first_in, first_out;      
51 51
      NodeT() {}
52 52
    };
53 53
    struct ArcT 
54 54
    {
55 55
      int target, source, next_in, next_out;      
56 56
      ArcT() {}  
57 57
    };
58 58

	
59 59
    std::vector<NodeT> nodes;
60 60
    std::vector<ArcT> arcs;
61 61
        
62 62
  public:
63 63

	
64 64
    typedef SmartDigraphBase Graph;
65 65

	
66 66
    class Node;
67 67
    class Arc;
68 68

	
69 69
  public:
70 70

	
71 71
    SmartDigraphBase() : nodes(), arcs() { }
72 72
    SmartDigraphBase(const SmartDigraphBase &_g) 
73 73
      : nodes(_g.nodes), arcs(_g.arcs) { }
74 74
    
75 75
    typedef True NodeNumTag;
76 76
    typedef True EdgeNumTag;
77 77

	
78 78
    int nodeNum() const { return nodes.size(); }
79 79
    int arcNum() const { return arcs.size(); }
80 80

	
81 81
    int maxNodeId() const { return nodes.size()-1; }
82 82
    int maxArcId() const { return arcs.size()-1; }
83 83

	
84 84
    Node addNode() {
85 85
      int n = nodes.size();     
86 86
      nodes.push_back(NodeT());
87 87
      nodes[n].first_in = -1;
88 88
      nodes[n].first_out = -1;
89 89
      return Node(n);
90 90
    }
91 91
    
92 92
    Arc addArc(Node u, Node v) {
93 93
      int n = arcs.size(); 
94 94
      arcs.push_back(ArcT());
95 95
      arcs[n].source = u._id; 
96 96
      arcs[n].target = v._id;
97 97
      arcs[n].next_out = nodes[u._id].first_out;
98 98
      arcs[n].next_in = nodes[v._id].first_in;
99 99
      nodes[u._id].first_out = nodes[v._id].first_in = n;
100 100

	
101 101
      return Arc(n);
102 102
    }
103 103

	
104 104
    void clear() {
105 105
      arcs.clear();
106 106
      nodes.clear();
107 107
    }
108 108

	
109 109
    Node source(Arc a) const { return Node(arcs[a._id].source); }
110 110
    Node target(Arc a) const { return Node(arcs[a._id].target); }
111 111

	
112 112
    static int id(Node v) { return v._id; }
113 113
    static int id(Arc a) { return a._id; }
114 114

	
115 115
    static Node nodeFromId(int id) { return Node(id);}
116 116
    static Arc arcFromId(int id) { return Arc(id);}
117 117

	
118
    bool valid(Node n) const { 
119
      return n._id >= 0 && n._id < static_cast<int>(nodes.size()); 
120
    }
121
    bool valid(Arc a) const { 
122
      return a._id >= 0 && a._id < static_cast<int>(arcs.size()); 
123
    }
124

	
118 125
    class Node {
119 126
      friend class SmartDigraphBase;
120 127
      friend class SmartDigraph;
121 128

	
122 129
    protected:
123 130
      int _id;
124 131
      explicit Node(int id) : _id(id) {}
125 132
    public:
126 133
      Node() {}
127 134
      Node (Invalid) : _id(-1) {}
128 135
      bool operator==(const Node i) const {return _id == i._id;}
129 136
      bool operator!=(const Node i) const {return _id != i._id;}
130 137
      bool operator<(const Node i) const {return _id < i._id;}
131 138
    };
132 139
    
133 140

	
134 141
    class Arc {
135 142
      friend class SmartDigraphBase;
136 143
      friend class SmartDigraph;
137 144

	
138 145
    protected:
139 146
      int _id;
140 147
      explicit Arc(int id) : _id(id) {}
141 148
    public:
142 149
      Arc() { }
143 150
      Arc (Invalid) : _id(-1) {}
144 151
      bool operator==(const Arc i) const {return _id == i._id;}
145 152
      bool operator!=(const Arc i) const {return _id != i._id;}
146 153
      bool operator<(const Arc i) const {return _id < i._id;}
147 154
    };
148 155

	
149 156
    void first(Node& node) const {
150 157
      node._id = nodes.size() - 1;
151 158
    }
152 159

	
153 160
    static void next(Node& node) {
154 161
      --node._id;
155 162
    }
156 163

	
157 164
    void first(Arc& arc) const {
158 165
      arc._id = arcs.size() - 1;
159 166
    }
160 167

	
161 168
    static void next(Arc& arc) {
162 169
      --arc._id;
163 170
    }
164 171

	
165 172
    void firstOut(Arc& arc, const Node& node) const {
166 173
      arc._id = nodes[node._id].first_out;
167 174
    }
168 175

	
169 176
    void nextOut(Arc& arc) const {
170 177
      arc._id = arcs[arc._id].next_out;
171 178
    }
172 179

	
173 180
    void firstIn(Arc& arc, const Node& node) const {
174 181
      arc._id = nodes[node._id].first_in;
175 182
    }
176 183
    
177 184
    void nextIn(Arc& arc) const {
178 185
      arc._id = arcs[arc._id].next_in;
179 186
    }
180 187

	
181 188
  };
182 189

	
183 190
  typedef DigraphExtender<SmartDigraphBase> ExtendedSmartDigraphBase;
184 191

	
185 192
  ///\ingroup graphs
186 193
  ///
187 194
  ///\brief A smart directed graph class.
188 195
  ///
189 196
  ///This is a simple and fast digraph implementation.
190 197
  ///It is also quite memory efficient, but at the price
191 198
  ///that <b> it does support only limited (only stack-like)
192 199
  ///node and arc deletions</b>.
193 200
  ///It conforms to the \ref concepts::Digraph "Digraph concept" with
194 201
  ///an important extra feature that its maps are real \ref
195 202
  ///concepts::ReferenceMap "reference map"s.
196 203
  ///
197 204
  ///\sa concepts::Digraph.
198 205
  ///
199 206
  ///\author Alpar Juttner
200 207
  class SmartDigraph : public ExtendedSmartDigraphBase {
201 208
  public:
202 209

	
203 210
    typedef ExtendedSmartDigraphBase Parent;
204 211

	
205 212
  private:
206 213

	
207 214
    ///SmartDigraph is \e not copy constructible. Use DigraphCopy() instead.
208 215

	
209 216
    ///SmartDigraph is \e not copy constructible. Use DigraphCopy() instead.
210 217
    ///
211 218
    SmartDigraph(const SmartDigraph &) : ExtendedSmartDigraphBase() {};
212 219
    ///\brief Assignment of SmartDigraph to another one is \e not allowed.
213 220
    ///Use DigraphCopy() instead.
214 221

	
215 222
    ///Assignment of SmartDigraph to another one is \e not allowed.
216 223
    ///Use DigraphCopy() instead.
217 224
    void operator=(const SmartDigraph &) {}
218 225

	
219 226
  public:
220 227
    
221 228
    /// Constructor
222 229
    
223 230
    /// Constructor.
224 231
    ///
225 232
    SmartDigraph() {};
226 233
    
227 234
    ///Add a new node to the digraph.
228 235
    
229 236
    /// \return the new node.
230 237
    ///
231 238
    Node addNode() { return Parent::addNode(); }
232 239
    
233 240
    ///Add a new arc to the digraph.
234 241
    
235 242
    ///Add a new arc to the digraph with source node \c s
236 243
    ///and target node \c t.
237 244
    ///\return the new arc.
238 245
    Arc addArc(const Node& s, const Node& t) { 
239 246
      return Parent::addArc(s, t); 
240 247
    }
241 248

	
242 249
    /// \brief Using this it is possible to avoid the superfluous memory
243 250
    /// allocation.
244 251

	
245 252
    /// Using this it is possible to avoid the superfluous memory
246 253
    /// allocation: if you know that the digraph you want to build will
247 254
    /// be very large (e.g. it will contain millions of nodes and/or arcs)
248 255
    /// then it is worth reserving space for this amount before starting
249 256
    /// to build the digraph.
250 257
    /// \sa reserveArc
251 258
    void reserveNode(int n) { nodes.reserve(n); };
252 259

	
253 260
    /// \brief Using this it is possible to avoid the superfluous memory
254 261
    /// allocation.
255 262

	
256 263
    /// Using this it is possible to avoid the superfluous memory
257 264
    /// allocation: if you know that the digraph you want to build will
258 265
    /// be very large (e.g. it will contain millions of nodes and/or arcs)
259 266
    /// then it is worth reserving space for this amount before starting
260 267
    /// to build the digraph.
261 268
    /// \sa reserveNode
262 269
    void reserveArc(int m) { arcs.reserve(m); };
263 270

	
271
    /// \brief Node validity check
272
    ///
273
    /// This function gives back true if the given node is valid,
274
    /// ie. it is a real node of the graph.  
275
    ///
276
    /// \warning A removed node (using Snapshot) could become valid again
277
    /// when new nodes are added to the graph.
278
    bool valid(Node n) const { return Parent::valid(n); }
279

	
280
    /// \brief Arc validity check
281
    ///
282
    /// This function gives back true if the given arc is valid,
283
    /// ie. it is a real arc of the graph.  
284
    ///
285
    /// \warning A removed arc (using Snapshot) could become valid again
286
    /// when new arcs are added to the graph.
287
    bool valid(Arc a) const { return Parent::valid(a); }
288

	
264 289
    ///Clear the digraph.
265 290
    
266 291
    ///Erase all the nodes and arcs from the digraph.
267 292
    ///
268 293
    void clear() {
269 294
      Parent::clear();
270 295
    }
271 296

	
272 297
    ///Split a node.
273 298
    
274 299
    ///This function splits a node. First a new node is added to the digraph,
275 300
    ///then the source of each outgoing arc of \c n is moved to this new node.
276 301
    ///If \c connect is \c true (this is the default value), then a new arc
277 302
    ///from \c n to the newly created node is also added.
278 303
    ///\return The newly created node.
279 304
    ///
280 305
    ///\note The <tt>Arc</tt>s
281 306
    ///referencing a moved arc remain
282 307
    ///valid. However <tt>InArc</tt>'s and <tt>OutArc</tt>'s
283 308
    ///may be invalidated.
284 309
    ///\warning This functionality cannot be used together with the Snapshot
285 310
    ///feature.
286 311
    ///\todo It could be implemented in a bit faster way.
287 312
    Node split(Node n, bool connect = true)
288 313
    {
289 314
      Node b = addNode();
290 315
      nodes[b._id].first_out=nodes[n._id].first_out;
291 316
      nodes[n._id].first_out=-1;
292 317
      for(int i=nodes[b._id].first_out;i!=-1;i++) arcs[i].source=b._id;
293 318
      if(connect) addArc(n,b);
294 319
      return b;
295 320
    }
296 321

	
297 322
  public:
298 323
    
299 324
    class Snapshot;
300 325

	
301 326
  protected:
302 327

	
303 328
    void restoreSnapshot(const Snapshot &s)
304 329
    {
305 330
      while(s.arc_num<arcs.size()) {
306 331
        Arc arc = arcFromId(arcs.size()-1);
307 332
	Parent::notifier(Arc()).erase(arc);
308 333
	nodes[arcs.back().source].first_out=arcs.back().next_out;
309 334
	nodes[arcs.back().target].first_in=arcs.back().next_in;
310 335
	arcs.pop_back();
311 336
      }
312 337
      while(s.node_num<nodes.size()) {
313 338
        Node node = nodeFromId(nodes.size()-1);
314 339
	Parent::notifier(Node()).erase(node);
315 340
	nodes.pop_back();
316 341
      }
317 342
    }    
318 343

	
319 344
  public:
320 345

	
321 346
    ///Class to make a snapshot of the digraph and to restrore to it later.
322 347

	
323 348
    ///Class to make a snapshot of the digraph and to restrore to it later.
324 349
    ///
325 350
    ///The newly added nodes and arcs can be removed using the
326 351
    ///restore() function.
327 352
    ///\note After you restore a state, you cannot restore
328 353
    ///a later state, in other word you cannot add again the arcs deleted
329 354
    ///by restore() using another one Snapshot instance.
330 355
    ///
331 356
    ///\warning If you do not use correctly the snapshot that can cause
332 357
    ///either broken program, invalid state of the digraph, valid but
333 358
    ///not the restored digraph or no change. Because the runtime performance
334 359
    ///the validity of the snapshot is not stored.
335 360
    class Snapshot 
336 361
    {
337 362
      SmartDigraph *_graph;
338 363
    protected:
339 364
      friend class SmartDigraph;
340 365
      unsigned int node_num;
341 366
      unsigned int arc_num;
342 367
    public:
343 368
      ///Default constructor.
344 369
      
345 370
      ///Default constructor.
346 371
      ///To actually make a snapshot you must call save().
347 372
      ///
348 373
      Snapshot() : _graph(0) {}
349 374
      ///Constructor that immediately makes a snapshot
350 375
      
351 376
      ///This constructor immediately makes a snapshot of the digraph.
352 377
      ///\param _g The digraph we make a snapshot of.
353 378
      Snapshot(SmartDigraph &graph) : _graph(&graph) {
354 379
	node_num=_graph->nodes.size();
355 380
	arc_num=_graph->arcs.size();
356 381
      }
357 382

	
358 383
      ///Make a snapshot.
359 384

	
... ...
@@ -457,284 +482,321 @@
457 482
      bool operator<(const Arc& arc) const {return _id < arc._id;}
458 483
    };
459 484

	
460 485

	
461 486

	
462 487
    SmartGraphBase()
463 488
      : nodes(), arcs() {}
464 489

	
465 490
    
466 491
    int maxNodeId() const { return nodes.size()-1; } 
467 492
    int maxEdgeId() const { return arcs.size() / 2 - 1; }
468 493
    int maxArcId() const { return arcs.size()-1; }
469 494

	
470 495
    Node source(Arc e) const { return Node(arcs[e._id ^ 1].target); }
471 496
    Node target(Arc e) const { return Node(arcs[e._id].target); }
472 497

	
473 498
    Node u(Edge e) const { return Node(arcs[2 * e._id].target); }
474 499
    Node v(Edge e) const { return Node(arcs[2 * e._id + 1].target); }
475 500

	
476 501
    static bool direction(Arc e) {
477 502
      return (e._id & 1) == 1;
478 503
    }
479 504

	
480 505
    static Arc direct(Edge e, bool d) {
481 506
      return Arc(e._id * 2 + (d ? 1 : 0));
482 507
    }
483 508

	
484 509
    void first(Node& node) const { 
485 510
      node._id = nodes.size() - 1;
486 511
    }
487 512

	
488 513
    void next(Node& node) const {
489 514
      --node._id;
490 515
    }
491 516

	
492 517
    void first(Arc& arc) const { 
493 518
      arc._id = arcs.size() - 1;
494 519
    }
495 520

	
496 521
    void next(Arc& arc) const {
497 522
      --arc._id;
498 523
    }
499 524

	
500 525
    void first(Edge& arc) const { 
501 526
      arc._id = arcs.size() / 2 - 1;
502 527
    }
503 528

	
504 529
    void next(Edge& arc) const {
505 530
      --arc._id;
506 531
    }
507 532

	
508 533
    void firstOut(Arc &arc, const Node& v) const {
509 534
      arc._id = nodes[v._id].first_out;
510 535
    }
511 536
    void nextOut(Arc &arc) const {
512 537
      arc._id = arcs[arc._id].next_out;
513 538
    }
514 539

	
515 540
    void firstIn(Arc &arc, const Node& v) const {
516 541
      arc._id = ((nodes[v._id].first_out) ^ 1);
517 542
      if (arc._id == -2) arc._id = -1;
518 543
    }
519 544
    void nextIn(Arc &arc) const {
520 545
      arc._id = ((arcs[arc._id ^ 1].next_out) ^ 1);
521 546
      if (arc._id == -2) arc._id = -1;
522 547
    }
523 548

	
524 549
    void firstInc(Edge &arc, bool& d, const Node& v) const {
525 550
      int de = nodes[v._id].first_out;
526 551
      if (de != -1) {
527 552
        arc._id = de / 2;
528 553
        d = ((de & 1) == 1);
529 554
      } else {
530 555
        arc._id = -1;
531 556
        d = true;
532 557
      }
533 558
    }
534 559
    void nextInc(Edge &arc, bool& d) const {
535 560
      int de = (arcs[(arc._id * 2) | (d ? 1 : 0)].next_out);
536 561
      if (de != -1) {
537 562
        arc._id = de / 2;
538 563
        d = ((de & 1) == 1);
539 564
      } else {
540 565
        arc._id = -1;
541 566
        d = true;      
542 567
      }
543 568
    }
544 569
    
545 570
    static int id(Node v) { return v._id; }
546 571
    static int id(Arc e) { return e._id; }
547 572
    static int id(Edge e) { return e._id; }
548 573

	
549 574
    static Node nodeFromId(int id) { return Node(id);}
550 575
    static Arc arcFromId(int id) { return Arc(id);}
551 576
    static Edge edgeFromId(int id) { return Edge(id);}
552 577

	
578
    bool valid(Node n) const { 
579
      return n._id >= 0 && n._id < static_cast<int>(nodes.size()); 
580
    }
581
    bool valid(Arc a) const { 
582
      return a._id >= 0 && a._id < static_cast<int>(arcs.size());
583
    }
584
    bool valid(Edge e) const { 
585
      return e._id >= 0 && 2 * e._id < static_cast<int>(arcs.size()); 
586
    }
587

	
553 588
    Node addNode() {     
554 589
      int n = nodes.size();
555 590
      nodes.push_back(NodeT());
556 591
      nodes[n].first_out = -1;
557 592
      
558 593
      return Node(n);
559 594
    }
560 595
    
561 596
    Edge addEdge(Node u, Node v) {
562 597
      int n = arcs.size();
563 598
      arcs.push_back(ArcT());
564 599
      arcs.push_back(ArcT());
565 600
      
566 601
      arcs[n].target = u._id;
567 602
      arcs[n | 1].target = v._id;
568 603

	
569 604
      arcs[n].next_out = nodes[v._id].first_out;
570 605
      nodes[v._id].first_out = n;
571 606

	
572 607
      arcs[n | 1].next_out = nodes[u._id].first_out;	
573 608
      nodes[u._id].first_out = (n | 1);
574 609

	
575 610
      return Edge(n / 2);
576 611
    }
577 612
    
578 613
    void clear() {
579 614
      arcs.clear();
580 615
      nodes.clear();
581 616
    }
582 617

	
583 618
  };
584 619

	
585 620
  typedef GraphExtender<SmartGraphBase> ExtendedSmartGraphBase;
586 621

	
587 622
  /// \ingroup graphs
588 623
  ///
589 624
  /// \brief A smart undirected graph class.
590 625
  ///
591 626
  /// This is a simple and fast graph implementation.
592 627
  /// It is also quite memory efficient, but at the price
593 628
  /// that <b> it does support only limited (only stack-like)
594 629
  /// node and arc deletions</b>.
595 630
  /// Except from this it conforms to 
596 631
  /// the \ref concepts::Graph "Graph concept".
597 632
  ///
598 633
  /// It also has an
599 634
  /// important extra feature that
600 635
  /// its maps are real \ref concepts::ReferenceMap "reference map"s.
601 636
  ///
602 637
  /// \sa concepts::Graph.
603 638
  ///
604 639
  class SmartGraph : public ExtendedSmartGraphBase {
605 640
  private:
606 641

	
607 642
    ///SmartGraph is \e not copy constructible. Use GraphCopy() instead.
608 643

	
609 644
    ///SmartGraph is \e not copy constructible. Use GraphCopy() instead.
610 645
    ///
611 646
    SmartGraph(const SmartGraph &) : ExtendedSmartGraphBase() {};
612 647

	
613 648
    ///\brief Assignment of SmartGraph to another one is \e not allowed.
614 649
    ///Use GraphCopy() instead.
615 650

	
616 651
    ///Assignment of SmartGraph to another one is \e not allowed.
617 652
    ///Use GraphCopy() instead.
618 653
    void operator=(const SmartGraph &) {}
619 654

	
620 655
  public:
621 656

	
622 657
    typedef ExtendedSmartGraphBase Parent;
623 658

	
624 659
    /// Constructor
625 660
    
626 661
    /// Constructor.
627 662
    ///
628 663
    SmartGraph() {}
629 664

	
630 665
    ///Add a new node to the graph.
631 666
    
632 667
    /// \return the new node.
633 668
    ///
634 669
    Node addNode() { return Parent::addNode(); }
635 670
    
636 671
    ///Add a new edge to the graph.
637 672
    
638 673
    ///Add a new edge to the graph with node \c s
639 674
    ///and \c t.
640 675
    ///\return the new edge.
641 676
    Edge addEdge(const Node& s, const Node& t) { 
642 677
      return Parent::addEdge(s, t); 
643 678
    }
644 679

	
680
    /// \brief Node validity check
681
    ///
682
    /// This function gives back true if the given node is valid,
683
    /// ie. it is a real node of the graph.  
684
    ///
685
    /// \warning A removed node (using Snapshot) could become valid again
686
    /// when new nodes are added to the graph.
687
    bool valid(Node n) const { return Parent::valid(n); }
688

	
689
    /// \brief Arc validity check
690
    ///
691
    /// This function gives back true if the given arc is valid,
692
    /// ie. it is a real arc of the graph.  
693
    ///
694
    /// \warning A removed arc (using Snapshot) could become valid again
695
    /// when new edges are added to the graph.
696
    bool valid(Arc a) const { return Parent::valid(a); }
697

	
698
    /// \brief Edge validity check
699
    ///
700
    /// This function gives back true if the given edge is valid,
701
    /// ie. it is a real edge of the graph.  
702
    ///
703
    /// \warning A removed edge (using Snapshot) could become valid again
704
    /// when new edges are added to the graph.
705
    bool valid(Edge e) const { return Parent::valid(e); }
706

	
645 707
    ///Clear the graph.
646 708
    
647 709
    ///Erase all the nodes and edges from the graph.
648 710
    ///
649 711
    void clear() {
650 712
      Parent::clear();
651 713
    }
652 714

	
653 715
  public:
654 716
    
655 717
    class Snapshot;
656 718

	
657 719
  protected:
658 720

	
659 721
    void saveSnapshot(Snapshot &s)
660 722
    {
661 723
      s._graph = this;
662 724
      s.node_num = nodes.size();
663 725
      s.arc_num = arcs.size();
664 726
    }
665 727

	
666 728
    void restoreSnapshot(const Snapshot &s)
667 729
    {
668 730
      while(s.arc_num<arcs.size()) {
669 731
        int n=arcs.size()-1;
670 732
        Edge arc=edgeFromId(n/2);
671 733
	Parent::notifier(Edge()).erase(arc);
672 734
        std::vector<Arc> dir;
673 735
        dir.push_back(arcFromId(n));
674 736
        dir.push_back(arcFromId(n-1));
675 737
	Parent::notifier(Arc()).erase(dir);
676 738
	nodes[arcs[n].target].first_out=arcs[n].next_out;
677 739
	nodes[arcs[n-1].target].first_out=arcs[n-1].next_out;
678 740
	arcs.pop_back();
679 741
	arcs.pop_back();
680 742
      }
681 743
      while(s.node_num<nodes.size()) {
682 744
        int n=nodes.size()-1;
683 745
        Node node = nodeFromId(n);
684 746
	Parent::notifier(Node()).erase(node);
685 747
	nodes.pop_back();
686 748
      }
687 749
    }    
688 750

	
689 751
  public:
690 752

	
691 753
    ///Class to make a snapshot of the digraph and to restrore to it later.
692 754

	
693 755
    ///Class to make a snapshot of the digraph and to restrore to it later.
694 756
    ///
695 757
    ///The newly added nodes and arcs can be removed using the
696 758
    ///restore() function.
697 759
    ///
698 760
    ///\note After you restore a state, you cannot restore
699 761
    ///a later state, in other word you cannot add again the arcs deleted
700 762
    ///by restore() using another one Snapshot instance.
701 763
    ///
702 764
    ///\warning If you do not use correctly the snapshot that can cause
703 765
    ///either broken program, invalid state of the digraph, valid but
704 766
    ///not the restored digraph or no change. Because the runtime performance
705 767
    ///the validity of the snapshot is not stored.
706 768
    class Snapshot 
707 769
    {
708 770
      SmartGraph *_graph;
709 771
    protected:
710 772
      friend class SmartGraph;
711 773
      unsigned int node_num;
712 774
      unsigned int arc_num;
713 775
    public:
714 776
      ///Default constructor.
715 777
      
716 778
      ///Default constructor.
717 779
      ///To actually make a snapshot you must call save().
718 780
      ///
719 781
      Snapshot() : _graph(0) {}
720 782
      ///Constructor that immediately makes a snapshot
721 783
      
722 784
      ///This constructor immediately makes a snapshot of the digraph.
723 785
      ///\param g The digraph we make a snapshot of.
724 786
      Snapshot(SmartGraph &graph) {
725 787
        graph.saveSnapshot(*this);
726 788
      }
727 789

	
728 790
      ///Make a snapshot.
729 791

	
730 792
      ///Make a snapshot of the graph.
731 793
      ///
732 794
      ///This function can be called more than once. In case of a repeated
733 795
      ///call, the previous snapshot gets lost.
734 796
      ///\param g The digraph we make the snapshot of.
735 797
      void save(SmartGraph &graph) 
736 798
      {
737 799
        graph.saveSnapshot(*this);
738 800
      }
739 801

	
740 802
      ///Undo the changes until a snapshot.
Ignore white space 192 line context
1 1
/* -*- C++ -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library
4 4
 *
5 5
 * Copyright (C) 2003-2008
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
#include <lemon/concepts/graph.h>
20 20
#include <lemon/list_graph.h>
21 21
#include <lemon/smart_graph.h>
22 22
// #include <lemon/full_graph.h>
23 23
// #include <lemon/grid_graph.h>
24 24

	
25
//#include <lemon/graph_utils.h>
25
#include <lemon/graph_utils.h>
26 26

	
27 27
#include "test_tools.h"
28 28

	
29 29

	
30 30
using namespace lemon;
31 31
using namespace lemon::concepts;
32 32

	
33 33
void check_concepts() {
34 34

	
35 35
  { // checking digraph components
36 36
    checkConcept<BaseGraphComponent, BaseGraphComponent >();
37 37

	
38 38
    checkConcept<IDableGraphComponent<>, 
39 39
      IDableGraphComponent<> >();
40 40

	
41 41
    checkConcept<IterableGraphComponent<>, 
42 42
      IterableGraphComponent<> >();
43 43

	
44 44
    checkConcept<MappableGraphComponent<>, 
45 45
      MappableGraphComponent<> >();
46 46

	
47 47
  }
48 48
  {
49 49
    checkConcept<Graph, ListGraph>();    
50 50
    checkConcept<Graph, SmartGraph>();    
51 51
//     checkConcept<Graph, FullGraph>();    
52 52
//     checkConcept<Graph, Graph>();    
53 53
//     checkConcept<Graph, GridGraph>();
54 54
  }
55 55
}
56 56

	
57 57
template <typename Graph>
58 58
void check_item_counts(Graph &g, int n, int e) {
59 59
  int nn = 0;
60 60
  for (typename Graph::NodeIt it(g); it != INVALID; ++it) {
61 61
    ++nn;
62 62
  }
63 63

	
64 64
  check(nn == n, "Wrong node number.");
65 65
  //  check(countNodes(g) == n, "Wrong node number.");
66 66

	
67 67
  int ee = 0;
68 68
  for (typename Graph::ArcIt it(g); it != INVALID; ++it) {
69 69
    ++ee;
70 70
  }
71 71

	
72 72
  check(ee == 2*e, "Wrong arc number.");
73 73
  //  check(countArcs(g) == 2*e, "Wrong arc number.");
74 74

	
75 75
  int uee = 0;
76 76
  for (typename Graph::EdgeIt it(g); it != INVALID; ++it) {
77 77
    ++uee;
78 78
  }
79 79

	
80 80
  check(uee == e, "Wrong edge number.");
81 81
  //  check(countEdges(g) == e, "Wrong edge number.");
82 82
}
83 83

	
84 84
template <typename Graph>
85
void print_items(Graph &g) {
85
void check_graph_counts() {
86 86

	
87
  typedef typename Graph::NodeIt NodeIt;
88
  typedef typename Graph::EdgeIt EdgeIt;
89
  typedef typename Graph::ArcIt ArcIt;
90

	
91
  std::cout << "Nodes" << std::endl;
92
  int i=0;
93
  for(NodeIt it(g); it!=INVALID; ++it, ++i) {
94
    std::cout << "  " << i << ": " << g.id(it) << std::endl;
95
  }
96

	
97
  std::cout << "Edge" << std::endl;
98
  i=0;
99
  for(EdgeIt it(g); it!=INVALID; ++it, ++i) {
100
    std::cout << "  " << i << ": " << g.id(it) 
101
	 << " (" << g.id(g.source(it)) << ", " << g.id(g.target(it)) 
102
	 << ")" << std::endl;
103
  }
104

	
105
  std::cout << "Arc" << std::endl;
106
  i=0;
107
  for(ArcIt it(g); it!=INVALID; ++it, ++i) {
108
    std::cout << "  " << i << ": " << g.id(it)
109
	 << " (" << g.id(g.source(it)) << ", " << g.id(g.target(it)) 
110
	 << ")" << std::endl;
111
  }
112

	
113
}
114

	
115
template <typename Graph>
116
void check_graph() {
117

	
118
  typedef typename Graph::Node Node;
119
  typedef typename Graph::Edge Edge;
120
  typedef typename Graph::Arc Arc;
121
  typedef typename Graph::NodeIt NodeIt;
122
  typedef typename Graph::EdgeIt EdgeIt;
123
  typedef typename Graph::ArcIt ArcIt;
124

	
87
  TEMPLATE_GRAPH_TYPEDEFS(Graph);
125 88
  Graph g;
126 89

	
127 90
  check_item_counts(g,0,0);
128 91

	
129 92
  Node
130 93
    n1 = g.addNode(),
131 94
    n2 = g.addNode(),
132 95
    n3 = g.addNode();
133 96

	
134 97
  Edge
135 98
    e1 = g.addEdge(n1, n2),
136 99
    e2 = g.addEdge(n2, n3);
137 100

	
138
  // print_items(g);
139

	
140 101
  check_item_counts(g,3,2);
141 102
}
142 103

	
104
template <typename Graph>
105
void check_graph_validity() {
106

	
107
  TEMPLATE_GRAPH_TYPEDEFS(Graph);
108
  Graph g;
109

	
110
  check_item_counts(g,0,0);
111

	
112
  Node
113
    n1 = g.addNode(),
114
    n2 = g.addNode(),
115
    n3 = g.addNode();
116

	
117
  Edge
118
    e1 = g.addEdge(n1, n2),
119
    e2 = g.addEdge(n2, n3);
120

	
121
  check(g.valid(n1), "Validity check");
122
  check(g.valid(e1), "Validity check");
123
  check(g.valid(g.direct(e1, true)), "Validity check");
124

	
125
  check(!g.valid(g.nodeFromId(-1)), "Validity check");
126
  check(!g.valid(g.edgeFromId(-1)), "Validity check");
127
  check(!g.valid(g.arcFromId(-1)), "Validity check");
128
    
129
}
130

	
131
template <typename Graph>
132
void check_graph_validity_erase() {
133

	
134
  TEMPLATE_GRAPH_TYPEDEFS(Graph);
135
  Graph g;
136

	
137
  check_item_counts(g,0,0);
138

	
139
  Node
140
    n1 = g.addNode(),
141
    n2 = g.addNode(),
142
    n3 = g.addNode();
143

	
144
  Edge
145
    e1 = g.addEdge(n1, n2),
146
    e2 = g.addEdge(n2, n3);
147

	
148
  check(g.valid(n1), "Validity check");
149
  check(g.valid(e1), "Validity check");
150
  check(g.valid(g.direct(e1, true)), "Validity check");
151

	
152
  g.erase(n1);
153

	
154
  check(!g.valid(n1), "Validity check");
155
  check(g.valid(n2), "Validity check");
156
  check(g.valid(n3), "Validity check");
157
  check(!g.valid(e1), "Validity check");
158
  check(g.valid(e2), "Validity check");
159

	
160
  check(!g.valid(g.nodeFromId(-1)), "Validity check");
161
  check(!g.valid(g.edgeFromId(-1)), "Validity check");
162
  check(!g.valid(g.arcFromId(-1)), "Validity check");
163
    
164
}
165

	
166

	
167

	
143 168
// void checkGridGraph(const GridGraph& g, int w, int h) {
144 169
//   check(g.width() == w, "Wrong width");
145 170
//   check(g.height() == h, "Wrong height");
146 171

	
147 172
//   for (int i = 0; i < w; ++i) {
148 173
//     for (int j = 0; j < h; ++j) {
149 174
//       check(g.col(g(i, j)) == i, "Wrong col");
150 175
//       check(g.row(g(i, j)) == j, "Wrong row");
151 176
//     }
152 177
//   }
153 178
  
154 179
//   for (int i = 0; i < w; ++i) {
155 180
//     for (int j = 0; j < h - 1; ++j) {
156 181
//       check(g.source(g.down(g(i, j))) == g(i, j), "Wrong down");
157 182
//       check(g.target(g.down(g(i, j))) == g(i, j + 1), "Wrong down");
158 183
//     }
159 184
//     check(g.down(g(i, h - 1)) == INVALID, "Wrong down");
160 185
//   }
161 186

	
162 187
//   for (int i = 0; i < w; ++i) {
163 188
//     for (int j = 1; j < h; ++j) {
164 189
//       check(g.source(g.up(g(i, j))) == g(i, j), "Wrong up");
165 190
//       check(g.target(g.up(g(i, j))) == g(i, j - 1), "Wrong up");
166 191
//     }
167 192
//     check(g.up(g(i, 0)) == INVALID, "Wrong up");
168 193
//   }
169 194

	
170 195
//   for (int j = 0; j < h; ++j) {
171 196
//     for (int i = 0; i < w - 1; ++i) {
172 197
//       check(g.source(g.right(g(i, j))) == g(i, j), "Wrong right");
173 198
//       check(g.target(g.right(g(i, j))) == g(i + 1, j), "Wrong right");      
174 199
//     }
175 200
//     check(g.right(g(w - 1, j)) == INVALID, "Wrong right");    
176 201
//   }
177 202

	
178 203
//   for (int j = 0; j < h; ++j) {
179 204
//     for (int i = 1; i < w; ++i) {
180 205
//       check(g.source(g.left(g(i, j))) == g(i, j), "Wrong left");
181 206
//       check(g.target(g.left(g(i, j))) == g(i - 1, j), "Wrong left");      
182 207
//     }
183 208
//     check(g.left(g(0, j)) == INVALID, "Wrong left");    
184 209
//   }
185 210
// }
186 211

	
187 212
int main() {
188 213
  check_concepts();
189 214

	
190
  check_graph<ListGraph>();
191
  check_graph<SmartGraph>();
215
  check_graph_counts<ListGraph>();
216
  check_graph_counts<SmartGraph>();
217

	
218
  check_graph_validity_erase<ListGraph>();
219
  check_graph_validity<SmartGraph>();
192 220

	
193 221
//   {
194 222
//     FullGraph g(5);
195 223
//     check_item_counts(g, 5, 10);
196 224
//   }
197 225

	
198 226
//   {
199 227
//     GridGraph g(5, 6);
200 228
//     check_item_counts(g, 30, 49);
201 229
//     checkGridGraph(g, 5, 6);
202 230
//   }
203 231

	
204 232
  std::cout << __FILE__ ": All tests passed.\n";
205 233

	
206 234
  return 0;
207 235
}
0 comments (0 inline)