gravatar
kpeter (Peter Kovacs)
kpeter@inf.elte.hu
Add a warning for List(Di)Graph::Snapshot (#311) and extend tests for snapshots
0 3 0
default
3 files changed with 23 insertions and 0 deletions:
↑ Collapse diff ↑
Ignore white space 768 line context
... ...
@@ -370,768 +370,771 @@
370 370

	
371 371
    /// Node validity check
372 372

	
373 373
    /// This function gives back \c true if the given node is valid,
374 374
    /// i.e. it is a real node of the digraph.
375 375
    ///
376 376
    /// \warning A removed node could become valid again if new nodes are
377 377
    /// added to the digraph.
378 378
    bool valid(Node n) const { return Parent::valid(n); }
379 379

	
380 380
    /// Arc validity check
381 381

	
382 382
    /// This function gives back \c true if the given arc is valid,
383 383
    /// i.e. it is a real arc of the digraph.
384 384
    ///
385 385
    /// \warning A removed arc could become valid again if new arcs are
386 386
    /// added to the digraph.
387 387
    bool valid(Arc a) const { return Parent::valid(a); }
388 388

	
389 389
    /// Change the target node of an arc
390 390

	
391 391
    /// This function changes the target node of the given arc \c a to \c n.
392 392
    ///
393 393
    ///\note \c ArcIt and \c OutArcIt iterators referencing the changed
394 394
    ///arc remain valid, however \c InArcIt iterators are invalidated.
395 395
    ///
396 396
    ///\warning This functionality cannot be used together with the Snapshot
397 397
    ///feature.
398 398
    void changeTarget(Arc a, Node n) {
399 399
      Parent::changeTarget(a,n);
400 400
    }
401 401
    /// Change the source node of an arc
402 402

	
403 403
    /// This function changes the source node of the given arc \c a to \c n.
404 404
    ///
405 405
    ///\note \c InArcIt iterators referencing the changed arc remain
406 406
    ///valid, however \c ArcIt and \c OutArcIt iterators are invalidated.
407 407
    ///
408 408
    ///\warning This functionality cannot be used together with the Snapshot
409 409
    ///feature.
410 410
    void changeSource(Arc a, Node n) {
411 411
      Parent::changeSource(a,n);
412 412
    }
413 413

	
414 414
    /// Reverse the direction of an arc.
415 415

	
416 416
    /// This function reverses the direction of the given arc.
417 417
    ///\note \c ArcIt, \c OutArcIt and \c InArcIt iterators referencing
418 418
    ///the changed arc are invalidated.
419 419
    ///
420 420
    ///\warning This functionality cannot be used together with the Snapshot
421 421
    ///feature.
422 422
    void reverseArc(Arc a) {
423 423
      Node t=target(a);
424 424
      changeTarget(a,source(a));
425 425
      changeSource(a,t);
426 426
    }
427 427

	
428 428
    ///Contract two nodes.
429 429

	
430 430
    ///This function contracts the given two nodes.
431 431
    ///Node \c v is removed, but instead of deleting its
432 432
    ///incident arcs, they are joined to node \c u.
433 433
    ///If the last parameter \c r is \c true (this is the default value),
434 434
    ///then the newly created loops are removed.
435 435
    ///
436 436
    ///\note The moved arcs are joined to node \c u using changeSource()
437 437
    ///or changeTarget(), thus \c ArcIt and \c OutArcIt iterators are
438 438
    ///invalidated for the outgoing arcs of node \c v and \c InArcIt
439 439
    ///iterators are invalidated for the incomming arcs of \c v.
440 440
    ///Moreover all iterators referencing node \c v or the removed 
441 441
    ///loops are also invalidated. Other iterators remain valid.
442 442
    ///
443 443
    ///\warning This functionality cannot be used together with the Snapshot
444 444
    ///feature.
445 445
    void contract(Node u, Node v, bool r = true)
446 446
    {
447 447
      for(OutArcIt e(*this,v);e!=INVALID;) {
448 448
        OutArcIt f=e;
449 449
        ++f;
450 450
        if(r && target(e)==u) erase(e);
451 451
        else changeSource(e,u);
452 452
        e=f;
453 453
      }
454 454
      for(InArcIt e(*this,v);e!=INVALID;) {
455 455
        InArcIt f=e;
456 456
        ++f;
457 457
        if(r && source(e)==u) erase(e);
458 458
        else changeTarget(e,u);
459 459
        e=f;
460 460
      }
461 461
      erase(v);
462 462
    }
463 463

	
464 464
    ///Split a node.
465 465

	
466 466
    ///This function splits the given node. First, a new node is added
467 467
    ///to the digraph, then the source of each outgoing arc of node \c n
468 468
    ///is moved to this new node.
469 469
    ///If the second parameter \c connect is \c true (this is the default
470 470
    ///value), then a new arc from node \c n to the newly created node
471 471
    ///is also added.
472 472
    ///\return The newly created node.
473 473
    ///
474 474
    ///\note All iterators remain valid.
475 475
    ///
476 476
    ///\warning This functionality cannot be used together with the
477 477
    ///Snapshot feature.
478 478
    Node split(Node n, bool connect = true) {
479 479
      Node b = addNode();
480 480
      nodes[b.id].first_out=nodes[n.id].first_out;
481 481
      nodes[n.id].first_out=-1;
482 482
      for(int i=nodes[b.id].first_out; i!=-1; i=arcs[i].next_out) {
483 483
        arcs[i].source=b.id;
484 484
      }
485 485
      if (connect) addArc(n,b);
486 486
      return b;
487 487
    }
488 488

	
489 489
    ///Split an arc.
490 490

	
491 491
    ///This function splits the given arc. First, a new node \c v is
492 492
    ///added to the digraph, then the target node of the original arc
493 493
    ///is set to \c v. Finally, an arc from \c v to the original target
494 494
    ///is added.
495 495
    ///\return The newly created node.
496 496
    ///
497 497
    ///\note \c InArcIt iterators referencing the original arc are
498 498
    ///invalidated. Other iterators remain valid.
499 499
    ///
500 500
    ///\warning This functionality cannot be used together with the
501 501
    ///Snapshot feature.
502 502
    Node split(Arc a) {
503 503
      Node v = addNode();
504 504
      addArc(v,target(a));
505 505
      changeTarget(a,v);
506 506
      return v;
507 507
    }
508 508

	
509 509
    ///Clear the digraph.
510 510

	
511 511
    ///This function erases all nodes and arcs from the digraph.
512 512
    ///
513 513
    void clear() {
514 514
      Parent::clear();
515 515
    }
516 516

	
517 517
    /// Reserve memory for nodes.
518 518

	
519 519
    /// Using this function, it is possible to avoid superfluous memory
520 520
    /// allocation: if you know that the digraph you want to build will
521 521
    /// be large (e.g. it will contain millions of nodes and/or arcs),
522 522
    /// then it is worth reserving space for this amount before starting
523 523
    /// to build the digraph.
524 524
    /// \sa reserveArc()
525 525
    void reserveNode(int n) { nodes.reserve(n); };
526 526

	
527 527
    /// Reserve memory for arcs.
528 528

	
529 529
    /// Using this function, it is possible to avoid superfluous memory
530 530
    /// allocation: if you know that the digraph you want to build will
531 531
    /// be large (e.g. it will contain millions of nodes and/or arcs),
532 532
    /// then it is worth reserving space for this amount before starting
533 533
    /// to build the digraph.
534 534
    /// \sa reserveNode()
535 535
    void reserveArc(int m) { arcs.reserve(m); };
536 536

	
537 537
    /// \brief Class to make a snapshot of the digraph and restore
538 538
    /// it later.
539 539
    ///
540 540
    /// Class to make a snapshot of the digraph and restore it later.
541 541
    ///
542 542
    /// The newly added nodes and arcs can be removed using the
543 543
    /// restore() function.
544 544
    ///
545 545
    /// \note After a state is restored, you cannot restore a later state, 
546 546
    /// i.e. you cannot add the removed nodes and arcs again using
547 547
    /// another Snapshot instance.
548 548
    ///
549 549
    /// \warning Node and arc deletions and other modifications (e.g.
550 550
    /// reversing, contracting, splitting arcs or nodes) cannot be
551 551
    /// restored. These events invalidate the snapshot.
552 552
    /// However the arcs and nodes that were added to the digraph after
553 553
    /// making the current snapshot can be removed without invalidating it.
554 554
    class Snapshot {
555 555
    protected:
556 556

	
557 557
      typedef Parent::NodeNotifier NodeNotifier;
558 558

	
559 559
      class NodeObserverProxy : public NodeNotifier::ObserverBase {
560 560
      public:
561 561

	
562 562
        NodeObserverProxy(Snapshot& _snapshot)
563 563
          : snapshot(_snapshot) {}
564 564

	
565 565
        using NodeNotifier::ObserverBase::attach;
566 566
        using NodeNotifier::ObserverBase::detach;
567 567
        using NodeNotifier::ObserverBase::attached;
568 568

	
569 569
      protected:
570 570

	
571 571
        virtual void add(const Node& node) {
572 572
          snapshot.addNode(node);
573 573
        }
574 574
        virtual void add(const std::vector<Node>& nodes) {
575 575
          for (int i = nodes.size() - 1; i >= 0; ++i) {
576 576
            snapshot.addNode(nodes[i]);
577 577
          }
578 578
        }
579 579
        virtual void erase(const Node& node) {
580 580
          snapshot.eraseNode(node);
581 581
        }
582 582
        virtual void erase(const std::vector<Node>& nodes) {
583 583
          for (int i = 0; i < int(nodes.size()); ++i) {
584 584
            snapshot.eraseNode(nodes[i]);
585 585
          }
586 586
        }
587 587
        virtual void build() {
588 588
          Node node;
589 589
          std::vector<Node> nodes;
590 590
          for (notifier()->first(node); node != INVALID;
591 591
               notifier()->next(node)) {
592 592
            nodes.push_back(node);
593 593
          }
594 594
          for (int i = nodes.size() - 1; i >= 0; --i) {
595 595
            snapshot.addNode(nodes[i]);
596 596
          }
597 597
        }
598 598
        virtual void clear() {
599 599
          Node node;
600 600
          for (notifier()->first(node); node != INVALID;
601 601
               notifier()->next(node)) {
602 602
            snapshot.eraseNode(node);
603 603
          }
604 604
        }
605 605

	
606 606
        Snapshot& snapshot;
607 607
      };
608 608

	
609 609
      class ArcObserverProxy : public ArcNotifier::ObserverBase {
610 610
      public:
611 611

	
612 612
        ArcObserverProxy(Snapshot& _snapshot)
613 613
          : snapshot(_snapshot) {}
614 614

	
615 615
        using ArcNotifier::ObserverBase::attach;
616 616
        using ArcNotifier::ObserverBase::detach;
617 617
        using ArcNotifier::ObserverBase::attached;
618 618

	
619 619
      protected:
620 620

	
621 621
        virtual void add(const Arc& arc) {
622 622
          snapshot.addArc(arc);
623 623
        }
624 624
        virtual void add(const std::vector<Arc>& arcs) {
625 625
          for (int i = arcs.size() - 1; i >= 0; ++i) {
626 626
            snapshot.addArc(arcs[i]);
627 627
          }
628 628
        }
629 629
        virtual void erase(const Arc& arc) {
630 630
          snapshot.eraseArc(arc);
631 631
        }
632 632
        virtual void erase(const std::vector<Arc>& arcs) {
633 633
          for (int i = 0; i < int(arcs.size()); ++i) {
634 634
            snapshot.eraseArc(arcs[i]);
635 635
          }
636 636
        }
637 637
        virtual void build() {
638 638
          Arc arc;
639 639
          std::vector<Arc> arcs;
640 640
          for (notifier()->first(arc); arc != INVALID;
641 641
               notifier()->next(arc)) {
642 642
            arcs.push_back(arc);
643 643
          }
644 644
          for (int i = arcs.size() - 1; i >= 0; --i) {
645 645
            snapshot.addArc(arcs[i]);
646 646
          }
647 647
        }
648 648
        virtual void clear() {
649 649
          Arc arc;
650 650
          for (notifier()->first(arc); arc != INVALID;
651 651
               notifier()->next(arc)) {
652 652
            snapshot.eraseArc(arc);
653 653
          }
654 654
        }
655 655

	
656 656
        Snapshot& snapshot;
657 657
      };
658 658

	
659 659
      ListDigraph *digraph;
660 660

	
661 661
      NodeObserverProxy node_observer_proxy;
662 662
      ArcObserverProxy arc_observer_proxy;
663 663

	
664 664
      std::list<Node> added_nodes;
665 665
      std::list<Arc> added_arcs;
666 666

	
667 667

	
668 668
      void addNode(const Node& node) {
669 669
        added_nodes.push_front(node);
670 670
      }
671 671
      void eraseNode(const Node& node) {
672 672
        std::list<Node>::iterator it =
673 673
          std::find(added_nodes.begin(), added_nodes.end(), node);
674 674
        if (it == added_nodes.end()) {
675 675
          clear();
676 676
          arc_observer_proxy.detach();
677 677
          throw NodeNotifier::ImmediateDetach();
678 678
        } else {
679 679
          added_nodes.erase(it);
680 680
        }
681 681
      }
682 682

	
683 683
      void addArc(const Arc& arc) {
684 684
        added_arcs.push_front(arc);
685 685
      }
686 686
      void eraseArc(const Arc& arc) {
687 687
        std::list<Arc>::iterator it =
688 688
          std::find(added_arcs.begin(), added_arcs.end(), arc);
689 689
        if (it == added_arcs.end()) {
690 690
          clear();
691 691
          node_observer_proxy.detach();
692 692
          throw ArcNotifier::ImmediateDetach();
693 693
        } else {
694 694
          added_arcs.erase(it);
695 695
        }
696 696
      }
697 697

	
698 698
      void attach(ListDigraph &_digraph) {
699 699
        digraph = &_digraph;
700 700
        node_observer_proxy.attach(digraph->notifier(Node()));
701 701
        arc_observer_proxy.attach(digraph->notifier(Arc()));
702 702
      }
703 703

	
704 704
      void detach() {
705 705
        node_observer_proxy.detach();
706 706
        arc_observer_proxy.detach();
707 707
      }
708 708

	
709 709
      bool attached() const {
710 710
        return node_observer_proxy.attached();
711 711
      }
712 712

	
713 713
      void clear() {
714 714
        added_nodes.clear();
715 715
        added_arcs.clear();
716 716
      }
717 717

	
718 718
    public:
719 719

	
720 720
      /// \brief Default constructor.
721 721
      ///
722 722
      /// Default constructor.
723 723
      /// You have to call save() to actually make a snapshot.
724 724
      Snapshot()
725 725
        : digraph(0), node_observer_proxy(*this),
726 726
          arc_observer_proxy(*this) {}
727 727

	
728 728
      /// \brief Constructor that immediately makes a snapshot.
729 729
      ///
730 730
      /// This constructor immediately makes a snapshot of the given digraph.
731 731
      Snapshot(ListDigraph &gr)
732 732
        : node_observer_proxy(*this),
733 733
          arc_observer_proxy(*this) {
734 734
        attach(gr);
735 735
      }
736 736

	
737 737
      /// \brief Make a snapshot.
738 738
      ///
739 739
      /// This function makes a snapshot of the given digraph.
740 740
      /// It can be called more than once. In case of a repeated
741 741
      /// call, the previous snapshot gets lost.
742 742
      void save(ListDigraph &gr) {
743 743
        if (attached()) {
744 744
          detach();
745 745
          clear();
746 746
        }
747 747
        attach(gr);
748 748
      }
749 749

	
750 750
      /// \brief Undo the changes until the last snapshot.
751 751
      ///
752 752
      /// This function undos the changes until the last snapshot
753 753
      /// created by save() or Snapshot(ListDigraph&).
754
      ///
755
      /// \warning This method invalidates the snapshot, i.e. repeated
756
      /// restoring is not supported unless you call save() again.
754 757
      void restore() {
755 758
        detach();
756 759
        for(std::list<Arc>::iterator it = added_arcs.begin();
757 760
            it != added_arcs.end(); ++it) {
758 761
          digraph->erase(*it);
759 762
        }
760 763
        for(std::list<Node>::iterator it = added_nodes.begin();
761 764
            it != added_nodes.end(); ++it) {
762 765
          digraph->erase(*it);
763 766
        }
764 767
        clear();
765 768
      }
766 769

	
767 770
      /// \brief Returns \c true if the snapshot is valid.
768 771
      ///
769 772
      /// This function returns \c true if the snapshot is valid.
770 773
      bool valid() const {
771 774
        return attached();
772 775
      }
773 776
    };
774 777

	
775 778
  };
