gravatar
kpeter (Peter Kovacs)
kpeter@inf.elte.hu
Add a resize() function to HypercubeGraph (#311) just like the similar functions in other static graph structures, and extend the test files to check these functions.
0 3 0
default
3 files changed with 38 insertions and 1 deletions:
↑ Collapse diff ↑
Ignore white space 6 line context
... ...
@@ -242,115 +242,131 @@
242 242
      return (arc._id & 1) == 1;
243 243
    }
244 244

	
245 245
    static Arc direct(Edge edge, bool dir) {
246 246
      return Arc((edge._id << 1) | (dir ? 1 : 0));
247 247
    }
248 248

	
249 249
    int dimension() const {
250 250
      return _dim;
251 251
    }
252 252

	
253 253
    bool projection(Node node, int n) const {
254 254
      return static_cast<bool>(node._id & (1 << n));
255 255
    }
256 256

	
257 257
    int dimension(Edge edge) const {
258 258
      return edge._id >> (_dim-1);
259 259
    }
260 260

	
261 261
    int dimension(Arc arc) const {
262 262
      return arc._id >> _dim;
263 263
    }
264 264

	
265 265
    int index(Node node) const {
266 266
      return node._id;
267 267
    }
268 268

	
269 269
    Node operator()(int ix) const {
270 270
      return Node(ix);
271 271
    }
272 272

	
273 273
  private:
274 274
    int _dim;
275 275
    int _node_num, _edge_num;
276 276
  };
277 277

	
278 278

	
279 279
  typedef GraphExtender<HypercubeGraphBase> ExtendedHypercubeGraphBase;
280 280

	
281 281
  /// \ingroup graphs
282 282
  ///
283 283
  /// \brief Hypercube graph class
284 284
  ///
285 285
  /// HypercubeGraph implements a special graph type. The nodes of the
286 286
  /// graph are indexed with integers having at most \c dim binary digits.
287 287
  /// Two nodes are connected in the graph if and only if their indices
288 288
  /// differ only on one position in the binary form.
289 289
  /// This class is completely static and it needs constant memory space.
290
  /// Thus you can neither add nor delete nodes or edges.
290
  /// Thus you can neither add nor delete nodes or edges, however 
291
  /// the structure can be resized using resize().
291 292
  ///
292 293
  /// This type fully conforms to the \ref concepts::Graph "Graph concept".
293 294
  /// Most of its member functions and nested classes are documented
294 295
  /// only in the concept class.
295 296
  ///
296 297
  /// \note The type of the indices is chosen to \c int for efficiency
297 298
  /// reasons. Thus the maximum dimension of this implementation is 26
298 299
  /// (assuming that the size of \c int is 32 bit).
