gravatar
deba@inf.elte.hu
deba@inf.elte.hu
Item validity checking for ListGraph and SmartGraph
0 3 0
default
3 files changed with 211 insertions and 46 deletions:
↑ Collapse diff ↑
Show white space 48 line context
... ...
@@ -131,48 +131,58 @@
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

	
... ...
@@ -198,78 +208,79 @@
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 261
      first_free_arc = n;      
251

	
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
    }
... ...
@@ -329,48 +340,68 @@
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) { 
... ...
@@ -924,48 +955,63 @@
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

	
... ...
@@ -992,76 +1038,78 @@
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) {
... ...
@@ -1136,48 +1184,75 @@
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); 
Show white space 48 line context
... ...
@@ -94,48 +94,55 @@
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:
... ...
@@ -240,48 +247,66 @@
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)
... ...
@@ -529,48 +554,58 @@
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
    }
... ...
@@ -621,48 +656,75 @@
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()) {
Show white space 48 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>();    
... ...
@@ -61,147 +61,175 @@
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)