776 779

	
777 780
  ///@}
778 781

	
779 782
  class ListGraphBase {
780 783

	
781 784
  protected:
782 785

	
783 786
    struct NodeT {
784 787
      int first_out;
785 788
      int prev, next;
786 789
    };
787 790

	
788 791
    struct ArcT {
789 792
      int target;
790 793
      int prev_out, next_out;
791 794
    };
792 795

	
793 796
    std::vector<NodeT> nodes;
794 797

	
795 798
    int first_node;
796 799

	
797 800
    int first_free_node;
798 801

	
799 802
    std::vector<ArcT> arcs;
800 803

	
801 804
    int first_free_arc;
802 805

	
803 806
  public:
804 807

	
805 808
    typedef ListGraphBase Graph;
806 809

	
807 810
    class Node {
808 811
      friend class ListGraphBase;
809 812
    protected:
810 813

	
811 814
      int id;
812 815
      explicit Node(int pid) { id = pid;}
813 816

	
814 817
    public:
815 818
      Node() {}
816 819
      Node (Invalid) { id = -1; }
817 820
      bool operator==(const Node& node) const {return id == node.id;}
818 821
      bool operator!=(const Node& node) const {return id != node.id;}
819 822
      bool operator<(const Node& node) const {return id < node.id;}
820 823
    };
821 824

	
822 825
    class Edge {
823 826
      friend class ListGraphBase;
824 827
    protected:
825 828

	
826 829
      int id;
827 830
      explicit Edge(int pid) { id = pid;}
828 831

	
829 832
    public:
830 833
      Edge() {}
831 834
      Edge (Invalid) { id = -1; }
832 835
      bool operator==(const Edge& edge) const {return id == edge.id;}
833 836
      bool operator!=(const Edge& edge) const {return id != edge.id;}
834 837
      bool operator<(const Edge& edge) const {return id < edge.id;}
835 838
    };
836 839

	
837 840
    class Arc {
838 841
      friend class ListGraphBase;
839 842
    protected:
840 843

	
841 844
      int id;
842 845
      explicit Arc(int pid) { id = pid;}
843 846

	
844 847
    public:
845 848
      operator Edge() const {
846 849
        return id != -1 ? edgeFromId(id / 2) : INVALID;
847 850
      }
848 851

	
849 852
      Arc() {}
850 853
      Arc (Invalid) { id = -1; }
851 854
      bool operator==(const Arc& arc) const {return id == arc.id;}
852 855
      bool operator!=(const Arc& arc) const {return id != arc.id;}
853 856
      bool operator<(const Arc& arc) const {return id < arc.id;}
854 857
    };
855 858

	
856 859
    ListGraphBase()
857 860
      : nodes(), first_node(-1),
858 861
        first_free_node(-1), arcs(), first_free_arc(-1) {}
859 862

	
860 863

	
861 864
    int maxNodeId() const { return nodes.size()-1; }
862 865
    int maxEdgeId() const { return arcs.size() / 2 - 1; }
863 866
    int maxArcId() const { return arcs.size()-1; }
864 867

	
865 868
    Node source(Arc e) const { return Node(arcs[e.id ^ 1].target); }
866 869
    Node target(Arc e) const { return Node(arcs[e.id].target); }
867 870

	
868 871
    Node u(Edge e) const { return Node(arcs[2 * e.id].target); }
869 872
    Node v(Edge e) const { return Node(arcs[2 * e.id + 1].target); }
870 873

	
871 874
    static bool direction(Arc e) {
872 875
      return (e.id & 1) == 1;
873 876
    }
874 877

	
875 878
    static Arc direct(Edge e, bool d) {
876 879
      return Arc(e.id * 2 + (d ? 1 : 0));
877 880
    }
878 881

	
879 882
    void first(Node& node) const {
880 883
      node.id = first_node;
881 884
    }
882 885

	
883 886
    void next(Node& node) const {
884 887
      node.id = nodes[node.id].next;
885 888
    }
886 889

	
887 890
    void first(Arc& e) const {
888 891
      int n = first_node;
889 892
      while (n != -1 && nodes[n].first_out == -1) {
890 893
        n = nodes[n].next;
891 894
      }
892 895
      e.id = (n == -1) ? -1 : nodes[n].first_out;
893 896
    }
894 897

	
895 898
    void next(Arc& e) const {
896 899
      if (arcs[e.id].next_out != -1) {
897 900
        e.id = arcs[e.id].next_out;
898 901
      } else {
899 902
        int n = nodes[arcs[e.id ^ 1].target].next;
900 903
        while(n != -1 && nodes[n].first_out == -1) {
901 904
          n = nodes[n].next;
902 905
        }
903 906
        e.id = (n == -1) ? -1 : nodes[n].first_out;
904 907
      }
905 908
    }
906 909

	
907 910
    void first(Edge& e) const {
908 911
      int n = first_node;
909 912
      while (n != -1) {
910 913
        e.id = nodes[n].first_out;
911 914
        while ((e.id & 1) != 1) {
912 915
          e.id = arcs[e.id].next_out;
913 916
        }
914 917
        if (e.id != -1) {
915 918
          e.id /= 2;
916 919
          return;
917 920
        }
918 921
        n = nodes[n].next;
919 922
      }
920 923
      e.id = -1;
921 924
    }
922 925

	
923 926
    void next(Edge& e) const {
924 927
      int n = arcs[e.id * 2].target;
925 928
      e.id = arcs[(e.id * 2) | 1].next_out;
926 929
      while ((e.id & 1) != 1) {
927 930
        e.id = arcs[e.id].next_out;
928 931
      }
929 932
      if (e.id != -1) {
930 933
        e.id /= 2;
931 934
        return;
932 935
      }
933 936
      n = nodes[n].next;
934 937
      while (n != -1) {
935 938
        e.id = nodes[n].first_out;
936 939
        while ((e.id & 1) != 1) {
937 940
          e.id = arcs[e.id].next_out;
938 941
        }
939 942
        if (e.id != -1) {
940 943
          e.id /= 2;
941 944
          return;
942 945
        }
943 946
        n = nodes[n].next;
944 947
      }
945 948
      e.id = -1;
946 949
    }
947 950

	
948 951
    void firstOut(Arc &e, const Node& v) const {
949 952
      e.id = nodes[v.id].first_out;
950 953
    }
951 954
    void nextOut(Arc &e) const {
952 955
      e.id = arcs[e.id].next_out;
953 956
    }
954 957

	
955 958
    void firstIn(Arc &e, const Node& v) const {
956 959
      e.id = ((nodes[v.id].first_out) ^ 1);
957 960
      if (e.id == -2) e.id = -1;
958 961
    }
959 962
    void nextIn(Arc &e) const {
960 963
      e.id = ((arcs[e.id ^ 1].next_out) ^ 1);
961 964
      if (e.id == -2) e.id = -1;
962 965
    }
963 966

	
964 967
    void firstInc(Edge &e, bool& d, const Node& v) const {
965 968
      int a = nodes[v.id].first_out;
966 969
      if (a != -1 ) {
967 970
        e.id = a / 2;
968 971
        d = ((a & 1) == 1);
969 972
      } else {
970 973
        e.id = -1;
971 974
        d = true;
972 975
      }
973 976
    }
974 977
    void nextInc(Edge &e, bool& d) const {
975 978
      int a = (arcs[(e.id * 2) | (d ? 1 : 0)].next_out);
976 979
      if (a != -1 ) {
977 980
        e.id = a / 2;
978 981
        d = ((a & 1) == 1);
979 982
      } else {
980 983
        e.id = -1;
981 984
        d = true;
982 985
      }
983 986
    }
984 987

	
985 988
    static int id(Node v) { return v.id; }
986 989
    static int id(Arc e) { return e.id; }
987 990
    static int id(Edge e) { return e.id; }
988 991

	
989 992
    static Node nodeFromId(int id) { return Node(id);}
990 993
    static Arc arcFromId(int id) { return Arc(id);}
991 994
    static Edge edgeFromId(int id) { return Edge(id);}
992 995

	
993 996
    bool valid(Node n) const {
994 997
      return n.id >= 0 && n.id < static_cast<int>(nodes.size()) &&
995 998
        nodes[n.id].prev != -2;
996 999
    }
997 1000

	
998 1001
    bool valid(Arc a) const {
999 1002
      return a.id >= 0 && a.id < static_cast<int>(arcs.size()) &&
1000 1003
        arcs[a.id].prev_out != -2;
1001 1004
    }
1002 1005

	
1003 1006
    bool valid(Edge e) const {
1004 1007
      return e.id >= 0 && 2 * e.id < static_cast<int>(arcs.size()) &&
1005 1008
        arcs[2 * e.id].prev_out != -2;
1006 1009
    }
1007 1010

	
1008 1011
    Node addNode() {
1009 1012
      int n;
1010 1013

	
1011 1014
      if(first_free_node==-1) {
1012 1015
        n = nodes.size();
1013 1016
        nodes.push_back(NodeT());
1014 1017
      } else {
1015 1018
        n = first_free_node;
1016 1019
        first_free_node = nodes[n].next;
1017 1020
      }
1018 1021

	
1019 1022
      nodes[n].next = first_node;
1020 1023
      if (first_node != -1) nodes[first_node].prev = n;
1021 1024
      first_node = n;
1022 1025
      nodes[n].prev = -1;
1023 1026

	
1024 1027
      nodes[n].first_out = -1;
1025 1028

	
1026 1029
      return Node(n);
1027 1030
    }
1028 1031

	
1029 1032
    Edge addEdge(Node u, Node v) {
1030 1033
      int n;
1031 1034

	
1032 1035
      if (first_free_arc == -1) {
1033 1036
        n = arcs.size();
1034 1037
        arcs.push_back(ArcT());
1035 1038
        arcs.push_back(ArcT());
1036 1039
      } else {
1037 1040
        n = first_free_arc;
1038 1041
        first_free_arc = arcs[n].next_out;
1039 1042
      }
1040 1043

	
1041 1044
      arcs[n].target = u.id;
1042 1045
      arcs[n | 1].target = v.id;
1043 1046

	
1044 1047
      arcs[n].next_out = nodes[v.id].first_out;
1045 1048
      if (nodes[v.id].first_out != -1) {
1046 1049
        arcs[nodes[v.id].first_out].prev_out = n;
1047 1050
      }
1048 1051
      arcs[n].prev_out = -1;
1049 1052
      nodes[v.id].first_out = n;
1050 1053

	
1051 1054
      arcs[n | 1].next_out = nodes[u.id].first_out;
1052 1055
      if (nodes[u.id].first_out != -1) {
1053 1056
        arcs[nodes[u.id].first_out].prev_out = (n | 1);
1054 1057
      }
1055 1058
      arcs[n | 1].prev_out = -1;
1056 1059
      nodes[u.id].first_out = (n | 1);
1057 1060

	
1058 1061
      return Edge(n / 2);
1059 1062
    }
1060 1063

	
1061 1064
    void erase(const Node& node) {
1062 1065
      int n = node.id;
1063 1066

	
1064 1067
      if(nodes[n].next != -1) {
1065 1068
        nodes[nodes[n].next].prev = nodes[n].prev;
1066 1069
      }
1067 1070

	
1068 1071
      if(nodes[n].prev != -1) {
1069 1072
        nodes[nodes[n].prev].next = nodes[n].next;
1070 1073
      } else {
1071 1074
        first_node = nodes[n].next;
1072 1075
      }
1073 1076

	
1074 1077
      nodes[n].next = first_free_node;
1075 1078
      first_free_node = n;
1076 1079
      nodes[n].prev = -2;
1077 1080
    }
1078 1081

	
1079 1082
    void erase(const Edge& edge) {
1080 1083
      int n = edge.id * 2;
1081 1084

	
1082 1085
      if (arcs[n].next_out != -1) {
1083 1086
        arcs[arcs[n].next_out].prev_out = arcs[n].prev_out;
1084 1087
      }
1085 1088

	
1086 1089
      if (arcs[n].prev_out != -1) {
1087 1090
        arcs[arcs[n].prev_out].next_out = arcs[n].next_out;
1088 1091
      } else {
1089 1092
        nodes[arcs[n | 1].target].first_out = arcs[n].next_out;
1090 1093
      }
1091 1094

	
1092 1095
      if (arcs[n | 1].next_out != -1) {
1093 1096
        arcs[arcs[n | 1].next_out].prev_out = arcs[n | 1].prev_out;
1094 1097
      }
1095 1098

	
1096 1099
      if (arcs[n | 1].prev_out != -1) {
1097 1100
        arcs[arcs[n | 1].prev_out].next_out = arcs[n | 1].next_out;
1098 1101
      } else {
1099 1102
        nodes[arcs[n].target].first_out = arcs[n | 1].next_out;
1100 1103
      }
1101 1104

	
1102 1105
      arcs[n].next_out = first_free_arc;
1103 1106
      first_free_arc = n;
1104 1107
      arcs[n].prev_out = -2;
1105 1108
      arcs[n | 1].prev_out = -2;
1106 1109

	
1107 1110
    }
1108 1111

	
1109 1112
    void clear() {
1110 1113
      arcs.clear();
1111 1114
      nodes.clear();
1112 1115
      first_node = first_free_node = first_free_arc = -1;
1113 1116
    }
1114 1117

	
1115 1118
  protected:
1116 1119

	
1117 1120
    void changeV(Edge e, Node n) {
1118 1121
      if(arcs[2 * e.id].next_out != -1) {
1119 1122
        arcs[arcs[2 * e.id].next_out].prev_out = arcs[2 * e.id].prev_out;
1120 1123
      }
1121 1124
      if(arcs[2 * e.id].prev_out != -1) {
1122 1125
        arcs[arcs[2 * e.id].prev_out].next_out =
1123 1126
          arcs[2 * e.id].next_out;
1124 1127
      } else {
1125 1128
        nodes[arcs[(2 * e.id) | 1].target].first_out =
1126 1129
          arcs[2 * e.id].next_out;
1127 1130
      }
1128 1131

	
1129 1132
      if (nodes[n.id].first_out != -1) {
1130 1133
        arcs[nodes[n.id].first_out].prev_out = 2 * e.id;
1131 1134
      }
1132 1135
      arcs[(2 * e.id) | 1].target = n.id;
1133 1136
      arcs[2 * e.id].prev_out = -1;
1134 1137
      arcs[2 * e.id].next_out = nodes[n.id].first_out;
1135 1138
      nodes[n.id].first_out = 2 * e.id;
1136 1139
    }
1137 1140

	
... ...
@@ -1169,411 +1172,414 @@
1169 1172

	
1170 1173
  ///\ref ListGraph is a versatile and fast undirected graph
1171 1174
  ///implementation based on linked lists that are stored in
1172 1175
  ///\c std::vector structures.
1173 1176
  ///
1174 1177
  ///This type fully conforms to the \ref concepts::Graph "Graph concept"
1175 1178
  ///and it also provides several useful additional functionalities.
1176 1179
  ///Most of its member functions and nested classes are documented
1177 1180
  ///only in the concept class.
1178 1181
  ///
1179 1182
  ///\sa concepts::Graph
1180 1183
  ///\sa ListDigraph
1181 1184
  class ListGraph : public ExtendedListGraphBase {
1182 1185
    typedef ExtendedListGraphBase Parent;
1183 1186

	
1184 1187
  private:
1185 1188
    /// Graphs are \e not copy constructible. Use GraphCopy instead.
1186 1189
    ListGraph(const ListGraph &) :ExtendedListGraphBase()  {};
1187 1190
    /// \brief Assignment of a graph to another one is \e not allowed.
1188 1191
    /// Use GraphCopy instead.
1189 1192
    void operator=(const ListGraph &) {}
1190 1193
  public:
1191 1194
    /// Constructor
1192 1195

	
1193 1196
    /// Constructor.
1194 1197
    ///
1195 1198
    ListGraph() {}
1196 1199

	
1197 1200
    typedef Parent::OutArcIt IncEdgeIt;
1198 1201

	
1199 1202
    /// \brief Add a new node to the graph.
1200 1203
    ///
1201 1204
    /// This function adds a new node to the graph.
1202 1205
    /// \return The new node.
1203 1206
    Node addNode() { return Parent::addNode(); }
1204 1207

	
1205 1208
    /// \brief Add a new edge to the graph.
1206 1209
    ///
1207 1210
    /// This function adds a new edge to the graph between nodes
1208 1211
    /// \c u and \c v with inherent orientation from node \c u to
1209 1212
    /// node \c v.
1210 1213
    /// \return The new edge.
1211 1214
    Edge addEdge(Node u, Node v) {
1212 1215
      return Parent::addEdge(u, v);
1213 1216
    }
1214 1217

	
1215 1218
    ///\brief Erase a node from the graph.
1216 1219
    ///
1217 1220
    /// This function erases the given node from the graph.
1218 1221
    void erase(Node n) { Parent::erase(n); }
1219 1222

	
1220 1223
    ///\brief Erase an edge from the graph.
1221 1224
    ///
1222 1225
    /// This function erases the given edge from the graph.
1223 1226
    void erase(Edge e) { Parent::erase(e); }
1224 1227
    /// Node validity check
1225 1228

	
1226 1229
    /// This function gives back \c true if the given node is valid,
1227 1230
    /// i.e. it is a real node of the graph.
1228 1231
    ///
1229 1232
    /// \warning A removed node could become valid again if new nodes are
1230 1233
    /// added to the graph.
1231 1234
    bool valid(Node n) const { return Parent::valid(n); }
1232 1235
    /// Edge validity check
1233 1236

	
1234 1237
    /// This function gives back \c true if the given edge is valid,
1235 1238
    /// i.e. it is a real edge of the graph.
1236 1239
    ///
1237 1240
    /// \warning A removed edge could become valid again if new edges are
1238 1241
    /// added to the graph.
1239 1242
    bool valid(Edge e) const { return Parent::valid(e); }
1240 1243
    /// Arc validity check
1241 1244

	
1242 1245
    /// This function gives back \c true if the given arc is valid,
1243 1246
    /// i.e. it is a real arc of the graph.
1244 1247
    ///
1245 1248
    /// \warning A removed arc could become valid again if new edges are
1246 1249
    /// added to the graph.
1247 1250
    bool valid(Arc a) const { return Parent::valid(a); }
1248 1251

	
1249 1252
    /// \brief Change the first node of an edge.
1250 1253
    ///
1251 1254
    /// This function changes the first node of the given edge \c e to \c n.
1252 1255
    ///
1253 1256
    ///\note \c EdgeIt and \c ArcIt iterators referencing the
1254 1257
    ///changed edge are invalidated and all other iterators whose
1255 1258
    ///base node is the changed node are also invalidated.
1256 1259
    ///
1257 1260
    ///\warning This functionality cannot be used together with the
1258 1261
    ///Snapshot feature.
1259 1262
    void changeU(Edge e, Node n) {
1260 1263
      Parent::changeU(e,n);
1261 1264
    }
1262 1265
    /// \brief Change the second node of an edge.
1263 1266
    ///
1264 1267
    /// This function changes the second node of the given edge \c e to \c n.
1265 1268
    ///
1266 1269
    ///\note \c EdgeIt iterators referencing the changed edge remain
1267 1270
    ///valid, however \c ArcIt iterators referencing the changed edge and
1268 1271
    ///all other iterators whose base node is the changed node are also
1269 1272
    ///invalidated.
1270 1273
    ///
1271 1274
    ///\warning This functionality cannot be used together with the
1272 1275
    ///Snapshot feature.
1273 1276
    void changeV(Edge e, Node n) {
1274 1277
      Parent::changeV(e,n);
1275 1278
    }
1276 1279

	
1277 1280
    /// \brief Contract two nodes.
1278 1281
    ///
1279 1282
    /// This function contracts the given two nodes.
1280 1283
    /// Node \c b is removed, but instead of deleting
1281 1284
    /// its incident edges, they are joined to node \c a.
1282 1285
    /// If the last parameter \c r is \c true (this is the default value),
1283 1286
    /// then the newly created loops are removed.
1284 1287
    ///
1285 1288
    /// \note The moved edges are joined to node \c a using changeU()
1286 1289
    /// or changeV(), thus all edge and arc iterators whose base node is
1287 1290
    /// \c b are invalidated.
1288 1291
    /// Moreover all iterators referencing node \c b or the removed 
1289 1292
    /// loops are also invalidated. Other iterators remain valid.
1290 1293
    ///
1291 1294
    ///\warning This functionality cannot be used together with the
1292 1295
    ///Snapshot feature.
1293 1296
    void contract(Node a, Node b, bool r = true) {
1294 1297
      for(IncEdgeIt e(*this, b); e!=INVALID;) {
1295 1298
        IncEdgeIt f = e; ++f;
1296 1299
        if (r && runningNode(e) == a) {
1297 1300
          erase(e);
1298 1301
        } else if (u(e) == b) {
1299 1302
          changeU(e, a);
1300 1303
        } else {
1301 1304
          changeV(e, a);
1302 1305
        }
1303 1306
        e = f;
1304 1307
      }
1305 1308
      erase(b);
1306 1309
    }
1307 1310

	
1308 1311
    ///Clear the graph.
1309 1312

	
1310 1313
    ///This function erases all nodes and arcs from the graph.
1311 1314
    ///
1312 1315
    void clear() {
1313 1316
      Parent::clear();
1314 1317
    }
1315 1318

	
1316 1319
    /// Reserve memory for nodes.
1317 1320

	
1318 1321
    /// Using this function, it is possible to avoid superfluous memory
1319 1322
    /// allocation: if you know that the graph you want to build will
1320 1323
    /// be large (e.g. it will contain millions of nodes and/or edges),
1321 1324
    /// then it is worth reserving space for this amount before starting
1322 1325
    /// to build the graph.
1323 1326
    /// \sa reserveEdge()
1324 1327
    void reserveNode(int n) { nodes.reserve(n); };
1325 1328

	
1326 1329
    /// Reserve memory for edges.
1327 1330

	
1328 1331
    /// Using this function, it is possible to avoid superfluous memory
1329 1332
    /// allocation: if you know that the graph you want to build will
1330 1333
    /// be large (e.g. it will contain millions of nodes and/or edges),
1331 1334
    /// then it is worth reserving space for this amount before starting
1332 1335
    /// to build the graph.
1333 1336
    /// \sa reserveNode()
1334 1337
    void reserveEdge(int m) { arcs.reserve(2 * m); };
1335 1338

	
1336 1339
    /// \brief Class to make a snapshot of the graph and restore
1337 1340
    /// it later.
1338 1341
    ///
1339 1342
    /// Class to make a snapshot of the graph and restore it later.
1340 1343
    ///
1341 1344
    /// The newly added nodes and edges can be removed
1342 1345
    /// using the restore() function.
1343 1346
    ///
1344 1347
    /// \note After a state is restored, you cannot restore a later state, 
1345 1348
    /// i.e. you cannot add the removed nodes and edges again using
1346 1349
    /// another Snapshot instance.
1347 1350
    ///
1348 1351
    /// \warning Node and edge deletions and other modifications
1349 1352
    /// (e.g. changing the end-nodes of edges or contracting nodes)
1350 1353
    /// cannot be restored. These events invalidate the snapshot.
1351 1354
    /// However the edges and nodes that were added to the graph after
1352 1355
    /// making the current snapshot can be removed without invalidating it.
1353 1356
    class Snapshot {
1354 1357
    protected:
1355 1358

	
1356 1359
      typedef Parent::NodeNotifier NodeNotifier;
1357 1360

	
1358 1361
      class NodeObserverProxy : public NodeNotifier::ObserverBase {
1359 1362
      public:
1360 1363

	
1361 1364
        NodeObserverProxy(Snapshot& _snapshot)
1362 1365
          : snapshot(_snapshot) {}
1363 1366

	
1364 1367
        using NodeNotifier::ObserverBase::attach;
1365 1368
        using NodeNotifier::ObserverBase::detach;
1366 1369
        using NodeNotifier::ObserverBase::attached;
1367 1370

	
1368 1371
      protected:
1369 1372

	
1370 1373
        virtual void add(const Node& node) {
1371 1374
          snapshot.addNode(node);
1372 1375
        }
1373 1376
        virtual void add(const std::vector<Node>& nodes) {
1374 1377
          for (int i = nodes.size() - 1; i >= 0; ++i) {
1375 1378
            snapshot.addNode(nodes[i]);
1376 1379
          }
1377 1380
        }
1378 1381
        virtual void erase(const Node& node) {
1379 1382
          snapshot.eraseNode(node);
1380 1383
        }
1381 1384
        virtual void erase(const std::vector<Node>& nodes) {
1382 1385
          for (int i = 0; i < int(nodes.size()); ++i) {
1383 1386
            snapshot.eraseNode(nodes[i]);
1384 1387
          }
1385 1388
        }
1386 1389
        virtual void build() {
1387 1390
          Node node;
1388 1391
          std::vector<Node> nodes;
1389 1392
          for (notifier()->first(node); node != INVALID;
1390 1393
               notifier()->next(node)) {
1391 1394
            nodes.push_back(node);
1392 1395
          }
1393 1396
          for (int i = nodes.size() - 1; i >= 0; --i) {
1394 1397
            snapshot.addNode(nodes[i]);
1395 1398
          }
1396 1399
        }
1397 1400
        virtual void clear() {
1398 1401
          Node node;
1399 1402
          for (notifier()->first(node); node != INVALID;
1400 1403
               notifier()->next(node)) {
1401 1404
            snapshot.eraseNode(node);
1402 1405
          }
1403 1406
        }
1404 1407

	
1405 1408
        Snapshot& snapshot;
1406 1409
      };
1407 1410

	
1408 1411
      class EdgeObserverProxy : public EdgeNotifier::ObserverBase {
1409 1412
      public:
1410 1413

	
1411 1414
        EdgeObserverProxy(Snapshot& _snapshot)
1412 1415
          : snapshot(_snapshot) {}
1413 1416

	
1414 1417
        using EdgeNotifier::ObserverBase::attach;
1415 1418
        using EdgeNotifier::ObserverBase::detach;
1416 1419
        using EdgeNotifier::ObserverBase::attached;
1417 1420

	
1418 1421
      protected:
1419 1422

	
1420 1423
        virtual void add(const Edge& edge) {
1421 1424
          snapshot.addEdge(edge);
1422 1425
        }
1423 1426
        virtual void add(const std::vector<Edge>& edges) {
1424 1427
          for (int i = edges.size() - 1; i >= 0; ++i) {
1425 1428
            snapshot.addEdge(edges[i]);
1426 1429
          }
1427 1430
        }
1428 1431
        virtual void erase(const Edge& edge) {
1429 1432
          snapshot.eraseEdge(edge);
1430 1433
        }
1431 1434
        virtual void erase(const std::vector<Edge>& edges) {
1432 1435
          for (int i = 0; i < int(edges.size()); ++i) {
1433 1436
            snapshot.eraseEdge(edges[i]);
1434 1437
          }
1435 1438
        }
1436 1439
        virtual void build() {
1437 1440
          Edge edge;
1438 1441
          std::vector<Edge> edges;
1439 1442
          for (notifier()->first(edge); edge != INVALID;
1440 1443
               notifier()->next(edge)) {
1441 1444
            edges.push_back(edge);
1442 1445
          }
1443 1446
          for (int i = edges.size() - 1; i >= 0; --i) {
1444 1447
            snapshot.addEdge(edges[i]);
1445 1448
          }
1446 1449
        }
1447 1450
        virtual void clear() {
1448 1451
          Edge edge;
1449 1452
          for (notifier()->first(edge); edge != INVALID;
1450 1453
               notifier()->next(edge)) {
1451 1454
            snapshot.eraseEdge(edge);
1452 1455
          }
1453 1456
        }
1454 1457

	
1455 1458
        Snapshot& snapshot;
1456 1459
      };
1457 1460

	
1458 1461
      ListGraph *graph;
1459 1462

	
1460 1463
      NodeObserverProxy node_observer_proxy;
1461 1464
      EdgeObserverProxy edge_observer_proxy;
1462 1465

	
1463 1466
      std::list<Node> added_nodes;
1464 1467
      std::list<Edge> added_edges;
1465 1468

	
1466 1469

	
1467 1470
      void addNode(const Node& node) {
1468 1471
        added_nodes.push_front(node);
1469 1472
      }
1470 1473
      void eraseNode(const Node& node) {
1471 1474
        std::list<Node>::iterator it =
1472 1475
          std::find(added_nodes.begin(), added_nodes.end(), node);
1473 1476
        if (it == added_nodes.end()) {
1474 1477
          clear();
1475 1478
          edge_observer_proxy.detach();
1476 1479
          throw NodeNotifier::ImmediateDetach();
1477 1480
        } else {
1478 1481
          added_nodes.erase(it);
1479 1482
        }
1480 1483
      }
1481 1484

	
1482 1485
      void addEdge(const Edge& edge) {
1483 1486
        added_edges.push_front(edge);
1484 1487
      }
1485 1488
      void eraseEdge(const Edge& edge) {
1486 1489
        std::list<Edge>::iterator it =
1487 1490
          std::find(added_edges.begin(), added_edges.end(), edge);
1488 1491
        if (it == added_edges.end()) {
1489 1492
          clear();
1490 1493
          node_observer_proxy.detach();
1491 1494
          throw EdgeNotifier::ImmediateDetach();
1492 1495
        } else {
1493 1496
          added_edges.erase(it);
1494 1497
        }
1495 1498
      }
1496 1499

	
1497 1500
      void attach(ListGraph &_graph) {
1498 1501
        graph = &_graph;
1499 1502
        node_observer_proxy.attach(graph->notifier(Node()));
1500 1503
        edge_observer_proxy.attach(graph->notifier(Edge()));
1501 1504
      }
1502 1505

	
1503 1506
      void detach() {
1504 1507
        node_observer_proxy.detach();
1505 1508
        edge_observer_proxy.detach();
1506 1509
      }
1507 1510

	
1508 1511
      bool attached() const {
1509 1512
        return node_observer_proxy.attached();
1510 1513
      }
1511 1514

	
1512 1515
      void clear() {
1513 1516
        added_nodes.clear();
1514 1517
        added_edges.clear();
1515 1518
      }
1516 1519

	
1517 1520
    public:
1518 1521

	
1519 1522
      /// \brief Default constructor.
1520 1523
      ///
1521 1524
      /// Default constructor.
1522 1525
      /// You have to call save() to actually make a snapshot.
1523 1526
      Snapshot()
1524 1527
        : graph(0), node_observer_proxy(*this),
1525 1528
          edge_observer_proxy(*this) {}
1526 1529

	
1527 1530
      /// \brief Constructor that immediately makes a snapshot.
1528 1531
      ///
1529 1532
      /// This constructor immediately makes a snapshot of the given graph.
1530 1533
      Snapshot(ListGraph &gr)
1531 1534
        : node_observer_proxy(*this),
1532 1535
          edge_observer_proxy(*this) {
1533 1536
        attach(gr);
1534 1537
      }
1535 1538

	
1536 1539
      /// \brief Make a snapshot.
1537 1540
      ///
1538 1541
      /// This function makes a snapshot of the given graph.
1539 1542
      /// It can be called more than once. In case of a repeated
1540 1543
      /// call, the previous snapshot gets lost.
1541 1544
      void save(ListGraph &gr) {
1542 1545
        if (attached()) {
1543 1546
          detach();
1544 1547
          clear();
1545 1548
        }
1546 1549
        attach(gr);
1547 1550
      }
1548 1551

	
1549 1552
      /// \brief Undo the changes until the last snapshot.
1550 1553
      ///
1551 1554
      /// This function undos the changes until the last snapshot
1552 1555
      /// created by save() or Snapshot(ListGraph&).
1556
      ///
1557
      /// \warning This method invalidates the snapshot, i.e. repeated
1558
      /// restoring is not supported unless you call save() again.
1553 1559
      void restore() {
1554 1560
        detach();
1555 1561
        for(std::list<Edge>::iterator it = added_edges.begin();
1556 1562
            it != added_edges.end(); ++it) {
1557 1563
          graph->erase(*it);
1558 1564
        }
1559 1565
        for(std::list<Node>::iterator it = added_nodes.begin();
1560 1566
            it != added_nodes.end(); ++it) {
1561 1567
          graph->erase(*it);
1562 1568
        }
1563 1569
        clear();
1564 1570
      }
1565 1571

	
1566 1572
      /// \brief Returns \c true if the snapshot is valid.
1567 1573
      ///
1568 1574
      /// This function returns \c true if the snapshot is valid.
1569 1575
      bool valid() const {
1570 1576
        return attached();
1571 1577
      }
1572 1578
    };
1573 1579
  };
1574 1580

	
1575 1581
  /// @}
1576 1582
} //namespace lemon
1577 1583

	
1578 1584

	
1579 1585
#endif
Ignore white space 768 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5 5
 * Copyright (C) 2003-2009
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/digraph.h>
20 20
#include <lemon/list_graph.h>
21 21
#include <lemon/smart_graph.h>
22 22
#include <lemon/full_graph.h>
23 23

	
24 24
#include "test_tools.h"
25 25
#include "graph_test.h"
26 26

	
27 27
using namespace lemon;
28 28
using namespace lemon::concepts;
29 29

	
30 30
template <class Digraph>
31 31
void checkDigraphBuild() {
32 32
  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
33 33
  Digraph G;
34 34

	
35 35
  checkGraphNodeList(G, 0);
36 36
  checkGraphArcList(G, 0);
37 37

	
38 38
  G.reserveNode(3);
39 39
  G.reserveArc(4);
40 40

	
41 41
  Node
42 42
    n1 = G.addNode(),
43 43
    n2 = G.addNode(),
44 44
    n3 = G.addNode();
45 45
  checkGraphNodeList(G, 3);
46 46
  checkGraphArcList(G, 0);
47 47

	
48 48
  Arc a1 = G.addArc(n1, n2);
49 49
  check(G.source(a1) == n1 && G.target(a1) == n2, "Wrong arc");
50 50
  checkGraphNodeList(G, 3);
51 51
  checkGraphArcList(G, 1);
52 52

	
53 53
  checkGraphOutArcList(G, n1, 1);
54 54
  checkGraphOutArcList(G, n2, 0);
55 55
  checkGraphOutArcList(G, n3, 0);
56 56

	
57 57
  checkGraphInArcList(G, n1, 0);
58 58
  checkGraphInArcList(G, n2, 1);
59 59
  checkGraphInArcList(G, n3, 0);
60 60

	
61 61
  checkGraphConArcList(G, 1);
62 62

	
63 63
  Arc a2 = G.addArc(n2, n1),
64 64
      a3 = G.addArc(n2, n3),
65 65
      a4 = G.addArc(n2, n3);
66 66

	
67 67
  checkGraphNodeList(G, 3);
68 68
  checkGraphArcList(G, 4);
69 69

	
70 70
  checkGraphOutArcList(G, n1, 1);
71 71
  checkGraphOutArcList(G, n2, 3);
72 72
  checkGraphOutArcList(G, n3, 0);
73 73

	
74 74
  checkGraphInArcList(G, n1, 1);
75 75
  checkGraphInArcList(G, n2, 1);
76 76
  checkGraphInArcList(G, n3, 2);
77 77

	
78 78
  checkGraphConArcList(G, 4);
79 79

	
80 80
  checkNodeIds(G);
81 81
  checkArcIds(G);
82 82
  checkGraphNodeMap(G);
83 83
  checkGraphArcMap(G);
84 84
}
85 85

	
86 86
template <class Digraph>
87 87
void checkDigraphSplit() {
88 88
  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
89 89

	
90 90
  Digraph G;
91 91
  Node n1 = G.addNode(), n2 = G.addNode(), n3 = G.addNode();
92 92
  Arc a1 = G.addArc(n1, n2), a2 = G.addArc(n2, n1),
93 93
      a3 = G.addArc(n2, n3), a4 = G.addArc(n2, n3);
94 94

	
95 95
  Node n4 = G.split(n2);
96 96

	
97 97
  check(G.target(OutArcIt(G, n2)) == n4 &&
98 98
        G.source(InArcIt(G, n4)) == n2,
99 99
        "Wrong split.");
100 100

	
101 101
  checkGraphNodeList(G, 4);
102 102
  checkGraphArcList(G, 5);
103 103

	
104 104
  checkGraphOutArcList(G, n1, 1);
105 105
  checkGraphOutArcList(G, n2, 1);
106 106
  checkGraphOutArcList(G, n3, 0);
107 107
  checkGraphOutArcList(G, n4, 3);
108 108

	
109 109
  checkGraphInArcList(G, n1, 1);
110 110
  checkGraphInArcList(G, n2, 1);
111 111
  checkGraphInArcList(G, n3, 2);
112 112
  checkGraphInArcList(G, n4, 1);
113 113

	
114 114
  checkGraphConArcList(G, 5);
115 115
}
116 116

	
117 117
template <class Digraph>
118 118
void checkDigraphAlter() {
119 119
  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
120 120

	
121 121
  Digraph G;
122 122
  Node n1 = G.addNode(), n2 = G.addNode(),
123 123
       n3 = G.addNode(), n4 = G.addNode();
124 124
  Arc a1 = G.addArc(n1, n2), a2 = G.addArc(n4, n1),
125 125
      a3 = G.addArc(n4, n3), a4 = G.addArc(n4, n3),
126 126
      a5 = G.addArc(n2, n4);
127 127

	
128 128
  checkGraphNodeList(G, 4);
129 129
  checkGraphArcList(G, 5);
130 130

	
131 131
  // Check changeSource() and changeTarget()
132 132
  G.changeTarget(a4, n1);
133 133

	
134 134
  checkGraphNodeList(G, 4);
135 135
  checkGraphArcList(G, 5);
136 136

	
137 137
  checkGraphOutArcList(G, n1, 1);
138 138
  checkGraphOutArcList(G, n2, 1);
139 139
  checkGraphOutArcList(G, n3, 0);
140 140
  checkGraphOutArcList(G, n4, 3);
141 141

	
142 142
  checkGraphInArcList(G, n1, 2);
143 143
  checkGraphInArcList(G, n2, 1);
144 144
  checkGraphInArcList(G, n3, 1);
145 145
  checkGraphInArcList(G, n4, 1);
146 146

	
147 147
  checkGraphConArcList(G, 5);
148 148

	
149 149
  G.changeSource(a4, n3);
150 150

	
151 151
  checkGraphNodeList(G, 4);
152 152
  checkGraphArcList(G, 5);
153 153

	
154 154
  checkGraphOutArcList(G, n1, 1);
155 155
  checkGraphOutArcList(G, n2, 1);
156 156
  checkGraphOutArcList(G, n3, 1);
157 157
  checkGraphOutArcList(G, n4, 2);
158 158

	
159 159
  checkGraphInArcList(G, n1, 2);
160 160
  checkGraphInArcList(G, n2, 1);
161 161
  checkGraphInArcList(G, n3, 1);
162 162
  checkGraphInArcList(G, n4, 1);
163 163

	
164 164
  checkGraphConArcList(G, 5);
165 165

	
166 166
  // Check contract()
167 167
  G.contract(n2, n4, false);
168 168

	
169 169
  checkGraphNodeList(G, 3);
170 170
  checkGraphArcList(G, 5);
171 171

	
172 172
  checkGraphOutArcList(G, n1, 1);
173 173
  checkGraphOutArcList(G, n2, 3);
174 174
  checkGraphOutArcList(G, n3, 1);
175 175

	
176 176
  checkGraphInArcList(G, n1, 2);
177 177
  checkGraphInArcList(G, n2, 2);
178 178
  checkGraphInArcList(G, n3, 1);
179 179

	
180 180
  checkGraphConArcList(G, 5);
181 181

	
182 182
  G.contract(n2, n1);
183 183

	
184 184
  checkGraphNodeList(G, 2);
185 185
  checkGraphArcList(G, 3);
186 186

	
187 187
  checkGraphOutArcList(G, n2, 2);
188 188
  checkGraphOutArcList(G, n3, 1);
189 189

	
190 190
  checkGraphInArcList(G, n2, 2);
191 191
  checkGraphInArcList(G, n3, 1);
192 192

	
193 193
  checkGraphConArcList(G, 3);
194 194
}
195 195

	
196 196
template <class Digraph>
197 197
void checkDigraphErase() {
198 198
  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
199 199

	
200 200
  Digraph G;
201 201
  Node n1 = G.addNode(), n2 = G.addNode(),
202 202
       n3 = G.addNode(), n4 = G.addNode();
203 203
  Arc a1 = G.addArc(n1, n2), a2 = G.addArc(n4, n1),
204 204
      a3 = G.addArc(n4, n3), a4 = G.addArc(n3, n1),
205 205
      a5 = G.addArc(n2, n4);
206 206

	
207 207
  // Check arc deletion
208 208
  G.erase(a1);
209 209

	
210 210
  checkGraphNodeList(G, 4);
211 211
  checkGraphArcList(G, 4);
212 212

	
213 213
  checkGraphOutArcList(G, n1, 0);
214 214
  checkGraphOutArcList(G, n2, 1);
215 215
  checkGraphOutArcList(G, n3, 1);
216 216
  checkGraphOutArcList(G, n4, 2);
217 217

	
218 218
  checkGraphInArcList(G, n1, 2);
219 219
  checkGraphInArcList(G, n2, 0);
220 220
  checkGraphInArcList(G, n3, 1);
221 221
  checkGraphInArcList(G, n4, 1);
222 222

	
223 223
  checkGraphConArcList(G, 4);
224 224

	
225 225
  // Check node deletion
226 226
  G.erase(n4);
227 227

	
228 228
  checkGraphNodeList(G, 3);
229 229
  checkGraphArcList(G, 1);
230 230

	
231 231
  checkGraphOutArcList(G, n1, 0);
232 232
  checkGraphOutArcList(G, n2, 0);
233 233
  checkGraphOutArcList(G, n3, 1);
234 234
  checkGraphOutArcList(G, n4, 0);
235 235

	
236 236
  checkGraphInArcList(G, n1, 1);
237 237
  checkGraphInArcList(G, n2, 0);
238 238
  checkGraphInArcList(G, n3, 0);
239 239
  checkGraphInArcList(G, n4, 0);
240 240

	
241 241
  checkGraphConArcList(G, 1);
242 242
}
243 243

	
244 244

	
245 245
template <class Digraph>
246 246
void checkDigraphSnapshot() {
247 247
  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
248 248

	
249 249
  Digraph G;
250 250
  Node n1 = G.addNode(), n2 = G.addNode(), n3 = G.addNode();
251 251
  Arc a1 = G.addArc(n1, n2), a2 = G.addArc(n2, n1),
252 252
      a3 = G.addArc(n2, n3), a4 = G.addArc(n2, n3);
253 253

	
254 254
  typename Digraph::Snapshot snapshot(G);
255 255

	
256 256
  Node n = G.addNode();
257 257
  G.addArc(n3, n);
258 258
  G.addArc(n, n3);
259 259

	
260 260
  checkGraphNodeList(G, 4);
261 261
  checkGraphArcList(G, 6);
262 262

	
263 263
  snapshot.restore();
264 264

	
265 265
  checkGraphNodeList(G, 3);
266 266
  checkGraphArcList(G, 4);
267 267

	
268 268
  checkGraphOutArcList(G, n1, 1);
269 269
  checkGraphOutArcList(G, n2, 3);
270 270
  checkGraphOutArcList(G, n3, 0);
271 271

	
272 272
  checkGraphInArcList(G, n1, 1);
273 273
  checkGraphInArcList(G, n2, 1);
274 274
  checkGraphInArcList(G, n3, 2);
275 275

	
276 276
  checkGraphConArcList(G, 4);
277 277

	
278 278
  checkNodeIds(G);
279 279
  checkArcIds(G);
280 280
  checkGraphNodeMap(G);
281 281
  checkGraphArcMap(G);
282 282

	
283 283
  G.addNode();
284 284
  snapshot.save(G);
285 285

	
286 286
  G.addArc(G.addNode(), G.addNode());
287 287

	
288 288
  snapshot.restore();
289
  snapshot.save(G);
290

	
291
  checkGraphNodeList(G, 4);
292
  checkGraphArcList(G, 4);
293

	
294
  G.addArc(G.addNode(), G.addNode());
295

	
296
  snapshot.restore();
289 297

	
290 298
  checkGraphNodeList(G, 4);
291 299
  checkGraphArcList(G, 4);
292 300
}
293 301

	
294 302
void checkConcepts() {
295 303
  { // Checking digraph components
296 304
    checkConcept<BaseDigraphComponent, BaseDigraphComponent >();
297 305

	
298 306
    checkConcept<IDableDigraphComponent<>,
299 307
      IDableDigraphComponent<> >();
300 308

	
301 309
    checkConcept<IterableDigraphComponent<>,
302 310
      IterableDigraphComponent<> >();
303 311

	
304 312
    checkConcept<MappableDigraphComponent<>,
305 313
      MappableDigraphComponent<> >();
306 314
  }
307 315
  { // Checking skeleton digraph
308 316
    checkConcept<Digraph, Digraph>();
309 317
  }
310 318
  { // Checking ListDigraph
311 319
    checkConcept<Digraph, ListDigraph>();
312 320
    checkConcept<AlterableDigraphComponent<>, ListDigraph>();
313 321
    checkConcept<ExtendableDigraphComponent<>, ListDigraph>();
314 322
    checkConcept<ClearableDigraphComponent<>, ListDigraph>();
315 323
    checkConcept<ErasableDigraphComponent<>, ListDigraph>();
316 324
  }
317 325
  { // Checking SmartDigraph
318 326
    checkConcept<Digraph, SmartDigraph>();
319 327
    checkConcept<AlterableDigraphComponent<>, SmartDigraph>();
320 328
    checkConcept<ExtendableDigraphComponent<>, SmartDigraph>();
321 329
    checkConcept<ClearableDigraphComponent<>, SmartDigraph>();
322 330
  }
323 331
  { // Checking FullDigraph
324 332
    checkConcept<Digraph, FullDigraph>();
325 333
  }
326 334
}
327 335

	
328 336
template <typename Digraph>
329 337
void checkDigraphValidity() {
330 338
  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
331 339
  Digraph g;
332 340

	
333 341
  Node
334 342
    n1 = g.addNode(),
335 343
    n2 = g.addNode(),
336 344
    n3 = g.addNode();
337 345

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

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

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

	
349 357
template <typename Digraph>
350 358
void checkDigraphValidityErase() {
351 359
  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
352 360
  Digraph g;
353 361

	
354 362
  Node
355 363
    n1 = g.addNode(),
356 364
    n2 = g.addNode(),
357 365
    n3 = g.addNode();
358 366

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

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

	
366 374
  g.erase(n1);
367 375

	
368 376
  check(!g.valid(n1), "Wrong validity check");
369 377
  check(g.valid(n2), "Wrong validity check");
370 378
  check(g.valid(n3), "Wrong validity check");
371 379
  check(!g.valid(e1), "Wrong validity check");
372 380
  check(g.valid(e2), "Wrong validity check");
373 381

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

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

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

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

	
388 396
  checkGraphNodeList(G, num);
389 397
  checkGraphArcList(G, num * num);
390 398

	
391 399
  for (NodeIt n(G); n != INVALID; ++n) {
392 400
    checkGraphOutArcList(G, n, num);
393 401
    checkGraphInArcList(G, n, num);
394 402
  }
395 403

	
396 404
  checkGraphConArcList(G, num * num);
397 405

	
398 406
  checkNodeIds(G);
399 407
  checkArcIds(G);
400 408
  checkGraphNodeMap(G);
401 409
  checkGraphArcMap(G);
402 410

	
403 411
  for (int i = 0; i < G.nodeNum(); ++i) {
404 412
    check(G.index(G(i)) == i, "Wrong index");
405 413
  }
406 414

	
407 415
  for (NodeIt s(G); s != INVALID; ++s) {
408 416
    for (NodeIt t(G); t != INVALID; ++t) {
409 417
      Arc a = G.arc(s, t);
410 418
      check(G.source(a) == s && G.target(a) == t, "Wrong arc lookup");
411 419
    }
412 420
  }
413 421
}
414 422

	
415 423
void checkDigraphs() {
416 424
  { // Checking ListDigraph
417 425
    checkDigraphBuild<ListDigraph>();
418 426
    checkDigraphSplit<ListDigraph>();
419 427
    checkDigraphAlter<ListDigraph>();
420 428
    checkDigraphErase<ListDigraph>();
421 429
    checkDigraphSnapshot<ListDigraph>();
422 430
    checkDigraphValidityErase<ListDigraph>();
423 431
  }
424 432
  { // Checking SmartDigraph
425 433
    checkDigraphBuild<SmartDigraph>();
426 434
    checkDigraphSplit<SmartDigraph>();
427 435
    checkDigraphSnapshot<SmartDigraph>();
428 436
    checkDigraphValidity<SmartDigraph>();
429 437
  }
430 438
  { // Checking FullDigraph
431 439
    checkFullDigraph(8);
432 440
  }
433 441
}
434 442

	
435 443
int main() {
436 444
  checkDigraphs();
437 445
  checkConcepts();
438 446
  return 0;
439 447
}
Ignore white space 768 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5 5
 * Copyright (C) 2003-2009
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
#include <lemon/hypercube_graph.h>
25 25

	
26 26
#include "test_tools.h"
27 27
#include "graph_test.h"
28 28

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

	
32 32
template <class Graph>
33 33
void checkGraphBuild() {
34 34
  TEMPLATE_GRAPH_TYPEDEFS(Graph);
35 35

	
36 36
  Graph G;
37 37
  checkGraphNodeList(G, 0);
38 38
  checkGraphEdgeList(G, 0);
39 39
  checkGraphArcList(G, 0);
40 40

	
41 41
  G.reserveNode(3);
42 42
  G.reserveEdge(3);
43 43

	
44 44
  Node
45 45
    n1 = G.addNode(),
46 46
    n2 = G.addNode(),
47 47
    n3 = G.addNode();
48 48
  checkGraphNodeList(G, 3);
49 49
  checkGraphEdgeList(G, 0);
50 50
  checkGraphArcList(G, 0);
51 51

	
52 52
  Edge e1 = G.addEdge(n1, n2);
53 53
  check((G.u(e1) == n1 && G.v(e1) == n2) || (G.u(e1) == n2 && G.v(e1) == n1),
54 54
        "Wrong edge");
55 55

	
56 56
  checkGraphNodeList(G, 3);
57 57
  checkGraphEdgeList(G, 1);
58 58
  checkGraphArcList(G, 2);
59 59

	
60 60
  checkGraphIncEdgeArcLists(G, n1, 1);
61 61
  checkGraphIncEdgeArcLists(G, n2, 1);
62 62
  checkGraphIncEdgeArcLists(G, n3, 0);
63 63

	
64 64
  checkGraphConEdgeList(G, 1);
65 65
  checkGraphConArcList(G, 2);
66 66

	
67 67
  Edge e2 = G.addEdge(n2, n1),
68 68
       e3 = G.addEdge(n2, n3);
69 69

	
70 70
  checkGraphNodeList(G, 3);
71 71
  checkGraphEdgeList(G, 3);
72 72
  checkGraphArcList(G, 6);
73 73

	
74 74
  checkGraphIncEdgeArcLists(G, n1, 2);
75 75
  checkGraphIncEdgeArcLists(G, n2, 3);
76 76
  checkGraphIncEdgeArcLists(G, n3, 1);
77 77

	
78 78
  checkGraphConEdgeList(G, 3);
79 79
  checkGraphConArcList(G, 6);
80 80

	
81 81
  checkArcDirections(G);
82 82

	
83 83
  checkNodeIds(G);
84 84
  checkArcIds(G);
85 85
  checkEdgeIds(G);
86 86
  checkGraphNodeMap(G);
87 87
  checkGraphArcMap(G);
88 88
  checkGraphEdgeMap(G);
89 89
}
90 90

	
91 91
template <class Graph>
92 92
void checkGraphAlter() {
93 93
  TEMPLATE_GRAPH_TYPEDEFS(Graph);
94 94

	
95 95
  Graph G;
96 96
  Node n1 = G.addNode(), n2 = G.addNode(),
97 97
       n3 = G.addNode(), n4 = G.addNode();
98 98
  Edge e1 = G.addEdge(n1, n2), e2 = G.addEdge(n2, n1),
99 99
       e3 = G.addEdge(n2, n3), e4 = G.addEdge(n1, n4),
100 100
       e5 = G.addEdge(n4, n3);
101 101

	
102 102
  checkGraphNodeList(G, 4);
103 103
  checkGraphEdgeList(G, 5);
104 104
  checkGraphArcList(G, 10);
105 105

	
106 106
  // Check changeU() and changeV()
107 107
  if (G.u(e2) == n2) {
108 108
    G.changeU(e2, n3);
109 109
  } else {
110 110
    G.changeV(e2, n3);
111 111
  }
112 112

	
113 113
  checkGraphNodeList(G, 4);
114 114
  checkGraphEdgeList(G, 5);
115 115
  checkGraphArcList(G, 10);
116 116

	
117 117
  checkGraphIncEdgeArcLists(G, n1, 3);
118 118
  checkGraphIncEdgeArcLists(G, n2, 2);
119 119
  checkGraphIncEdgeArcLists(G, n3, 3);
120 120
  checkGraphIncEdgeArcLists(G, n4, 2);
121 121

	
122 122
  checkGraphConEdgeList(G, 5);
123 123
  checkGraphConArcList(G, 10);
124 124

	
125 125
  if (G.u(e2) == n1) {
126 126
    G.changeU(e2, n2);
127 127
  } else {
128 128
    G.changeV(e2, n2);
129 129
  }
130 130

	
131 131
  checkGraphNodeList(G, 4);
132 132
  checkGraphEdgeList(G, 5);
133 133
  checkGraphArcList(G, 10);
134 134

	
135 135
  checkGraphIncEdgeArcLists(G, n1, 2);
136 136
  checkGraphIncEdgeArcLists(G, n2, 3);
137 137
  checkGraphIncEdgeArcLists(G, n3, 3);
138 138
  checkGraphIncEdgeArcLists(G, n4, 2);
139 139

	
140 140
  checkGraphConEdgeList(G, 5);
141 141
  checkGraphConArcList(G, 10);
142 142

	
143 143
  // Check contract()
144 144
  G.contract(n1, n4, false);
145 145

	
146 146
  checkGraphNodeList(G, 3);
147 147
  checkGraphEdgeList(G, 5);
148 148
  checkGraphArcList(G, 10);
149 149

	
150 150
  checkGraphIncEdgeArcLists(G, n1, 4);
151 151
  checkGraphIncEdgeArcLists(G, n2, 3);
152 152
  checkGraphIncEdgeArcLists(G, n3, 3);
153 153

	
154 154
  checkGraphConEdgeList(G, 5);
155 155
  checkGraphConArcList(G, 10);
156 156

	
157 157
  G.contract(n2, n3);
158 158

	
159 159
  checkGraphNodeList(G, 2);
160 160
  checkGraphEdgeList(G, 3);
161 161
  checkGraphArcList(G, 6);
162 162

	
163 163
  checkGraphIncEdgeArcLists(G, n1, 4);
164 164
  checkGraphIncEdgeArcLists(G, n2, 2);
165 165

	
166 166
  checkGraphConEdgeList(G, 3);
167 167
  checkGraphConArcList(G, 6);
168 168
}
169 169

	
170 170
template <class Graph>
171 171
void checkGraphErase() {
172 172
  TEMPLATE_GRAPH_TYPEDEFS(Graph);
173 173

	
174 174
  Graph G;
175 175
  Node n1 = G.addNode(), n2 = G.addNode(),
176 176
       n3 = G.addNode(), n4 = G.addNode();
177 177
  Edge e1 = G.addEdge(n1, n2), e2 = G.addEdge(n2, n1),
178 178
       e3 = G.addEdge(n2, n3), e4 = G.addEdge(n1, n4),
179 179
       e5 = G.addEdge(n4, n3);
180 180

	
181 181
  // Check edge deletion
182 182
  G.erase(e2);
183 183

	
184 184
  checkGraphNodeList(G, 4);
185 185
  checkGraphEdgeList(G, 4);
186 186
  checkGraphArcList(G, 8);
187 187

	
188 188
  checkGraphIncEdgeArcLists(G, n1, 2);
189 189
  checkGraphIncEdgeArcLists(G, n2, 2);
190 190
  checkGraphIncEdgeArcLists(G, n3, 2);
191 191
  checkGraphIncEdgeArcLists(G, n4, 2);
192 192

	
193 193
  checkGraphConEdgeList(G, 4);
194 194
  checkGraphConArcList(G, 8);
195 195

	
196 196
  // Check node deletion
197 197
  G.erase(n3);
198 198

	
199 199
  checkGraphNodeList(G, 3);
200 200
  checkGraphEdgeList(G, 2);
201 201
  checkGraphArcList(G, 4);
202 202

	
203 203
  checkGraphIncEdgeArcLists(G, n1, 2);
204 204
  checkGraphIncEdgeArcLists(G, n2, 1);
205 205
  checkGraphIncEdgeArcLists(G, n4, 1);
206 206

	
207 207
  checkGraphConEdgeList(G, 2);
208 208
  checkGraphConArcList(G, 4);
209 209
}
210 210

	
211 211

	
212 212
template <class Graph>
213 213
void checkGraphSnapshot() {
214 214
  TEMPLATE_GRAPH_TYPEDEFS(Graph);
215 215

	
216 216
  Graph G;
217 217
  Node n1 = G.addNode(), n2 = G.addNode(), n3 = G.addNode();
218 218
  Edge e1 = G.addEdge(n1, n2), e2 = G.addEdge(n2, n1),
219 219
       e3 = G.addEdge(n2, n3);
220 220

	
221 221
  checkGraphNodeList(G, 3);
222 222
  checkGraphEdgeList(G, 3);
223 223
  checkGraphArcList(G, 6);
224 224

	
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
  snapshot.save(G);
263

	
264
  checkGraphNodeList(G, 4);
265
  checkGraphEdgeList(G, 3);
266
  checkGraphArcList(G, 6);
267
  
268
  G.addEdge(G.addNode(), G.addNode());
269

	
270
  snapshot.restore();
262 271

	
263 272
  checkGraphNodeList(G, 4);
264 273
  checkGraphEdgeList(G, 3);
265 274
  checkGraphArcList(G, 6);
266 275
}
267 276

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

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

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

	
280 289
  checkGraphNodeList(G, num);
281 290
  checkGraphEdgeList(G, num * (num - 1) / 2);
282 291

	
283 292
  for (NodeIt n(G); n != INVALID; ++n) {
284 293
    checkGraphOutArcList(G, n, num - 1);
285 294
    checkGraphInArcList(G, n, num - 1);
286 295
    checkGraphIncEdgeList(G, n, num - 1);
287 296
  }
288 297

	
289 298
  checkGraphConArcList(G, num * (num - 1));
290 299
  checkGraphConEdgeList(G, num * (num - 1) / 2);
291 300

	
292 301
  checkArcDirections(G);
293 302

	
294 303
  checkNodeIds(G);
295 304
  checkArcIds(G);
296 305
  checkEdgeIds(G);
297 306
  checkGraphNodeMap(G);
298 307
  checkGraphArcMap(G);
299 308
  checkGraphEdgeMap(G);
300 309

	
301 310

	
302 311
  for (int i = 0; i < G.nodeNum(); ++i) {
303 312
    check(G.index(G(i)) == i, "Wrong index");
304 313
  }
305 314

	
306 315
  for (NodeIt u(G); u != INVALID; ++u) {
307 316
    for (NodeIt v(G); v != INVALID; ++v) {
308 317
      Edge e = G.edge(u, v);
309 318
      Arc a = G.arc(u, v);
310 319
      if (u == v) {
311 320
        check(e == INVALID, "Wrong edge lookup");
312 321
        check(a == INVALID, "Wrong arc lookup");
313 322
      } else {
314 323
        check((G.u(e) == u && G.v(e) == v) ||
315 324
              (G.u(e) == v && G.v(e) == u), "Wrong edge lookup");
316 325
        check(G.source(a) == u && G.target(a) == v, "Wrong arc lookup");
317 326
      }
318 327
    }
319 328
  }
320 329
}
321 330

	
322 331
void checkConcepts() {
323 332
  { // Checking graph components
324 333
    checkConcept<BaseGraphComponent, BaseGraphComponent >();
325 334

	
326 335
    checkConcept<IDableGraphComponent<>,
327 336
      IDableGraphComponent<> >();
328 337

	
329 338
    checkConcept<IterableGraphComponent<>,
330 339
      IterableGraphComponent<> >();
331 340

	
332 341
    checkConcept<MappableGraphComponent<>,
333 342
      MappableGraphComponent<> >();
334 343
  }
335 344
  { // Checking skeleton graph
336 345
    checkConcept<Graph, Graph>();
337 346
  }
338 347
  { // Checking ListGraph
339 348
    checkConcept<Graph, ListGraph>();
340 349
    checkConcept<AlterableGraphComponent<>, ListGraph>();
341 350
    checkConcept<ExtendableGraphComponent<>, ListGraph>();
342 351
    checkConcept<ClearableGraphComponent<>, ListGraph>();
343 352
    checkConcept<ErasableGraphComponent<>, ListGraph>();
344 353
  }
345 354
  { // Checking SmartGraph
346 355
    checkConcept<Graph, SmartGraph>();
347 356
    checkConcept<AlterableGraphComponent<>, SmartGraph>();
348 357
    checkConcept<ExtendableGraphComponent<>, SmartGraph>();
349 358
    checkConcept<ClearableGraphComponent<>, SmartGraph>();
350 359
  }
351 360
  { // Checking FullGraph
352 361
    checkConcept<Graph, FullGraph>();
353 362
  }
354 363
  { // Checking GridGraph
355 364
    checkConcept<Graph, GridGraph>();
356 365
  }
357 366
  { // Checking HypercubeGraph
358 367
    checkConcept<Graph, HypercubeGraph>();
359 368
  }
360 369
}
361 370

	
362 371
template <typename Graph>
363 372
void checkGraphValidity() {
364 373
  TEMPLATE_GRAPH_TYPEDEFS(Graph);
365 374
  Graph g;
366 375

	
367 376
  Node
368 377
    n1 = g.addNode(),
369 378
    n2 = g.addNode(),
370 379
    n3 = g.addNode();
371 380

	
372 381
  Edge
373 382
    e1 = g.addEdge(n1, n2),
374 383
    e2 = g.addEdge(n2, n3);
375 384

	
376 385
  check(g.valid(n1), "Wrong validity check");
377 386
  check(g.valid(e1), "Wrong validity check");
378 387
  check(g.valid(g.direct(e1, true)), "Wrong validity check");
379 388

	
380 389
  check(!g.valid(g.nodeFromId(-1)), "Wrong validity check");
381 390
  check(!g.valid(g.edgeFromId(-1)), "Wrong validity check");
382 391
  check(!g.valid(g.arcFromId(-1)), "Wrong validity check");
383 392
}
384 393

	
385 394
template <typename Graph>
386 395
void checkGraphValidityErase() {
387 396
  TEMPLATE_GRAPH_TYPEDEFS(Graph);
388 397
  Graph g;
389 398

	
390 399
  Node
391 400
    n1 = g.addNode(),
392 401
    n2 = g.addNode(),
393 402
    n3 = g.addNode();
394 403

	
395 404
  Edge
396 405
    e1 = g.addEdge(n1, n2),
397 406
    e2 = g.addEdge(n2, n3);
398 407

	
399 408
  check(g.valid(n1), "Wrong validity check");
400 409
  check(g.valid(e1), "Wrong validity check");
401 410
  check(g.valid(g.direct(e1, true)), "Wrong validity check");
402 411

	
403 412
  g.erase(n1);
404 413

	
405 414
  check(!g.valid(n1), "Wrong validity check");
406 415
  check(g.valid(n2), "Wrong validity check");
407 416
  check(g.valid(n3), "Wrong validity check");
408 417
  check(!g.valid(e1), "Wrong validity check");
409 418
  check(g.valid(e2), "Wrong validity check");
410 419

	
411 420
  check(!g.valid(g.nodeFromId(-1)), "Wrong validity check");
412 421
  check(!g.valid(g.edgeFromId(-1)), "Wrong validity check");
413 422
  check(!g.valid(g.arcFromId(-1)), "Wrong validity check");
414 423
}
415 424

	
416 425
void checkGridGraph(int width, int height) {
417 426
  typedef GridGraph Graph;
418 427
  GRAPH_TYPEDEFS(Graph);
419 428
  Graph G(width, height);
420 429

	
421 430
  check(G.width() == width, "Wrong column number");
422 431
  check(G.height() == height, "Wrong row number");
423 432

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

	
428 437
  for (int i = 0; i < width; ++i) {
429 438
    for (int j = 0; j < height; ++j) {
430 439
      check(G.col(G(i, j)) == i, "Wrong column");
431 440
      check(G.row(G(i, j)) == j, "Wrong row");
432 441
      check(G.pos(G(i, j)).x == i, "Wrong column");
433 442
      check(G.pos(G(i, j)).y == j, "Wrong row");
434 443
    }
435 444
  }
436 445

	
437 446
  for (int j = 0; j < height; ++j) {
438 447
    for (int i = 0; i < width - 1; ++i) {
439 448
      check(G.source(G.right(G(i, j))) == G(i, j), "Wrong right");
440 449
      check(G.target(G.right(G(i, j))) == G(i + 1, j), "Wrong right");
441 450
    }
442 451
    check(G.right(G(width - 1, j)) == INVALID, "Wrong right");
443 452
  }
444 453

	
445 454
  for (int j = 0; j < height; ++j) {
446 455
    for (int i = 1; i < width; ++i) {
447 456
      check(G.source(G.left(G(i, j))) == G(i, j), "Wrong left");
448 457
      check(G.target(G.left(G(i, j))) == G(i - 1, j), "Wrong left");
449 458
    }
450 459
    check(G.left(G(0, j)) == INVALID, "Wrong left");
451 460
  }
452 461

	
453 462
  for (int i = 0; i < width; ++i) {
454 463
    for (int j = 0; j < height - 1; ++j) {
455 464
      check(G.source(G.up(G(i, j))) == G(i, j), "Wrong up");
456 465
      check(G.target(G.up(G(i, j))) == G(i, j + 1), "Wrong up");
457 466
    }
458 467
    check(G.up(G(i, height - 1)) == INVALID, "Wrong up");
459 468
  }
460 469

	
461 470
  for (int i = 0; i < width; ++i) {
462 471
    for (int j = 1; j < height; ++j) {
463 472
      check(G.source(G.down(G(i, j))) == G(i, j), "Wrong down");
464 473
      check(G.target(G.down(G(i, j))) == G(i, j - 1), "Wrong down");
465 474
    }
466 475
    check(G.down(G(i, 0)) == INVALID, "Wrong down");
467 476
  }
468 477

	
469 478
  checkGraphNodeList(G, width * height);
470 479
  checkGraphEdgeList(G, width * (height - 1) + (width - 1) * height);
471 480
  checkGraphArcList(G, 2 * (width * (height - 1) + (width - 1) * height));
472 481

	
473 482
  for (NodeIt n(G); n != INVALID; ++n) {
474 483
    int nb = 4;
475 484
    if (G.col(n) == 0) --nb;
476 485
    if (G.col(n) == width - 1) --nb;
477 486
    if (G.row(n) == 0) --nb;
478 487
    if (G.row(n) == height - 1) --nb;
479 488

	
480 489
    checkGraphOutArcList(G, n, nb);
481 490
    checkGraphInArcList(G, n, nb);
482 491
    checkGraphIncEdgeList(G, n, nb);
483 492
  }
484 493

	
485 494
  checkArcDirections(G);
486 495

	
487 496
  checkGraphConArcList(G, 2 * (width * (height - 1) + (width - 1) * height));
488 497
  checkGraphConEdgeList(G, width * (height - 1) + (width - 1) * height);
489 498

	
490 499
  checkNodeIds(G);
491 500
  checkArcIds(G);
492 501
  checkEdgeIds(G);
493 502
  checkGraphNodeMap(G);
494 503
  checkGraphArcMap(G);
495 504
  checkGraphEdgeMap(G);
496 505

	
497 506
}
498 507

	
499 508
void checkHypercubeGraph(int dim) {
500 509
  GRAPH_TYPEDEFS(HypercubeGraph);
501 510

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

	
505 514
  G.resize(dim);
506 515
  check(G.dimension() == dim, "Wrong dimension");
507 516
  
508 517
  checkGraphNodeList(G, 1 << dim);
509 518
  checkGraphEdgeList(G, dim * (1 << (dim-1)));
510 519
  checkGraphArcList(G, dim * (1 << dim));
511 520

	
512 521
  Node n = G.nodeFromId(dim);
513 522

	
514 523
  for (NodeIt n(G); n != INVALID; ++n) {
515 524
    checkGraphIncEdgeList(G, n, dim);
516 525
    for (IncEdgeIt e(G, n); e != INVALID; ++e) {
517 526
      check( (G.u(e) == n &&
518 527
              G.id(G.v(e)) == (G.id(n) ^ (1 << G.dimension(e)))) ||
519 528
             (G.v(e) == n &&
520 529
              G.id(G.u(e)) == (G.id(n) ^ (1 << G.dimension(e)))),
521 530
             "Wrong edge or wrong dimension");
522 531
    }
523 532

	
524 533
    checkGraphOutArcList(G, n, dim);
525 534
    for (OutArcIt a(G, n); a != INVALID; ++a) {
526 535
      check(G.source(a) == n &&
527 536
            G.id(G.target(a)) == (G.id(n) ^ (1 << G.dimension(a))),
528 537
            "Wrong arc or wrong dimension");
529 538
    }
530 539

	
531 540
    checkGraphInArcList(G, n, dim);
532 541
    for (InArcIt a(G, n); a != INVALID; ++a) {
533 542
      check(G.target(a) == n &&
534 543
            G.id(G.source(a)) == (G.id(n) ^ (1 << G.dimension(a))),
535 544
            "Wrong arc or wrong dimension");
536 545
    }
537 546
  }
538 547

	
539 548
  checkGraphConArcList(G, (1 << dim) * dim);
540 549
  checkGraphConEdgeList(G, dim * (1 << (dim-1)));
541 550

	
542 551
  checkArcDirections(G);
543 552

	
544 553
  checkNodeIds(G);
545 554
  checkArcIds(G);
546 555
  checkEdgeIds(G);
547 556
  checkGraphNodeMap(G);
548 557
  checkGraphArcMap(G);
549 558
  checkGraphEdgeMap(G);
550 559
}
551 560

	
552 561
void checkGraphs() {
553 562
  { // Checking ListGraph
554 563
    checkGraphBuild<ListGraph>();
555 564
    checkGraphAlter<ListGraph>();
556 565
    checkGraphErase<ListGraph>();
557 566
    checkGraphSnapshot<ListGraph>();
558 567
    checkGraphValidityErase<ListGraph>();
559 568
  }
560 569
  { // Checking SmartGraph
561 570
    checkGraphBuild<SmartGraph>();
562 571
    checkGraphSnapshot<SmartGraph>();
563 572
    checkGraphValidity<SmartGraph>();
564 573
  }
565 574
  { // Checking FullGraph
566 575
    checkFullGraph(7);
567 576
    checkFullGraph(8);
568 577
  }
569 578
  { // Checking GridGraph
570 579
    checkGridGraph(5, 8);
571 580
    checkGridGraph(8, 5);
572 581
    checkGridGraph(5, 5);
573 582
    checkGridGraph(0, 0);
574 583
    checkGridGraph(1, 1);
575 584
  }
576 585
  { // Checking HypercubeGraph
577 586
    checkHypercubeGraph(1);
578 587
    checkHypercubeGraph(2);
579 588
    checkHypercubeGraph(3);
580 589
    checkHypercubeGraph(4);
581 590
  }
582 591
}
583 592

	
584 593
int main() {
585 594
  checkConcepts();
586 595
  checkGraphs();
587 596
  return 0;
588 597
}
0 comments (0 inline)