299 300
  class HypercubeGraph : public ExtendedHypercubeGraphBase {
300 301
    typedef ExtendedHypercubeGraphBase Parent;
301 302

	
302 303
  public:
303 304

	
304 305
    /// \brief Constructs a hypercube graph with \c dim dimensions.
305 306
    ///
306 307
    /// Constructs a hypercube graph with \c dim dimensions.
307 308
    HypercubeGraph(int dim) { construct(dim); }
308 309

	
310
    /// \brief Resizes the graph
311
    ///
312
    /// This function resizes the graph. It fully destroys and
313
    /// rebuilds the structure, therefore the maps of the graph will be
314
    /// reallocated automatically and the previous values will be lost.
315
    void resize(int dim) {
316
      Parent::notifier(Arc()).clear();
317
      Parent::notifier(Edge()).clear();
318
      Parent::notifier(Node()).clear();
319
      construct(dim);
320
      Parent::notifier(Node()).build();
321
      Parent::notifier(Edge()).build();
322
      Parent::notifier(Arc()).build();
323
    }
324

	
309 325
    /// \brief The number of dimensions.
310 326
    ///
311 327
    /// Gives back the number of dimensions.
312 328
    int dimension() const {
313 329
      return Parent::dimension();
314 330
    }
315 331

	
316 332
    /// \brief Returns \c true if the n'th bit of the node is one.
317 333
    ///
318 334
    /// Returns \c true if the n'th bit of the node is one.
319 335
    bool projection(Node node, int n) const {
320 336
      return Parent::projection(node, n);
321 337
    }
322 338

	
323 339
    /// \brief The dimension id of an edge.
324 340
    ///
325 341
    /// Gives back the dimension id of the given edge.
326 342
    /// It is in the range <tt>[0..dim-1]</tt>.
327 343
    int dimension(Edge edge) const {
328 344
      return Parent::dimension(edge);
329 345
    }
330 346

	
331 347
    /// \brief The dimension id of an arc.
332 348
    ///
333 349
    /// Gives back the dimension id of the given arc.
334 350
    /// It is in the range <tt>[0..dim-1]</tt>.
335 351
    int dimension(Arc arc) const {
336 352
      return Parent::dimension(arc);
337 353
    }
338 354

	
339 355
    /// \brief The index of a node.
340 356
    ///
341 357
    /// Gives back the index of the given node.
342 358
    /// The lower bits of the integer describes the node.
343 359
    int index(Node node) const {
344 360
      return Parent::index(node);
345 361
    }
346 362

	
347 363
    /// \brief Gives back a node by its index.
348 364
    ///
349 365
    /// Gives back a node by its index.
350 366
    Node operator()(int ix) const {
351 367
      return Parent::operator()(ix);
352 368
    }
353 369

	
354 370
    /// \brief Number of nodes.
355 371
    int nodeNum() const { return Parent::nodeNum(); }
356 372
    /// \brief Number of edges.
Ignore white space 6 line context
... ...
@@ -333,97 +333,102 @@
333 333
  Node
334 334
    n1 = g.addNode(),
335 335
    n2 = g.addNode(),
336 336
    n3 = g.addNode();
337 337

	
338 338
  Arc
339 339
    e1 = g.addArc(n1, n2),
340 340
    e2 = g.addArc(n2, n3);
341 341

	
342 342
  check(g.valid(n1), "Wrong validity check");
343 343
  check(g.valid(e1), "Wrong validity check");
344 344

	
345 345
  check(!g.valid(g.nodeFromId(-1)), "Wrong validity check");
346 346
  check(!g.valid(g.arcFromId(-1)), "Wrong validity check");
347 347
}
348 348

	
349 349
template <typename Digraph>
350 350
void checkDigraphValidityErase() {
351 351
  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
352 352
  Digraph g;
353 353

	
354 354
  Node
355 355
    n1 = g.addNode(),
356 356
    n2 = g.addNode(),
357 357
    n3 = g.addNode();
358 358

	
359 359
  Arc
360 360
    e1 = g.addArc(n1, n2),
361 361
    e2 = g.addArc(n2, n3);
362 362

	
363 363
  check(g.valid(n1), "Wrong validity check");
364 364
  check(g.valid(e1), "Wrong validity check");
365 365

	
366 366
  g.erase(n1);
367 367

	
368 368
  check(!g.valid(n1), "Wrong validity check");
369 369
  check(g.valid(n2), "Wrong validity check");
370 370
  check(g.valid(n3), "Wrong validity check");
371 371
  check(!g.valid(e1), "Wrong validity check");
372 372
  check(g.valid(e2), "Wrong validity check");
373 373

	
374 374
  check(!g.valid(g.nodeFromId(-1)), "Wrong validity check");
375 375
  check(!g.valid(g.arcFromId(-1)), "Wrong validity check");
376 376
}
377 377

	
378 378
void checkFullDigraph(int num) {
379 379
  typedef FullDigraph Digraph;
380 380
  DIGRAPH_TYPEDEFS(Digraph);
381

	
381 382
  Digraph G(num);
383
  check(G.nodeNum() == num && G.arcNum() == num * num, "Wrong size");
384

	
385
  G.resize(num);
386
  check(G.nodeNum() == num && G.arcNum() == num * num, "Wrong size");
382 387

	
383 388
  checkGraphNodeList(G, num);
384 389
  checkGraphArcList(G, num * num);
385 390

	
386 391
  for (NodeIt n(G); n != INVALID; ++n) {
387 392
    checkGraphOutArcList(G, n, num);
388 393
    checkGraphInArcList(G, n, num);
389 394
  }
390 395

	
391 396
  checkGraphConArcList(G, num * num);
392 397

	
393 398
  checkNodeIds(G);
394 399
  checkArcIds(G);
395 400
  checkGraphNodeMap(G);
396 401
  checkGraphArcMap(G);
397 402

	
398 403
  for (int i = 0; i < G.nodeNum(); ++i) {
399 404
    check(G.index(G(i)) == i, "Wrong index");
400 405
  }
401 406

	
402 407
  for (NodeIt s(G); s != INVALID; ++s) {
403 408
    for (NodeIt t(G); t != INVALID; ++t) {
404 409
      Arc a = G.arc(s, t);
405 410
      check(G.source(a) == s && G.target(a) == t, "Wrong arc lookup");
406 411
    }
407 412
  }
408 413
}
409 414

	
410 415
void checkDigraphs() {
411 416
  { // Checking ListDigraph
412 417
    checkDigraphBuild<ListDigraph>();
413 418
    checkDigraphSplit<ListDigraph>();
414 419
    checkDigraphAlter<ListDigraph>();
415 420
    checkDigraphErase<ListDigraph>();
416 421
    checkDigraphSnapshot<ListDigraph>();
417 422
    checkDigraphValidityErase<ListDigraph>();
418 423
  }
419 424
  { // Checking SmartDigraph
420 425
    checkDigraphBuild<SmartDigraph>();
421 426
    checkDigraphSplit<SmartDigraph>();
422 427
    checkDigraphSnapshot<SmartDigraph>();
423 428
    checkDigraphValidity<SmartDigraph>();
424 429
  }
425 430
  { // Checking FullDigraph
426 431
    checkFullDigraph(8);
427 432
  }
428 433
}
429 434

	
Ignore white space 96 line context
... ...
@@ -225,96 +225,103 @@
225 225
  typename Graph::Snapshot snapshot(G);
226 226

	
227 227
  Node n = G.addNode();
228 228
  G.addEdge(n3, n);
229 229
  G.addEdge(n, n3);
230 230
  G.addEdge(n3, n2);
231 231

	
232 232
  checkGraphNodeList(G, 4);
233 233
  checkGraphEdgeList(G, 6);
234 234
  checkGraphArcList(G, 12);
235 235

	
236 236
  snapshot.restore();
237 237

	
238 238
  checkGraphNodeList(G, 3);
239 239
  checkGraphEdgeList(G, 3);
240 240
  checkGraphArcList(G, 6);
241 241

	
242 242
  checkGraphIncEdgeArcLists(G, n1, 2);
243 243
  checkGraphIncEdgeArcLists(G, n2, 3);
244 244
  checkGraphIncEdgeArcLists(G, n3, 1);
245 245

	
246 246
  checkGraphConEdgeList(G, 3);
247 247
  checkGraphConArcList(G, 6);
248 248

	
249 249
  checkNodeIds(G);
250 250
  checkEdgeIds(G);
251 251
  checkArcIds(G);
252 252
  checkGraphNodeMap(G);
253 253
  checkGraphEdgeMap(G);
254 254
  checkGraphArcMap(G);
255 255

	
256 256
  G.addNode();
257 257
  snapshot.save(G);
258 258

	
259 259
  G.addEdge(G.addNode(), G.addNode());
260 260

	
261 261
  snapshot.restore();
262 262

	
263 263
  checkGraphNodeList(G, 4);
264 264
  checkGraphEdgeList(G, 3);
265 265
  checkGraphArcList(G, 6);
266 266
}
267 267

	
268 268
void checkFullGraph(int num) {
269 269
  typedef FullGraph Graph;
270 270
  GRAPH_TYPEDEFS(Graph);
271 271

	
272 272
  Graph G(num);
273
  check(G.nodeNum() == num && G.edgeNum() == num * (num - 1) / 2,
274
        "Wrong size");
275

	
276
  G.resize(num);
277
  check(G.nodeNum() == num && G.edgeNum() == num * (num - 1) / 2,
278
        "Wrong size");
279

	
273 280
  checkGraphNodeList(G, num);
274 281
  checkGraphEdgeList(G, num * (num - 1) / 2);
275 282

	
276 283
  for (NodeIt n(G); n != INVALID; ++n) {
277 284
    checkGraphOutArcList(G, n, num - 1);
278 285
    checkGraphInArcList(G, n, num - 1);
279 286
    checkGraphIncEdgeList(G, n, num - 1);
280 287
  }
281 288

	
282 289
  checkGraphConArcList(G, num * (num - 1));
283 290
  checkGraphConEdgeList(G, num * (num - 1) / 2);
284 291

	
285 292
  checkArcDirections(G);
286 293

	
287 294
  checkNodeIds(G);
288 295
  checkArcIds(G);
289 296
  checkEdgeIds(G);
290 297
  checkGraphNodeMap(G);
291 298
  checkGraphArcMap(G);
292 299
  checkGraphEdgeMap(G);
293 300

	
294 301

	
295 302
  for (int i = 0; i < G.nodeNum(); ++i) {
296 303
    check(G.index(G(i)) == i, "Wrong index");
297 304
  }
298 305

	
299 306
  for (NodeIt u(G); u != INVALID; ++u) {
300 307
    for (NodeIt v(G); v != INVALID; ++v) {
301 308
      Edge e = G.edge(u, v);
302 309
      Arc a = G.arc(u, v);
303 310
      if (u == v) {
304 311
        check(e == INVALID, "Wrong edge lookup");
305 312
        check(a == INVALID, "Wrong arc lookup");
306 313
      } else {
307 314
        check((G.u(e) == u && G.v(e) == v) ||
308 315
              (G.u(e) == v && G.v(e) == u), "Wrong edge lookup");
309 316
        check(G.source(a) == u && G.target(a) == v, "Wrong arc lookup");
310 317
      }
311 318
    }
312 319
  }
313 320
}
314 321

	
315 322
void checkConcepts() {
316 323
  { // Checking graph components
317 324
    checkConcept<BaseGraphComponent, BaseGraphComponent >();
318 325

	
319 326
    checkConcept<IDableGraphComponent<>,
320 327
      IDableGraphComponent<> >();
... ...
@@ -369,171 +376,180 @@
369 376
  check(g.valid(n1), "Wrong validity check");
370 377
  check(g.valid(e1), "Wrong validity check");
371 378
  check(g.valid(g.direct(e1, true)), "Wrong validity check");
372 379

	
373 380
  check(!g.valid(g.nodeFromId(-1)), "Wrong validity check");
374 381
  check(!g.valid(g.edgeFromId(-1)), "Wrong validity check");
375 382
  check(!g.valid(g.arcFromId(-1)), "Wrong validity check");
376 383
}
377 384

	
378 385
template <typename Graph>
379 386
void checkGraphValidityErase() {
380 387
  TEMPLATE_GRAPH_TYPEDEFS(Graph);
381 388
  Graph g;
382 389

	
383 390
  Node
384 391
    n1 = g.addNode(),
385 392
    n2 = g.addNode(),
386 393
    n3 = g.addNode();
387 394

	
388 395
  Edge
389 396
    e1 = g.addEdge(n1, n2),
390 397
    e2 = g.addEdge(n2, n3);
391 398

	
392 399
  check(g.valid(n1), "Wrong validity check");
393 400
  check(g.valid(e1), "Wrong validity check");
394 401
  check(g.valid(g.direct(e1, true)), "Wrong validity check");
395 402

	
396 403
  g.erase(n1);
397 404

	
398 405
  check(!g.valid(n1), "Wrong validity check");
399 406
  check(g.valid(n2), "Wrong validity check");
400 407
  check(g.valid(n3), "Wrong validity check");
401 408
  check(!g.valid(e1), "Wrong validity check");
402 409
  check(g.valid(e2), "Wrong validity check");
403 410

	
404 411
  check(!g.valid(g.nodeFromId(-1)), "Wrong validity check");
405 412
  check(!g.valid(g.edgeFromId(-1)), "Wrong validity check");
406 413
  check(!g.valid(g.arcFromId(-1)), "Wrong validity check");
407 414
}
408 415

	
409 416
void checkGridGraph(int width, int height) {
410 417
  typedef GridGraph Graph;
411 418
  GRAPH_TYPEDEFS(Graph);
412 419
  Graph G(width, height);
413 420

	
414 421
  check(G.width() == width, "Wrong column number");
415 422
  check(G.height() == height, "Wrong row number");
416 423

	
424
  G.resize(width, height);
425
  check(G.width() == width, "Wrong column number");
426
  check(G.height() == height, "Wrong row number");
427

	
417 428
  for (int i = 0; i < width; ++i) {
418 429
    for (int j = 0; j < height; ++j) {
419 430
      check(G.col(G(i, j)) == i, "Wrong column");
420 431
      check(G.row(G(i, j)) == j, "Wrong row");
421 432
      check(G.pos(G(i, j)).x == i, "Wrong column");
422 433
      check(G.pos(G(i, j)).y == j, "Wrong row");
423 434
    }
424 435
  }
425 436

	
426 437
  for (int j = 0; j < height; ++j) {
427 438
    for (int i = 0; i < width - 1; ++i) {
428 439
      check(G.source(G.right(G(i, j))) == G(i, j), "Wrong right");
429 440
      check(G.target(G.right(G(i, j))) == G(i + 1, j), "Wrong right");
430 441
    }
431 442
    check(G.right(G(width - 1, j)) == INVALID, "Wrong right");
432 443
  }
433 444

	
434 445
  for (int j = 0; j < height; ++j) {
435 446
    for (int i = 1; i < width; ++i) {
436 447
      check(G.source(G.left(G(i, j))) == G(i, j), "Wrong left");
437 448
      check(G.target(G.left(G(i, j))) == G(i - 1, j), "Wrong left");
438 449
    }
439 450
    check(G.left(G(0, j)) == INVALID, "Wrong left");
440 451
  }
441 452

	
442 453
  for (int i = 0; i < width; ++i) {
443 454
    for (int j = 0; j < height - 1; ++j) {
444 455
      check(G.source(G.up(G(i, j))) == G(i, j), "Wrong up");
445 456
      check(G.target(G.up(G(i, j))) == G(i, j + 1), "Wrong up");
446 457
    }
447 458
    check(G.up(G(i, height - 1)) == INVALID, "Wrong up");
448 459
  }
449 460

	
450 461
  for (int i = 0; i < width; ++i) {
451 462
    for (int j = 1; j < height; ++j) {
452 463
      check(G.source(G.down(G(i, j))) == G(i, j), "Wrong down");
453 464
      check(G.target(G.down(G(i, j))) == G(i, j - 1), "Wrong down");
454 465
    }
455 466
    check(G.down(G(i, 0)) == INVALID, "Wrong down");
456 467
  }
457 468

	
458 469
  checkGraphNodeList(G, width * height);
459 470
  checkGraphEdgeList(G, width * (height - 1) + (width - 1) * height);
460 471
  checkGraphArcList(G, 2 * (width * (height - 1) + (width - 1) * height));
461 472

	
462 473
  for (NodeIt n(G); n != INVALID; ++n) {
463 474
    int nb = 4;
464 475
    if (G.col(n) == 0) --nb;
465 476
    if (G.col(n) == width - 1) --nb;
466 477
    if (G.row(n) == 0) --nb;
467 478
    if (G.row(n) == height - 1) --nb;
468 479

	
469 480
    checkGraphOutArcList(G, n, nb);
470 481
    checkGraphInArcList(G, n, nb);
471 482
    checkGraphIncEdgeList(G, n, nb);
472 483
  }
473 484

	
474 485
  checkArcDirections(G);
475 486

	
476 487
  checkGraphConArcList(G, 2 * (width * (height - 1) + (width - 1) * height));
477 488
  checkGraphConEdgeList(G, width * (height - 1) + (width - 1) * height);
478 489

	
479 490
  checkNodeIds(G);
480 491
  checkArcIds(G);
481 492
  checkEdgeIds(G);
482 493
  checkGraphNodeMap(G);
483 494
  checkGraphArcMap(G);
484 495
  checkGraphEdgeMap(G);
485 496

	
486 497
}
487 498

	
488 499
void checkHypercubeGraph(int dim) {
489 500
  GRAPH_TYPEDEFS(HypercubeGraph);
490 501

	
491 502
  HypercubeGraph G(dim);
503
  check(G.dimension() == dim, "Wrong dimension");
504

	
505
  G.resize(dim);
506
  check(G.dimension() == dim, "Wrong dimension");
507
  
492 508
  checkGraphNodeList(G, 1 << dim);
493 509
  checkGraphEdgeList(G, dim * (1 << (dim-1)));
494 510
  checkGraphArcList(G, dim * (1 << dim));
495 511

	
496 512
  Node n = G.nodeFromId(dim);
497 513

	
498 514
  for (NodeIt n(G); n != INVALID; ++n) {
499 515
    checkGraphIncEdgeList(G, n, dim);
500 516
    for (IncEdgeIt e(G, n); e != INVALID; ++e) {
501 517
      check( (G.u(e) == n &&
502 518
              G.id(G.v(e)) == (G.id(n) ^ (1 << G.dimension(e)))) ||
503 519
             (G.v(e) == n &&
504 520
              G.id(G.u(e)) == (G.id(n) ^ (1 << G.dimension(e)))),
505 521
             "Wrong edge or wrong dimension");
506 522
    }
507 523

	
508 524
    checkGraphOutArcList(G, n, dim);
509 525
    for (OutArcIt a(G, n); a != INVALID; ++a) {
510 526
      check(G.source(a) == n &&
511 527
            G.id(G.target(a)) == (G.id(n) ^ (1 << G.dimension(a))),
512 528
            "Wrong arc or wrong dimension");
513 529
    }
514 530

	
515 531
    checkGraphInArcList(G, n, dim);
516 532
    for (InArcIt a(G, n); a != INVALID; ++a) {
517 533
      check(G.target(a) == n &&
518 534
            G.id(G.source(a)) == (G.id(n) ^ (1 << G.dimension(a))),
519 535
            "Wrong arc or wrong dimension");
520 536
    }
521 537
  }
522 538

	
523 539
  checkGraphConArcList(G, (1 << dim) * dim);
524 540
  checkGraphConEdgeList(G, dim * (1 << (dim-1)));
525 541

	
526 542
  checkArcDirections(G);
527 543

	
528 544
  checkNodeIds(G);
529 545
  checkArcIds(G);
530 546
  checkEdgeIds(G);
531 547
  checkGraphNodeMap(G);
532 548
  checkGraphArcMap(G);
533 549
  checkGraphEdgeMap(G);
534 550
}
535 551

	
536 552
void checkGraphs() {
537 553
  { // Checking ListGraph
538 554
    checkGraphBuild<ListGraph>();
539 555
    checkGraphAlter<ListGraph>();
0 comments (0 inline)