gravatar
deba@inf.elte.hu
deba@inf.elte.hu
Uniforming primal scale to 2 (#314)
0 2 0
default
2 files changed with 44 insertions and 25 deletions:
↑ Collapse diff ↑
Ignore white space 384 line context
... ...
@@ -469,418 +469,417 @@
469 469
      }
470 470
    }
471 471

	
472 472
    /// \brief Starts the algorithm and computes a perfect fractional
473 473
    /// matching
474 474
    ///
475 475
    /// The algorithm computes a perfect fractional matching. If it
476 476
    /// does not exists, then the algorithm returns false and the
477 477
    /// matching is undefined and the barrier.
478 478
    ///
479 479
    /// \param postprocess The algorithm computes first a matching
480 480
    /// which is a union of a matching with one value edges, cycles
481 481
    /// with half value edges and even length paths with half value
482 482
    /// edges. If the parameter is true, then after the push-relabel
483 483
    /// algorithm it postprocesses the matching to contain only
484 484
    /// matching edges and half value odd cycles.
485 485
    bool startPerfect(bool postprocess = true) {
486 486
      Node n;
487 487
      while ((n = _level->highestActive()) != INVALID) {
488 488
        int level = _level->highestActiveLevel();
489 489
        int new_level = _level->maxLevel();
490 490
        for (InArcIt a(_graph, n); a != INVALID; ++a) {
491 491
          Node u = _graph.source(a);
492 492
          if (n == u && !_allow_loops) continue;
493 493
          Node v = _graph.target((*_matching)[u]);
494 494
          if ((*_level)[v] < level) {
495 495
            _indeg->set(v, (*_indeg)[v] - 1);
496 496
            if ((*_indeg)[v] == 0) {
497 497
              _level->activate(v);
498 498
            }
499 499
            _matching->set(u, a);
500 500
            _indeg->set(n, (*_indeg)[n] + 1);
501 501
            _level->deactivate(n);
502 502
            goto no_more_push;
503 503
          } else if (new_level > (*_level)[v]) {
504 504
            new_level = (*_level)[v];
505 505
          }
506 506
        }
507 507

	
508 508
        if (new_level + 1 < _level->maxLevel()) {
509 509
          _level->liftHighestActive(new_level + 1);
510 510
        } else {
511 511
          _level->liftHighestActiveToTop();
512 512
          _empty_level = _level->maxLevel() - 1;
513 513
          return false;
514 514
        }
515 515
        if (_level->emptyLevel(level)) {
516 516
          _level->liftToTop(level);
517 517
          _empty_level = level;
518 518
          return false;
519 519
        }
520 520
      no_more_push:
521 521
        ;
522 522
      }
523 523
      if (postprocess) {
524 524
        postprocessing();
525 525
      }
526 526
      return true;
527 527
    }
528 528

	
529 529
    /// \brief Runs the algorithm
530 530
    ///
531 531
    /// Just a shortcut for the next code:
532 532
    ///\code
533 533
    /// init();
534 534
    /// start();
535 535
    ///\endcode
536 536
    void run(bool postprocess = true) {
537 537
      init();
538 538
      start(postprocess);
539 539
    }
540 540

	
541 541
    /// \brief Runs the algorithm to find a perfect fractional matching
542 542
    ///
543 543
    /// Just a shortcut for the next code:
544 544
    ///\code
545 545
    /// init();
546 546
    /// startPerfect();
547 547
    ///\endcode
548 548
    bool runPerfect(bool postprocess = true) {
549 549
      init();
550 550
      return startPerfect(postprocess);
551 551
    }
552 552

	
553 553
    ///@}
554 554

	
555 555
    /// \name Query Functions
556 556
    /// The result of the %Matching algorithm can be obtained using these
557 557
    /// functions.\n
558 558
    /// Before the use of these functions,
559 559
    /// either run() or start() must be called.
560 560
    ///@{
561 561

	
562 562

	
563 563
    /// \brief Return the number of covered nodes in the matching.
564 564
    ///
565 565
    /// This function returns the number of covered nodes in the matching.
566 566
    ///
567 567
    /// \pre Either run() or start() must be called before using this function.
568 568
    int matchingSize() const {
569 569
      int num = 0;
570 570
      for (NodeIt n(_graph); n != INVALID; ++n) {
571 571
        if ((*_matching)[n] != INVALID) {
572 572
          ++num;
573 573
        }
574 574
      }
575 575
      return num;
576 576
    }
577 577

	
578 578
    /// \brief Returns a const reference to the matching map.
579 579
    ///
580 580
    /// Returns a const reference to the node map storing the found
581 581
    /// fractional matching. This method can be called after
582 582
    /// running the algorithm.
583 583
    ///
584 584
    /// \pre Either \ref run() or \ref init() must be called before
585 585
    /// using this function.
586 586
    const MatchingMap& matchingMap() const {
587 587
      return *_matching;
588 588
    }
589 589

	
590 590
    /// \brief Return \c true if the given edge is in the matching.
591 591
    ///
592 592
    /// This function returns \c true if the given edge is in the
593 593
    /// found matching. The result is scaled by \ref primalScale
594 594
    /// "primal scale".
595 595
    ///
596 596
    /// \pre Either run() or start() must be called before using this function.
597 597
    int matching(const Edge& edge) const {
598 598
      return (edge == (*_matching)[_graph.u(edge)] ? 1 : 0) +
599 599
        (edge == (*_matching)[_graph.v(edge)] ? 1 : 0);
600 600
    }
601 601

	
602 602
    /// \brief Return the fractional matching arc (or edge) incident
603 603
    /// to the given node.
604 604
    ///
605 605
    /// This function returns one of the fractional matching arc (or
606 606
    /// edge) incident to the given node in the found matching or \c
607 607
    /// INVALID if the node is not covered by the matching or if the
608 608
    /// node is on an odd length cycle then it is the successor edge
609 609
    /// on the cycle.
610 610
    ///
611 611
    /// \pre Either run() or start() must be called before using this function.
612 612
    Arc matching(const Node& node) const {
613 613
      return (*_matching)[node];
614 614
    }
615 615

	
616 616
    /// \brief Returns true if the node is in the barrier
617 617
    ///
618 618
    /// The barrier is a subset of the nodes. If the nodes in the
619 619
    /// barrier have less adjacent nodes than the size of the barrier,
620 620
    /// then at least as much nodes cannot be covered as the
621 621
    /// difference of the two subsets.
622 622
    bool barrier(const Node& node) const {
623 623
      return (*_level)[node] >= _empty_level;
624 624
    }
625 625

	
626 626
    /// @}
627 627

	
628 628
  };
629 629

	
630 630
  /// \ingroup matching
631 631
  ///
632 632
  /// \brief Weighted fractional matching in general graphs
633 633
  ///
634 634
  /// This class provides an efficient implementation of fractional
635 635
  /// matching algorithm. The implementation uses priority queues and
636 636
  /// provides \f$O(nm\log n)\f$ time complexity.
637 637
  ///
638 638
  /// The maximum weighted fractional matching is a relaxation of the
639 639
  /// maximum weighted matching problem where the odd set constraints
640 640
  /// are omitted.
641 641
  /// It can be formulated with the following linear program.
642 642
  /// \f[ \sum_{e \in \delta(u)}x_e \le 1 \quad \forall u\in V\f]
643 643
  /// \f[x_e \ge 0\quad \forall e\in E\f]
644 644
  /// \f[\max \sum_{e\in E}x_ew_e\f]
645 645
  /// where \f$\delta(X)\f$ is the set of edges incident to a node in
646 646
  /// \f$X\f$. The result must be the union of a matching with one
647 647
  /// value edges and a set of odd length cycles with half value edges.
648 648
  ///
649 649
  /// The algorithm calculates an optimal fractional matching and a
650 650
  /// proof of the optimality. The solution of the dual problem can be
651 651
  /// used to check the result of the algorithm. The dual linear
652 652
  /// problem is the following.
653 653
  /// \f[ y_u + y_v \ge w_{uv} \quad \forall uv\in E\f]
654 654
  /// \f[y_u \ge 0 \quad \forall u \in V\f]
655 655
  /// \f[\min \sum_{u \in V}y_u \f]
656 656
  ///
657 657
  /// The algorithm can be executed with the run() function.
658 658
  /// After it the matching (the primal solution) and the dual solution
659 659
  /// can be obtained using the query functions.
660 660
  ///
661
  /// If the value type is integer, then the primal and the dual
662
  /// solutions are multiplied by
663
  /// \ref MaxWeightedFractionalMatching::primalScale "2" and
664
  /// \ref MaxWeightedFractionalMatching::dualScale "4" respectively.
661
  /// The primal solution is multiplied by
662
  /// \ref MaxWeightedFractionalMatching::primalScale "2".
663
  /// If the value type is integer, then the dual
664
  /// solution is scaled by
665
  /// \ref MaxWeightedFractionalMatching::dualScale "4".
665 666
  ///
666 667
  /// \tparam GR The undirected graph type the algorithm runs on.
667 668
  /// \tparam WM The type edge weight map. The default type is
668 669
  /// \ref concepts::Graph::EdgeMap "GR::EdgeMap<int>".
669 670
#ifdef DOXYGEN
670 671
  template <typename GR, typename WM>
671 672
#else
672 673
  template <typename GR,
673 674
            typename WM = typename GR::template EdgeMap<int> >
674 675
#endif
675 676
  class MaxWeightedFractionalMatching {
676 677
  public:
677 678

	
678 679
    /// The graph type of the algorithm
679 680
    typedef GR Graph;
680 681
    /// The type of the edge weight map
681 682
    typedef WM WeightMap;
682 683
    /// The value type of the edge weights
683 684
    typedef typename WeightMap::Value Value;
684 685

	
685 686
    /// The type of the matching map
686 687
    typedef typename Graph::template NodeMap<typename Graph::Arc>
687 688
    MatchingMap;
688 689

	
689 690
    /// \brief Scaling factor for primal solution
690 691
    ///
691
    /// Scaling factor for primal solution. It is equal to 2 or 1
692
    /// according to the value type.
693
    static const int primalScale =
694
      std::numeric_limits<Value>::is_integer ? 2 : 1;
692
    /// Scaling factor for primal solution.
693
    static const int primalScale = 2;
695 694

	
696 695
    /// \brief Scaling factor for dual solution
697 696
    ///
698 697
    /// Scaling factor for dual solution. It is equal to 4 or 1
699 698
    /// according to the value type.
700 699
    static const int dualScale =
701 700
      std::numeric_limits<Value>::is_integer ? 4 : 1;
702 701

	
703 702
  private:
704 703

	
705 704
    TEMPLATE_GRAPH_TYPEDEFS(Graph);
706 705

	
707 706
    typedef typename Graph::template NodeMap<Value> NodePotential;
708 707

	
709 708
    const Graph& _graph;
710 709
    const WeightMap& _weight;
711 710

	
712 711
    MatchingMap* _matching;
713 712
    NodePotential* _node_potential;
714 713

	
715 714
    int _node_num;
716 715
    bool _allow_loops;
717 716

	
718 717
    enum Status {
719 718
      EVEN = -1, MATCHED = 0, ODD = 1
720 719
    };
721 720

	
722 721
    typedef typename Graph::template NodeMap<Status> StatusMap;
723 722
    StatusMap* _status;
724 723

	
725 724
    typedef typename Graph::template NodeMap<Arc> PredMap;
726 725
    PredMap* _pred;
727 726

	
728 727
    typedef ExtendFindEnum<IntNodeMap> TreeSet;
729 728

	
730 729
    IntNodeMap *_tree_set_index;
731 730
    TreeSet *_tree_set;
732 731

	
733 732
    IntNodeMap *_delta1_index;
734 733
    BinHeap<Value, IntNodeMap> *_delta1;
735 734

	
736 735
    IntNodeMap *_delta2_index;
737 736
    BinHeap<Value, IntNodeMap> *_delta2;
738 737

	
739 738
    IntEdgeMap *_delta3_index;
740 739
    BinHeap<Value, IntEdgeMap> *_delta3;
741 740

	
742 741
    Value _delta_sum;
743 742

	
744 743
    void createStructures() {
745 744
      _node_num = countNodes(_graph);
746 745

	
747 746
      if (!_matching) {
748 747
        _matching = new MatchingMap(_graph);
749 748
      }
750 749
      if (!_node_potential) {
751 750
        _node_potential = new NodePotential(_graph);
752 751
      }
753 752
      if (!_status) {
754 753
        _status = new StatusMap(_graph);
755 754
      }
756 755
      if (!_pred) {
757 756
        _pred = new PredMap(_graph);
758 757
      }
759 758
      if (!_tree_set) {
760 759
        _tree_set_index = new IntNodeMap(_graph);
761 760
        _tree_set = new TreeSet(*_tree_set_index);
762 761
      }
763 762
      if (!_delta1) {
764 763
        _delta1_index = new IntNodeMap(_graph);
765 764
        _delta1 = new BinHeap<Value, IntNodeMap>(*_delta1_index);
766 765
      }
767 766
      if (!_delta2) {
768 767
        _delta2_index = new IntNodeMap(_graph);
769 768
        _delta2 = new BinHeap<Value, IntNodeMap>(*_delta2_index);
770 769
      }
771 770
      if (!_delta3) {
772 771
        _delta3_index = new IntEdgeMap(_graph);
773 772
        _delta3 = new BinHeap<Value, IntEdgeMap>(*_delta3_index);
774 773
      }
775 774
    }
776 775

	
777 776
    void destroyStructures() {
778 777
      if (_matching) {
779 778
        delete _matching;
780 779
      }
781 780
      if (_node_potential) {
782 781
        delete _node_potential;
783 782
      }
784 783
      if (_status) {
785 784
        delete _status;
786 785
      }
787 786
      if (_pred) {
788 787
        delete _pred;
789 788
      }
790 789
      if (_tree_set) {
791 790
        delete _tree_set_index;
792 791
        delete _tree_set;
793 792
      }
794 793
      if (_delta1) {
795 794
        delete _delta1_index;
796 795
        delete _delta1;
797 796
      }
798 797
      if (_delta2) {
799 798
        delete _delta2_index;
800 799
        delete _delta2;
801 800
      }
802 801
      if (_delta3) {
803 802
        delete _delta3_index;
804 803
        delete _delta3;
805 804
      }
806 805
    }
807 806

	
808 807
    void matchedToEven(Node node, int tree) {
809 808
      _tree_set->insert(node, tree);
810 809
      _node_potential->set(node, (*_node_potential)[node] + _delta_sum);
811 810
      _delta1->push(node, (*_node_potential)[node]);
812 811

	
813 812
      if (_delta2->state(node) == _delta2->IN_HEAP) {
814 813
        _delta2->erase(node);
815 814
      }
816 815

	
817 816
      for (InArcIt a(_graph, node); a != INVALID; ++a) {
818 817
        Node v = _graph.source(a);
819 818
        Value rw = (*_node_potential)[node] + (*_node_potential)[v] -
820 819
          dualScale * _weight[a];
821 820
        if (node == v) {
822 821
          if (_allow_loops && _graph.direction(a)) {
823 822
            _delta3->push(a, rw / 2);
824 823
          }
825 824
        } else if ((*_status)[v] == EVEN) {
826 825
          _delta3->push(a, rw / 2);
827 826
        } else if ((*_status)[v] == MATCHED) {
828 827
          if (_delta2->state(v) != _delta2->IN_HEAP) {
829 828
            _pred->set(v, a);
830 829
            _delta2->push(v, rw);
831 830
          } else if ((*_delta2)[v] > rw) {
832 831
            _pred->set(v, a);
833 832
            _delta2->decrease(v, rw);
834 833
          }
835 834
        }
836 835
      }
837 836
    }
838 837

	
839 838
    void matchedToOdd(Node node, int tree) {
840 839
      _tree_set->insert(node, tree);
841 840
      _node_potential->set(node, (*_node_potential)[node] - _delta_sum);
842 841

	
843 842
      if (_delta2->state(node) == _delta2->IN_HEAP) {
844 843
        _delta2->erase(node);
845 844
      }
846 845
    }
847 846

	
848 847
    void evenToMatched(Node node, int tree) {
849 848
      _delta1->erase(node);
850 849
      _node_potential->set(node, (*_node_potential)[node] - _delta_sum);
851 850
      Arc min = INVALID;
852 851
      Value minrw = std::numeric_limits<Value>::max();
853 852
      for (InArcIt a(_graph, node); a != INVALID; ++a) {
854 853
        Node v = _graph.source(a);
855 854
        Value rw = (*_node_potential)[node] + (*_node_potential)[v] -
856 855
          dualScale * _weight[a];
857 856

	
858 857
        if (node == v) {
859 858
          if (_allow_loops && _graph.direction(a)) {
860 859
            _delta3->erase(a);
861 860
          }
862 861
        } else if ((*_status)[v] == EVEN) {
863 862
          _delta3->erase(a);
864 863
          if (minrw > rw) {
865 864
            min = _graph.oppositeArc(a);
866 865
            minrw = rw;
867 866
          }
868 867
        } else if ((*_status)[v]  == MATCHED) {
869 868
          if ((*_pred)[v] == a) {
870 869
            Arc mina = INVALID;
871 870
            Value minrwa = std::numeric_limits<Value>::max();
872 871
            for (OutArcIt aa(_graph, v); aa != INVALID; ++aa) {
873 872
              Node va = _graph.target(aa);
874 873
              if ((*_status)[va] != EVEN ||
875 874
                  _tree_set->find(va) == tree) continue;
876 875
              Value rwa = (*_node_potential)[v] + (*_node_potential)[va] -
877 876
                dualScale * _weight[aa];
878 877
              if (minrwa > rwa) {
879 878
                minrwa = rwa;
880 879
                mina = aa;
881 880
              }
882 881
            }
883 882
            if (mina != INVALID) {
884 883
              _pred->set(v, mina);
885 884
              _delta2->increase(v, minrwa);
886 885
            } else {
... ...
@@ -1140,513 +1139,511 @@
1140 1139
      _delta1_index(0), _delta1(0),
1141 1140
      _delta2_index(0), _delta2(0),
1142 1141
      _delta3_index(0), _delta3(0),
1143 1142

	
1144 1143
      _delta_sum() {}
1145 1144

	
1146 1145
    ~MaxWeightedFractionalMatching() {
1147 1146
      destroyStructures();
1148 1147
    }
1149 1148

	
1150 1149
    /// \name Execution Control
1151 1150
    /// The simplest way to execute the algorithm is to use the
1152 1151
    /// \ref run() member function.
1153 1152

	
1154 1153
    ///@{
1155 1154

	
1156 1155
    /// \brief Initialize the algorithm
1157 1156
    ///
1158 1157
    /// This function initializes the algorithm.
1159 1158
    void init() {
1160 1159
      createStructures();
1161 1160

	
1162 1161
      for (NodeIt n(_graph); n != INVALID; ++n) {
1163 1162
        (*_delta1_index)[n] = _delta1->PRE_HEAP;
1164 1163
        (*_delta2_index)[n] = _delta2->PRE_HEAP;
1165 1164
      }
1166 1165
      for (EdgeIt e(_graph); e != INVALID; ++e) {
1167 1166
        (*_delta3_index)[e] = _delta3->PRE_HEAP;
1168 1167
      }
1169 1168

	
1170 1169
      for (NodeIt n(_graph); n != INVALID; ++n) {
1171 1170
        Value max = 0;
1172 1171
        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
1173 1172
          if (_graph.target(e) == n && !_allow_loops) continue;
1174 1173
          if ((dualScale * _weight[e]) / 2 > max) {
1175 1174
            max = (dualScale * _weight[e]) / 2;
1176 1175
          }
1177 1176
        }
1178 1177
        _node_potential->set(n, max);
1179 1178
        _delta1->push(n, max);
1180 1179

	
1181 1180
        _tree_set->insert(n);
1182 1181

	
1183 1182
        _matching->set(n, INVALID);
1184 1183
        _status->set(n, EVEN);
1185 1184
      }
1186 1185

	
1187 1186
      for (EdgeIt e(_graph); e != INVALID; ++e) {
1188 1187
        Node left = _graph.u(e);
1189 1188
        Node right = _graph.v(e);
1190 1189
        if (left == right && !_allow_loops) continue;
1191 1190
        _delta3->push(e, ((*_node_potential)[left] +
1192 1191
                          (*_node_potential)[right] -
1193 1192
                          dualScale * _weight[e]) / 2);
1194 1193
      }
1195 1194
    }
1196 1195

	
1197 1196
    /// \brief Start the algorithm
1198 1197
    ///
1199 1198
    /// This function starts the algorithm.
1200 1199
    ///
1201 1200
    /// \pre \ref init() must be called before using this function.
1202 1201
    void start() {
1203 1202
      enum OpType {
1204 1203
        D1, D2, D3
1205 1204
      };
1206 1205

	
1207 1206
      int unmatched = _node_num;
1208 1207
      while (unmatched > 0) {
1209 1208
        Value d1 = !_delta1->empty() ?
1210 1209
          _delta1->prio() : std::numeric_limits<Value>::max();
1211 1210

	
1212 1211
        Value d2 = !_delta2->empty() ?
1213 1212
          _delta2->prio() : std::numeric_limits<Value>::max();
1214 1213

	
1215 1214
        Value d3 = !_delta3->empty() ?
1216 1215
          _delta3->prio() : std::numeric_limits<Value>::max();
1217 1216

	
1218 1217
        _delta_sum = d3; OpType ot = D3;
1219 1218
        if (d1 < _delta_sum) { _delta_sum = d1; ot = D1; }
1220 1219
        if (d2 < _delta_sum) { _delta_sum = d2; ot = D2; }
1221 1220

	
1222 1221
        switch (ot) {
1223 1222
        case D1:
1224 1223
          {
1225 1224
            Node n = _delta1->top();
1226 1225
            unmatchNode(n);
1227 1226
            --unmatched;
1228 1227
          }
1229 1228
          break;
1230 1229
        case D2:
1231 1230
          {
1232 1231
            Node n = _delta2->top();
1233 1232
            Arc a = (*_pred)[n];
1234 1233
            if ((*_matching)[n] == INVALID) {
1235 1234
              augmentOnArc(a);
1236 1235
              --unmatched;
1237 1236
            } else {
1238 1237
              Node v = _graph.target((*_matching)[n]);
1239 1238
              if ((*_matching)[n] !=
1240 1239
                  _graph.oppositeArc((*_matching)[v])) {
1241 1240
                extractCycle(a);
1242 1241
                --unmatched;
1243 1242
              } else {
1244 1243
                extendOnArc(a);
1245 1244
              }
1246 1245
            }
1247 1246
          } break;
1248 1247
        case D3:
1249 1248
          {
1250 1249
            Edge e = _delta3->top();
1251 1250

	
1252 1251
            Node left = _graph.u(e);
1253 1252
            Node right = _graph.v(e);
1254 1253

	
1255 1254
            int left_tree = _tree_set->find(left);
1256 1255
            int right_tree = _tree_set->find(right);
1257 1256

	
1258 1257
            if (left_tree == right_tree) {
1259 1258
              cycleOnEdge(e, left_tree);
1260 1259
              --unmatched;
1261 1260
            } else {
1262 1261
              augmentOnEdge(e);
1263 1262
              unmatched -= 2;
1264 1263
            }
1265 1264
          } break;
1266 1265
        }
1267 1266
      }
1268 1267
    }
1269 1268

	
1270 1269
    /// \brief Run the algorithm.
1271 1270
    ///
1272 1271
    /// This method runs the \c %MaxWeightedFractionalMatching algorithm.
1273 1272
    ///
1274 1273
    /// \note mwfm.run() is just a shortcut of the following code.
1275 1274
    /// \code
1276 1275
    ///   mwfm.init();
1277 1276
    ///   mwfm.start();
1278 1277
    /// \endcode
1279 1278
    void run() {
1280 1279
      init();
1281 1280
      start();
1282 1281
    }
1283 1282

	
1284 1283
    /// @}
1285 1284

	
1286 1285
    /// \name Primal Solution
1287 1286
    /// Functions to get the primal solution, i.e. the maximum weighted
1288 1287
    /// matching.\n
1289 1288
    /// Either \ref run() or \ref start() function should be called before
1290 1289
    /// using them.
1291 1290

	
1292 1291
    /// @{
1293 1292

	
1294 1293
    /// \brief Return the weight of the matching.
1295 1294
    ///
1296 1295
    /// This function returns the weight of the found matching. This
1297 1296
    /// value is scaled by \ref primalScale "primal scale".
1298 1297
    ///
1299 1298
    /// \pre Either run() or start() must be called before using this function.
1300 1299
    Value matchingWeight() const {
1301 1300
      Value sum = 0;
1302 1301
      for (NodeIt n(_graph); n != INVALID; ++n) {
1303 1302
        if ((*_matching)[n] != INVALID) {
1304 1303
          sum += _weight[(*_matching)[n]];
1305 1304
        }
1306 1305
      }
1307 1306
      return sum * primalScale / 2;
1308 1307
    }
1309 1308

	
1310 1309
    /// \brief Return the number of covered nodes in the matching.
1311 1310
    ///
1312 1311
    /// This function returns the number of covered nodes in the matching.
1313 1312
    ///
1314 1313
    /// \pre Either run() or start() must be called before using this function.
1315 1314
    int matchingSize() const {
1316 1315
      int num = 0;
1317 1316
      for (NodeIt n(_graph); n != INVALID; ++n) {
1318 1317
        if ((*_matching)[n] != INVALID) {
1319 1318
          ++num;
1320 1319
        }
1321 1320
      }
1322 1321
      return num;
1323 1322
    }
1324 1323

	
1325 1324
    /// \brief Return \c true if the given edge is in the matching.
1326 1325
    ///
1327 1326
    /// This function returns \c true if the given edge is in the
1328 1327
    /// found matching. The result is scaled by \ref primalScale
1329 1328
    /// "primal scale".
1330 1329
    ///
1331 1330
    /// \pre Either run() or start() must be called before using this function.
1332
    Value matching(const Edge& edge) const {
1333
      return Value(edge == (*_matching)[_graph.u(edge)] ? 1 : 0)
1334
        * primalScale / 2 + Value(edge == (*_matching)[_graph.v(edge)] ? 1 : 0)
1335
        * primalScale / 2;
1331
    int matching(const Edge& edge) const {
1332
      return (edge == (*_matching)[_graph.u(edge)] ? 1 : 0)
1333
        + (edge == (*_matching)[_graph.v(edge)] ? 1 : 0);
1336 1334
    }
1337 1335

	
1338 1336
    /// \brief Return the fractional matching arc (or edge) incident
1339 1337
    /// to the given node.
1340 1338
    ///
1341 1339
    /// This function returns one of the fractional matching arc (or
1342 1340
    /// edge) incident to the given node in the found matching or \c
1343 1341
    /// INVALID if the node is not covered by the matching or if the
1344 1342
    /// node is on an odd length cycle then it is the successor edge
1345 1343
    /// on the cycle.
1346 1344
    ///
1347 1345
    /// \pre Either run() or start() must be called before using this function.
1348 1346
    Arc matching(const Node& node) const {
1349 1347
      return (*_matching)[node];
1350 1348
    }
1351 1349

	
1352 1350
    /// \brief Return a const reference to the matching map.
1353 1351
    ///
1354 1352
    /// This function returns a const reference to a node map that stores
1355 1353
    /// the matching arc (or edge) incident to each node.
1356 1354
    const MatchingMap& matchingMap() const {
1357 1355
      return *_matching;
1358 1356
    }
1359 1357

	
1360 1358
    /// @}
1361 1359

	
1362 1360
    /// \name Dual Solution
1363 1361
    /// Functions to get the dual solution.\n
1364 1362
    /// Either \ref run() or \ref start() function should be called before
1365 1363
    /// using them.
1366 1364

	
1367 1365
    /// @{
1368 1366

	
1369 1367
    /// \brief Return the value of the dual solution.
1370 1368
    ///
1371 1369
    /// This function returns the value of the dual solution.
1372 1370
    /// It should be equal to the primal value scaled by \ref dualScale
1373 1371
    /// "dual scale".
1374 1372
    ///
1375 1373
    /// \pre Either run() or start() must be called before using this function.
1376 1374
    Value dualValue() const {
1377 1375
      Value sum = 0;
1378 1376
      for (NodeIt n(_graph); n != INVALID; ++n) {
1379 1377
        sum += nodeValue(n);
1380 1378
      }
1381 1379
      return sum;
1382 1380
    }
1383 1381

	
1384 1382
    /// \brief Return the dual value (potential) of the given node.
1385 1383
    ///
1386 1384
    /// This function returns the dual value (potential) of the given node.
1387 1385
    ///
1388 1386
    /// \pre Either run() or start() must be called before using this function.
1389 1387
    Value nodeValue(const Node& n) const {
1390 1388
      return (*_node_potential)[n];
1391 1389
    }
1392 1390

	
1393 1391
    /// @}
1394 1392

	
1395 1393
  };
1396 1394

	
1397 1395
  /// \ingroup matching
1398 1396
  ///
1399 1397
  /// \brief Weighted fractional perfect matching in general graphs
1400 1398
  ///
1401 1399
  /// This class provides an efficient implementation of fractional
1402 1400
  /// matching algorithm. The implementation uses priority queues and
1403 1401
  /// provides \f$O(nm\log n)\f$ time complexity.
1404 1402
  ///
1405 1403
  /// The maximum weighted fractional perfect matching is a relaxation
1406 1404
  /// of the maximum weighted perfect matching problem where the odd
1407 1405
  /// set constraints are omitted.
1408 1406
  /// It can be formulated with the following linear program.
1409 1407
  /// \f[ \sum_{e \in \delta(u)}x_e = 1 \quad \forall u\in V\f]
1410 1408
  /// \f[x_e \ge 0\quad \forall e\in E\f]
1411 1409
  /// \f[\max \sum_{e\in E}x_ew_e\f]
1412 1410
  /// where \f$\delta(X)\f$ is the set of edges incident to a node in
1413 1411
  /// \f$X\f$. The result must be the union of a matching with one
1414 1412
  /// value edges and a set of odd length cycles with half value edges.
1415 1413
  ///
1416 1414
  /// The algorithm calculates an optimal fractional matching and a
1417 1415
  /// proof of the optimality. The solution of the dual problem can be
1418 1416
  /// used to check the result of the algorithm. The dual linear
1419 1417
  /// problem is the following.
1420 1418
  /// \f[ y_u + y_v \ge w_{uv} \quad \forall uv\in E\f]
1421 1419
  /// \f[\min \sum_{u \in V}y_u \f]
1422 1420
  ///
1423 1421
  /// The algorithm can be executed with the run() function.
1424 1422
  /// After it the matching (the primal solution) and the dual solution
1425 1423
  /// can be obtained using the query functions.
1426

	
1427
  /// If the value type is integer, then the primal and the dual
1428
  /// solutions are multiplied by
1429
  /// \ref MaxWeightedPerfectFractionalMatching::primalScale "2" and
1430
  /// \ref MaxWeightedPerfectFractionalMatching::dualScale "4" respectively.
1424
  ///
1425
  /// The primal solution is multiplied by
1426
  /// \ref MaxWeightedPerfectFractionalMatching::primalScale "2".
1427
  /// If the value type is integer, then the dual
1428
  /// solution is scaled by
1429
  /// \ref MaxWeightedPerfectFractionalMatching::dualScale "4".
1431 1430
  ///
1432 1431
  /// \tparam GR The undirected graph type the algorithm runs on.
1433 1432
  /// \tparam WM The type edge weight map. The default type is
1434 1433
  /// \ref concepts::Graph::EdgeMap "GR::EdgeMap<int>".
1435 1434
#ifdef DOXYGEN
1436 1435
  template <typename GR, typename WM>
1437 1436
#else
1438 1437
  template <typename GR,
1439 1438
            typename WM = typename GR::template EdgeMap<int> >
1440 1439
#endif
1441 1440
  class MaxWeightedPerfectFractionalMatching {
1442 1441
  public:
1443 1442

	
1444 1443
    /// The graph type of the algorithm
1445 1444
    typedef GR Graph;
1446 1445
    /// The type of the edge weight map
1447 1446
    typedef WM WeightMap;
1448 1447
    /// The value type of the edge weights
1449 1448
    typedef typename WeightMap::Value Value;
1450 1449

	
1451 1450
    /// The type of the matching map
1452 1451
    typedef typename Graph::template NodeMap<typename Graph::Arc>
1453 1452
    MatchingMap;
1454 1453

	
1455 1454
    /// \brief Scaling factor for primal solution
1456 1455
    ///
1457
    /// Scaling factor for primal solution. It is equal to 2 or 1
1458
    /// according to the value type.
1459
    static const int primalScale =
1460
      std::numeric_limits<Value>::is_integer ? 2 : 1;
1456
    /// Scaling factor for primal solution.
1457
    static const int primalScale = 2;
1461 1458

	
1462 1459
    /// \brief Scaling factor for dual solution
1463 1460
    ///
1464 1461
    /// Scaling factor for dual solution. It is equal to 4 or 1
1465 1462
    /// according to the value type.
1466 1463
    static const int dualScale =
1467 1464
      std::numeric_limits<Value>::is_integer ? 4 : 1;
1468 1465

	
1469 1466
  private:
1470 1467

	
1471 1468
    TEMPLATE_GRAPH_TYPEDEFS(Graph);
1472 1469

	
1473 1470
    typedef typename Graph::template NodeMap<Value> NodePotential;
1474 1471

	
1475 1472
    const Graph& _graph;
1476 1473
    const WeightMap& _weight;
1477 1474

	
1478 1475
    MatchingMap* _matching;
1479 1476
    NodePotential* _node_potential;
1480 1477

	
1481 1478
    int _node_num;
1482 1479
    bool _allow_loops;
1483 1480

	
1484 1481
    enum Status {
1485 1482
      EVEN = -1, MATCHED = 0, ODD = 1
1486 1483
    };
1487 1484

	
1488 1485
    typedef typename Graph::template NodeMap<Status> StatusMap;
1489 1486
    StatusMap* _status;
1490 1487

	
1491 1488
    typedef typename Graph::template NodeMap<Arc> PredMap;
1492 1489
    PredMap* _pred;
1493 1490

	
1494 1491
    typedef ExtendFindEnum<IntNodeMap> TreeSet;
1495 1492

	
1496 1493
    IntNodeMap *_tree_set_index;
1497 1494
    TreeSet *_tree_set;
1498 1495

	
1499 1496
    IntNodeMap *_delta2_index;
1500 1497
    BinHeap<Value, IntNodeMap> *_delta2;
1501 1498

	
1502 1499
    IntEdgeMap *_delta3_index;
1503 1500
    BinHeap<Value, IntEdgeMap> *_delta3;
1504 1501

	
1505 1502
    Value _delta_sum;
1506 1503

	
1507 1504
    void createStructures() {
1508 1505
      _node_num = countNodes(_graph);
1509 1506

	
1510 1507
      if (!_matching) {
1511 1508
        _matching = new MatchingMap(_graph);
1512 1509
      }
1513 1510
      if (!_node_potential) {
1514 1511
        _node_potential = new NodePotential(_graph);
1515 1512
      }
1516 1513
      if (!_status) {
1517 1514
        _status = new StatusMap(_graph);
1518 1515
      }
1519 1516
      if (!_pred) {
1520 1517
        _pred = new PredMap(_graph);
1521 1518
      }
1522 1519
      if (!_tree_set) {
1523 1520
        _tree_set_index = new IntNodeMap(_graph);
1524 1521
        _tree_set = new TreeSet(*_tree_set_index);
1525 1522
      }
1526 1523
      if (!_delta2) {
1527 1524
        _delta2_index = new IntNodeMap(_graph);
1528 1525
        _delta2 = new BinHeap<Value, IntNodeMap>(*_delta2_index);
1529 1526
      }
1530 1527
      if (!_delta3) {
1531 1528
        _delta3_index = new IntEdgeMap(_graph);
1532 1529
        _delta3 = new BinHeap<Value, IntEdgeMap>(*_delta3_index);
1533 1530
      }
1534 1531
    }
1535 1532

	
1536 1533
    void destroyStructures() {
1537 1534
      if (_matching) {
1538 1535
        delete _matching;
1539 1536
      }
1540 1537
      if (_node_potential) {
1541 1538
        delete _node_potential;
1542 1539
      }
1543 1540
      if (_status) {
1544 1541
        delete _status;
1545 1542
      }
1546 1543
      if (_pred) {
1547 1544
        delete _pred;
1548 1545
      }
1549 1546
      if (_tree_set) {
1550 1547
        delete _tree_set_index;
1551 1548
        delete _tree_set;
1552 1549
      }
1553 1550
      if (_delta2) {
1554 1551
        delete _delta2_index;
1555 1552
        delete _delta2;
1556 1553
      }
1557 1554
      if (_delta3) {
1558 1555
        delete _delta3_index;
1559 1556
        delete _delta3;
1560 1557
      }
1561 1558
    }
1562 1559

	
1563 1560
    void matchedToEven(Node node, int tree) {
1564 1561
      _tree_set->insert(node, tree);
1565 1562
      _node_potential->set(node, (*_node_potential)[node] + _delta_sum);
1566 1563

	
1567 1564
      if (_delta2->state(node) == _delta2->IN_HEAP) {
1568 1565
        _delta2->erase(node);
1569 1566
      }
1570 1567

	
1571 1568
      for (InArcIt a(_graph, node); a != INVALID; ++a) {
1572 1569
        Node v = _graph.source(a);
1573 1570
        Value rw = (*_node_potential)[node] + (*_node_potential)[v] -
1574 1571
          dualScale * _weight[a];
1575 1572
        if (node == v) {
1576 1573
          if (_allow_loops && _graph.direction(a)) {
1577 1574
            _delta3->push(a, rw / 2);
1578 1575
          }
1579 1576
        } else if ((*_status)[v] == EVEN) {
1580 1577
          _delta3->push(a, rw / 2);
1581 1578
        } else if ((*_status)[v] == MATCHED) {
1582 1579
          if (_delta2->state(v) != _delta2->IN_HEAP) {
1583 1580
            _pred->set(v, a);
1584 1581
            _delta2->push(v, rw);
1585 1582
          } else if ((*_delta2)[v] > rw) {
1586 1583
            _pred->set(v, a);
1587 1584
            _delta2->decrease(v, rw);
1588 1585
          }
1589 1586
        }
1590 1587
      }
1591 1588
    }
1592 1589

	
1593 1590
    void matchedToOdd(Node node, int tree) {
1594 1591
      _tree_set->insert(node, tree);
1595 1592
      _node_potential->set(node, (*_node_potential)[node] - _delta_sum);
1596 1593

	
1597 1594
      if (_delta2->state(node) == _delta2->IN_HEAP) {
1598 1595
        _delta2->erase(node);
1599 1596
      }
1600 1597
    }
1601 1598

	
1602 1599
    void evenToMatched(Node node, int tree) {
1603 1600
      _node_potential->set(node, (*_node_potential)[node] - _delta_sum);
1604 1601
      Arc min = INVALID;
1605 1602
      Value minrw = std::numeric_limits<Value>::max();
1606 1603
      for (InArcIt a(_graph, node); a != INVALID; ++a) {
1607 1604
        Node v = _graph.source(a);
1608 1605
        Value rw = (*_node_potential)[node] + (*_node_potential)[v] -
1609 1606
          dualScale * _weight[a];
1610 1607

	
1611 1608
        if (node == v) {
1612 1609
          if (_allow_loops && _graph.direction(a)) {
1613 1610
            _delta3->erase(a);
1614 1611
          }
1615 1612
        } else if ((*_status)[v] == EVEN) {
1616 1613
          _delta3->erase(a);
1617 1614
          if (minrw > rw) {
1618 1615
            min = _graph.oppositeArc(a);
1619 1616
            minrw = rw;
1620 1617
          }
1621 1618
        } else if ((*_status)[v]  == MATCHED) {
1622 1619
          if ((*_pred)[v] == a) {
1623 1620
            Arc mina = INVALID;
1624 1621
            Value minrwa = std::numeric_limits<Value>::max();
1625 1622
            for (OutArcIt aa(_graph, v); aa != INVALID; ++aa) {
1626 1623
              Node va = _graph.target(aa);
1627 1624
              if ((*_status)[va] != EVEN ||
1628 1625
                  _tree_set->find(va) == tree) continue;
1629 1626
              Value rwa = (*_node_potential)[v] + (*_node_potential)[va] -
1630 1627
                dualScale * _weight[aa];
1631 1628
              if (minrwa > rwa) {
1632 1629
                minrwa = rwa;
1633 1630
                mina = aa;
1634 1631
              }
1635 1632
            }
1636 1633
            if (mina != INVALID) {
1637 1634
              _pred->set(v, mina);
1638 1635
              _delta2->increase(v, minrwa);
1639 1636
            } else {
1640 1637
              _pred->set(v, INVALID);
1641 1638
              _delta2->erase(v);
1642 1639
            }
1643 1640
          }
1644 1641
        }
1645 1642
      }
1646 1643
      if (min != INVALID) {
1647 1644
        _pred->set(node, min);
1648 1645
        _delta2->push(node, minrw);
1649 1646
      } else {
1650 1647
        _pred->set(node, INVALID);
1651 1648
      }
1652 1649
    }
... ...
@@ -1875,260 +1872,259 @@
1875 1872
    MaxWeightedPerfectFractionalMatching(const Graph& graph,
1876 1873
                                         const WeightMap& weight,
1877 1874
                                         bool allow_loops = true)
1878 1875
      : _graph(graph), _weight(weight), _matching(0),
1879 1876
      _node_potential(0), _node_num(0), _allow_loops(allow_loops),
1880 1877
      _status(0),  _pred(0),
1881 1878
      _tree_set_index(0), _tree_set(0),
1882 1879

	
1883 1880
      _delta2_index(0), _delta2(0),
1884 1881
      _delta3_index(0), _delta3(0),
1885 1882

	
1886 1883
      _delta_sum() {}
1887 1884

	
1888 1885
    ~MaxWeightedPerfectFractionalMatching() {
1889 1886
      destroyStructures();
1890 1887
    }
1891 1888

	
1892 1889
    /// \name Execution Control
1893 1890
    /// The simplest way to execute the algorithm is to use the
1894 1891
    /// \ref run() member function.
1895 1892

	
1896 1893
    ///@{
1897 1894

	
1898 1895
    /// \brief Initialize the algorithm
1899 1896
    ///
1900 1897
    /// This function initializes the algorithm.
1901 1898
    void init() {
1902 1899
      createStructures();
1903 1900

	
1904 1901
      for (NodeIt n(_graph); n != INVALID; ++n) {
1905 1902
        (*_delta2_index)[n] = _delta2->PRE_HEAP;
1906 1903
      }
1907 1904
      for (EdgeIt e(_graph); e != INVALID; ++e) {
1908 1905
        (*_delta3_index)[e] = _delta3->PRE_HEAP;
1909 1906
      }
1910 1907

	
1911 1908
      for (NodeIt n(_graph); n != INVALID; ++n) {
1912 1909
        Value max = - std::numeric_limits<Value>::max();
1913 1910
        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
1914 1911
          if (_graph.target(e) == n && !_allow_loops) continue;
1915 1912
          if ((dualScale * _weight[e]) / 2 > max) {
1916 1913
            max = (dualScale * _weight[e]) / 2;
1917 1914
          }
1918 1915
        }
1919 1916
        _node_potential->set(n, max);
1920 1917

	
1921 1918
        _tree_set->insert(n);
1922 1919

	
1923 1920
        _matching->set(n, INVALID);
1924 1921
        _status->set(n, EVEN);
1925 1922
      }
1926 1923

	
1927 1924
      for (EdgeIt e(_graph); e != INVALID; ++e) {
1928 1925
        Node left = _graph.u(e);
1929 1926
        Node right = _graph.v(e);
1930 1927
        if (left == right && !_allow_loops) continue;
1931 1928
        _delta3->push(e, ((*_node_potential)[left] +
1932 1929
                          (*_node_potential)[right] -
1933 1930
                          dualScale * _weight[e]) / 2);
1934 1931
      }
1935 1932
    }
1936 1933

	
1937 1934
    /// \brief Start the algorithm
1938 1935
    ///
1939 1936
    /// This function starts the algorithm.
1940 1937
    ///
1941 1938
    /// \pre \ref init() must be called before using this function.
1942 1939
    bool start() {
1943 1940
      enum OpType {
1944 1941
        D2, D3
1945 1942
      };
1946 1943

	
1947 1944
      int unmatched = _node_num;
1948 1945
      while (unmatched > 0) {
1949 1946
        Value d2 = !_delta2->empty() ?
1950 1947
          _delta2->prio() : std::numeric_limits<Value>::max();
1951 1948

	
1952 1949
        Value d3 = !_delta3->empty() ?
1953 1950
          _delta3->prio() : std::numeric_limits<Value>::max();
1954 1951

	
1955 1952
        _delta_sum = d3; OpType ot = D3;
1956 1953
        if (d2 < _delta_sum) { _delta_sum = d2; ot = D2; }
1957 1954

	
1958 1955
        if (_delta_sum == std::numeric_limits<Value>::max()) {
1959 1956
          return false;
1960 1957
        }
1961 1958

	
1962 1959
        switch (ot) {
1963 1960
        case D2:
1964 1961
          {
1965 1962
            Node n = _delta2->top();
1966 1963
            Arc a = (*_pred)[n];
1967 1964
            if ((*_matching)[n] == INVALID) {
1968 1965
              augmentOnArc(a);
1969 1966
              --unmatched;
1970 1967
            } else {
1971 1968
              Node v = _graph.target((*_matching)[n]);
1972 1969
              if ((*_matching)[n] !=
1973 1970
                  _graph.oppositeArc((*_matching)[v])) {
1974 1971
                extractCycle(a);
1975 1972
                --unmatched;
1976 1973
              } else {
1977 1974
                extendOnArc(a);
1978 1975
              }
1979 1976
            }
1980 1977
          } break;
1981 1978
        case D3:
1982 1979
          {
1983 1980
            Edge e = _delta3->top();
1984 1981

	
1985 1982
            Node left = _graph.u(e);
1986 1983
            Node right = _graph.v(e);
1987 1984

	
1988 1985
            int left_tree = _tree_set->find(left);
1989 1986
            int right_tree = _tree_set->find(right);
1990 1987

	
1991 1988
            if (left_tree == right_tree) {
1992 1989
              cycleOnEdge(e, left_tree);
1993 1990
              --unmatched;
1994 1991
            } else {
1995 1992
              augmentOnEdge(e);
1996 1993
              unmatched -= 2;
1997 1994
            }
1998 1995
          } break;
1999 1996
        }
2000 1997
      }
2001 1998
      return true;
2002 1999
    }
2003 2000

	
2004 2001
    /// \brief Run the algorithm.
2005 2002
    ///
2006 2003
    /// This method runs the \c %MaxWeightedPerfectFractionalMatching 
2007 2004
    /// algorithm.
2008 2005
    ///
2009 2006
    /// \note mwfm.run() is just a shortcut of the following code.
2010 2007
    /// \code
2011 2008
    ///   mwpfm.init();
2012 2009
    ///   mwpfm.start();
2013 2010
    /// \endcode
2014 2011
    bool run() {
2015 2012
      init();
2016 2013
      return start();
2017 2014
    }
2018 2015

	
2019 2016
    /// @}
2020 2017

	
2021 2018
    /// \name Primal Solution
2022 2019
    /// Functions to get the primal solution, i.e. the maximum weighted
2023 2020
    /// matching.\n
2024 2021
    /// Either \ref run() or \ref start() function should be called before
2025 2022
    /// using them.
2026 2023

	
2027 2024
    /// @{
2028 2025

	
2029 2026
    /// \brief Return the weight of the matching.
2030 2027
    ///
2031 2028
    /// This function returns the weight of the found matching. This
2032 2029
    /// value is scaled by \ref primalScale "primal scale".
2033 2030
    ///
2034 2031
    /// \pre Either run() or start() must be called before using this function.
2035 2032
    Value matchingWeight() const {
2036 2033
      Value sum = 0;
2037 2034
      for (NodeIt n(_graph); n != INVALID; ++n) {
2038 2035
        if ((*_matching)[n] != INVALID) {
2039 2036
          sum += _weight[(*_matching)[n]];
2040 2037
        }
2041 2038
      }
2042 2039
      return sum * primalScale / 2;
2043 2040
    }
2044 2041

	
2045 2042
    /// \brief Return the number of covered nodes in the matching.
2046 2043
    ///
2047 2044
    /// This function returns the number of covered nodes in the matching.
2048 2045
    ///
2049 2046
    /// \pre Either run() or start() must be called before using this function.
2050 2047
    int matchingSize() const {
2051 2048
      int num = 0;
2052 2049
      for (NodeIt n(_graph); n != INVALID; ++n) {
2053 2050
        if ((*_matching)[n] != INVALID) {
2054 2051
          ++num;
2055 2052
        }
2056 2053
      }
2057 2054
      return num;
2058 2055
    }
2059 2056

	
2060 2057
    /// \brief Return \c true if the given edge is in the matching.
2061 2058
    ///
2062 2059
    /// This function returns \c true if the given edge is in the
2063 2060
    /// found matching. The result is scaled by \ref primalScale
2064 2061
    /// "primal scale".
2065 2062
    ///
2066 2063
    /// \pre Either run() or start() must be called before using this function.
2067
    Value matching(const Edge& edge) const {
2068
      return Value(edge == (*_matching)[_graph.u(edge)] ? 1 : 0)
2069
        * primalScale / 2 + Value(edge == (*_matching)[_graph.v(edge)] ? 1 : 0)
2070
        * primalScale / 2;
2064
    int matching(const Edge& edge) const {
2065
      return (edge == (*_matching)[_graph.u(edge)] ? 1 : 0)
2066
        + (edge == (*_matching)[_graph.v(edge)] ? 1 : 0);
2071 2067
    }
2072 2068

	
2073 2069
    /// \brief Return the fractional matching arc (or edge) incident
2074 2070
    /// to the given node.
2075 2071
    ///
2076 2072
    /// This function returns one of the fractional matching arc (or
2077 2073
    /// edge) incident to the given node in the found matching or \c
2078 2074
    /// INVALID if the node is not covered by the matching or if the
2079 2075
    /// node is on an odd length cycle then it is the successor edge
2080 2076
    /// on the cycle.
2081 2077
    ///
2082 2078
    /// \pre Either run() or start() must be called before using this function.
2083 2079
    Arc matching(const Node& node) const {
2084 2080
      return (*_matching)[node];
2085 2081
    }
2086 2082

	
2087 2083
    /// \brief Return a const reference to the matching map.
2088 2084
    ///
2089 2085
    /// This function returns a const reference to a node map that stores
2090 2086
    /// the matching arc (or edge) incident to each node.
2091 2087
    const MatchingMap& matchingMap() const {
2092 2088
      return *_matching;
2093 2089
    }
2094 2090

	
2095 2091
    /// @}
2096 2092

	
2097 2093
    /// \name Dual Solution
2098 2094
    /// Functions to get the dual solution.\n
2099 2095
    /// Either \ref run() or \ref start() function should be called before
2100 2096
    /// using them.
2101 2097

	
2102 2098
    /// @{
2103 2099

	
2104 2100
    /// \brief Return the value of the dual solution.
2105 2101
    ///
2106 2102
    /// This function returns the value of the dual solution.
2107 2103
    /// It should be equal to the primal value scaled by \ref dualScale
2108 2104
    /// "dual scale".
2109 2105
    ///
2110 2106
    /// \pre Either run() or start() must be called before using this function.
2111 2107
    Value dualValue() const {
2112 2108
      Value sum = 0;
2113 2109
      for (NodeIt n(_graph); n != INVALID; ++n) {
2114 2110
        sum += nodeValue(n);
2115 2111
      }
2116 2112
      return sum;
2117 2113
    }
2118 2114

	
2119 2115
    /// \brief Return the dual value (potential) of the given node.
2120 2116
    ///
2121 2117
    /// This function returns the dual value (potential) of the given node.
2122 2118
    ///
2123 2119
    /// \pre Either run() or start() must be called before using this function.
2124 2120
    Value nodeValue(const Node& n) const {
2125 2121
      return (*_node_potential)[n];
2126 2122
    }
2127 2123

	
2128 2124
    /// @}
2129 2125

	
2130 2126
  };
2131 2127

	
2132 2128
} //END OF NAMESPACE LEMON
2133 2129

	
2134 2130
#endif //LEMON_FRACTIONAL_MATCHING_H
Ignore white space 6 line context
... ...
@@ -47,456 +47,479 @@
47 47
  "3\n"
48 48
  "4\n"
49 49
  "5\n"
50 50
  "6\n"
51 51
  "7\n"
52 52
  "@edges\n"
53 53
  "     label  weight\n"
54 54
  "7 4  0      984\n"
55 55
  "0 7  1      73\n"
56 56
  "7 1  2      204\n"
57 57
  "2 3  3      583\n"
58 58
  "2 7  4      565\n"
59 59
  "2 1  5      582\n"
60 60
  "0 4  6      551\n"
61 61
  "2 5  7      385\n"
62 62
  "1 5  8      561\n"
63 63
  "5 3  9      484\n"
64 64
  "7 5  10     904\n"
65 65
  "3 6  11     47\n"
66 66
  "7 6  12     888\n"
67 67
  "3 0  13     747\n"
68 68
  "6 1  14     310\n",
69 69

	
70 70
  "@nodes\n"
71 71
  "label\n"
72 72
  "0\n"
73 73
  "1\n"
74 74
  "2\n"
75 75
  "3\n"
76 76
  "4\n"
77 77
  "5\n"
78 78
  "6\n"
79 79
  "7\n"
80 80
  "@edges\n"
81 81
  "     label  weight\n"
82 82
  "2 5  0      710\n"
83 83
  "0 5  1      241\n"
84 84
  "2 4  2      856\n"
85 85
  "2 6  3      762\n"
86 86
  "4 1  4      747\n"
87 87
  "6 1  5      962\n"
88 88
  "4 7  6      723\n"
89 89
  "1 7  7      661\n"
90 90
  "2 3  8      376\n"
91 91
  "1 0  9      416\n"
92 92
  "6 7  10     391\n",
93 93

	
94 94
  "@nodes\n"
95 95
  "label\n"
96 96
  "0\n"
97 97
  "1\n"
98 98
  "2\n"
99 99
  "3\n"
100 100
  "4\n"
101 101
  "5\n"
102 102
  "6\n"
103 103
  "7\n"
104 104
  "@edges\n"
105 105
  "     label  weight\n"
106 106
  "6 2  0      553\n"
107 107
  "0 7  1      653\n"
108 108
  "6 3  2      22\n"
109 109
  "4 7  3      846\n"
110 110
  "7 2  4      981\n"
111 111
  "7 6  5      250\n"
112 112
  "5 2  6      539\n",
113 113

	
114 114
  "@nodes\n"
115 115
  "label\n"
116 116
  "0\n"
117 117
  "@edges\n"
118 118
  "     label  weight\n"
119 119
  "0 0  0      100\n"
120 120
};
121 121

	
122 122
void checkMaxFractionalMatchingCompile()
123 123
{
124 124
  typedef concepts::Graph Graph;
125 125
  typedef Graph::Node Node;
126 126
  typedef Graph::Edge Edge;
127 127

	
128 128
  Graph g;
129 129
  Node n;
130 130
  Edge e;
131 131

	
132 132
  MaxFractionalMatching<Graph> mat_test(g);
133 133
  const MaxFractionalMatching<Graph>&
134 134
    const_mat_test = mat_test;
135 135

	
136 136
  mat_test.init();
137 137
  mat_test.start();
138 138
  mat_test.start(true);
139 139
  mat_test.startPerfect();
140 140
  mat_test.startPerfect(true);
141 141
  mat_test.run();
142 142
  mat_test.run(true);
143 143
  mat_test.runPerfect();
144 144
  mat_test.runPerfect(true);
145 145

	
146 146
  const_mat_test.matchingSize();
147 147
  const_mat_test.matching(e);
148 148
  const_mat_test.matching(n);
149 149
  const MaxFractionalMatching<Graph>::MatchingMap& mmap =
150 150
    const_mat_test.matchingMap();
151 151
  e = mmap[n];
152 152

	
153 153
  const_mat_test.barrier(n);
154 154
}
155 155

	
156 156
void checkMaxWeightedFractionalMatchingCompile()
157 157
{
158 158
  typedef concepts::Graph Graph;
159 159
  typedef Graph::Node Node;
160 160
  typedef Graph::Edge Edge;
161 161
  typedef Graph::EdgeMap<int> WeightMap;
162 162

	
163 163
  Graph g;
164 164
  Node n;
165 165
  Edge e;
166 166
  WeightMap w(g);
167 167

	
168 168
  MaxWeightedFractionalMatching<Graph> mat_test(g, w);
169 169
  const MaxWeightedFractionalMatching<Graph>&
170 170
    const_mat_test = mat_test;
171 171

	
172 172
  mat_test.init();
173 173
  mat_test.start();
174 174
  mat_test.run();
175 175

	
176 176
  const_mat_test.matchingWeight();
177 177
  const_mat_test.matchingSize();
178 178
  const_mat_test.matching(e);
179 179
  const_mat_test.matching(n);
180 180
  const MaxWeightedFractionalMatching<Graph>::MatchingMap& mmap =
181 181
    const_mat_test.matchingMap();
182 182
  e = mmap[n];
183 183

	
184 184
  const_mat_test.dualValue();
185 185
  const_mat_test.nodeValue(n);
186 186
}
187 187

	
188 188
void checkMaxWeightedPerfectFractionalMatchingCompile()
189 189
{
190 190
  typedef concepts::Graph Graph;
191 191
  typedef Graph::Node Node;
192 192
  typedef Graph::Edge Edge;
193 193
  typedef Graph::EdgeMap<int> WeightMap;
194 194

	
195 195
  Graph g;
196 196
  Node n;
197 197
  Edge e;
198 198
  WeightMap w(g);
199 199

	
200 200
  MaxWeightedPerfectFractionalMatching<Graph> mat_test(g, w);
201 201
  const MaxWeightedPerfectFractionalMatching<Graph>&
202 202
    const_mat_test = mat_test;
203 203

	
204 204
  mat_test.init();
205 205
  mat_test.start();
206 206
  mat_test.run();
207 207

	
208 208
  const_mat_test.matchingWeight();
209 209
  const_mat_test.matching(e);
210 210
  const_mat_test.matching(n);
211 211
  const MaxWeightedPerfectFractionalMatching<Graph>::MatchingMap& mmap =
212 212
    const_mat_test.matchingMap();
213 213
  e = mmap[n];
214 214

	
215 215
  const_mat_test.dualValue();
216 216
  const_mat_test.nodeValue(n);
217 217
}
218 218

	
219 219
void checkFractionalMatching(const SmartGraph& graph,
220 220
                             const MaxFractionalMatching<SmartGraph>& mfm,
221 221
                             bool allow_loops = true) {
222 222
  int pv = 0;
223 223
  for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
224 224
    int indeg = 0;
225 225
    for (InArcIt a(graph, n); a != INVALID; ++a) {
226 226
      if (mfm.matching(graph.source(a)) == a) {
227 227
        ++indeg;
228 228
      }
229 229
    }
230 230
    if (mfm.matching(n) != INVALID) {
231 231
      check(indeg == 1, "Invalid matching");
232 232
      ++pv;
233 233
    } else {
234 234
      check(indeg == 0, "Invalid matching");
235 235
    }
236 236
  }
237 237
  check(pv == mfm.matchingSize(), "Wrong matching size");
238 238

	
239
  for (SmartGraph::EdgeIt e(graph); e != INVALID; ++e) {
240
    check((e == mfm.matching(graph.u(e)) ? 1 : 0) +
241
          (e == mfm.matching(graph.v(e)) ? 1 : 0) == 
242
          mfm.matching(e), "Invalid matching");
243
  }
244

	
239 245
  SmartGraph::NodeMap<bool> processed(graph, false);
240 246
  for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
241 247
    if (processed[n]) continue;
242 248
    processed[n] = true;
243 249
    if (mfm.matching(n) == INVALID) continue;
244 250
    int num = 1;
245 251
    Node v = graph.target(mfm.matching(n));
246 252
    while (v != n) {
247 253
      processed[v] = true;
248 254
      ++num;
249 255
      v = graph.target(mfm.matching(v));
250 256
    }
251 257
    check(num == 2 || num % 2 == 1, "Wrong cycle size");
252 258
    check(allow_loops || num != 1, "Wrong cycle size");
253 259
  }
254 260

	
255 261
  int anum = 0, bnum = 0;
256 262
  SmartGraph::NodeMap<bool> neighbours(graph, false);
257 263
  for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
258 264
    if (!mfm.barrier(n)) continue;
259 265
    ++anum;
260 266
    for (SmartGraph::InArcIt a(graph, n); a != INVALID; ++a) {
261 267
      Node u = graph.source(a);
262 268
      if (!allow_loops && u == n) continue;
263 269
      if (!neighbours[u]) {
264 270
        neighbours[u] = true;
265 271
        ++bnum;
266 272
      }
267 273
    }
268 274
  }
269 275
  check(anum - bnum + mfm.matchingSize() == countNodes(graph),
270 276
        "Wrong barrier");
271 277
}
272 278

	
273 279
void checkPerfectFractionalMatching(const SmartGraph& graph,
274 280
                             const MaxFractionalMatching<SmartGraph>& mfm,
275 281
                             bool perfect, bool allow_loops = true) {
276 282
  if (perfect) {
277 283
    for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
278 284
      int indeg = 0;
279 285
      for (InArcIt a(graph, n); a != INVALID; ++a) {
280 286
        if (mfm.matching(graph.source(a)) == a) {
281 287
          ++indeg;
282 288
        }
283 289
      }
284 290
      check(mfm.matching(n) != INVALID, "Invalid matching");
285 291
      check(indeg == 1, "Invalid matching");
286 292
    }
293
    for (SmartGraph::EdgeIt e(graph); e != INVALID; ++e) {
294
      check((e == mfm.matching(graph.u(e)) ? 1 : 0) +
295
            (e == mfm.matching(graph.v(e)) ? 1 : 0) == 
296
            mfm.matching(e), "Invalid matching");
297
    }
287 298
  } else {
288 299
    int anum = 0, bnum = 0;
289 300
    SmartGraph::NodeMap<bool> neighbours(graph, false);
290 301
    for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
291 302
      if (!mfm.barrier(n)) continue;
292 303
      ++anum;
293 304
      for (SmartGraph::InArcIt a(graph, n); a != INVALID; ++a) {
294 305
        Node u = graph.source(a);
295 306
        if (!allow_loops && u == n) continue;
296 307
        if (!neighbours[u]) {
297 308
          neighbours[u] = true;
298 309
          ++bnum;
299 310
        }
300 311
      }
301 312
    }
302 313
    check(anum - bnum > 0, "Wrong barrier");
303 314
  }
304 315
}
305 316

	
306 317
void checkWeightedFractionalMatching(const SmartGraph& graph,
307 318
                   const SmartGraph::EdgeMap<int>& weight,
308 319
                   const MaxWeightedFractionalMatching<SmartGraph>& mwfm,
309 320
                   bool allow_loops = true) {
310 321
  for (SmartGraph::EdgeIt e(graph); e != INVALID; ++e) {
311 322
    if (graph.u(e) == graph.v(e) && !allow_loops) continue;
312 323
    int rw = mwfm.nodeValue(graph.u(e)) + mwfm.nodeValue(graph.v(e))
313 324
      - weight[e] * mwfm.dualScale;
314 325

	
315 326
    check(rw >= 0, "Negative reduced weight");
316 327
    check(rw == 0 || !mwfm.matching(e),
317 328
          "Non-zero reduced weight on matching edge");
318 329
  }
319 330

	
320 331
  int pv = 0;
321 332
  for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
322 333
    int indeg = 0;
323 334
    for (InArcIt a(graph, n); a != INVALID; ++a) {
324 335
      if (mwfm.matching(graph.source(a)) == a) {
325 336
        ++indeg;
326 337
      }
327 338
    }
328 339
    check(indeg <= 1, "Invalid matching");
329 340
    if (mwfm.matching(n) != INVALID) {
330 341
      check(mwfm.nodeValue(n) >= 0, "Invalid node value");
331 342
      check(indeg == 1, "Invalid matching");
332 343
      pv += weight[mwfm.matching(n)];
333 344
      SmartGraph::Node o = graph.target(mwfm.matching(n));
334 345
    } else {
335 346
      check(mwfm.nodeValue(n) == 0, "Invalid matching");
336 347
      check(indeg == 0, "Invalid matching");
337 348
    }
338 349
  }
339 350

	
351
  for (SmartGraph::EdgeIt e(graph); e != INVALID; ++e) {
352
    check((e == mwfm.matching(graph.u(e)) ? 1 : 0) +
353
          (e == mwfm.matching(graph.v(e)) ? 1 : 0) == 
354
          mwfm.matching(e), "Invalid matching");
355
  }
356

	
340 357
  int dv = 0;
341 358
  for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
342 359
    dv += mwfm.nodeValue(n);
343 360
  }
344 361

	
345 362
  check(pv * mwfm.dualScale == dv * 2, "Wrong duality");
346 363

	
347 364
  SmartGraph::NodeMap<bool> processed(graph, false);
348 365
  for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
349 366
    if (processed[n]) continue;
350 367
    processed[n] = true;
351 368
    if (mwfm.matching(n) == INVALID) continue;
352 369
    int num = 1;
353 370
    Node v = graph.target(mwfm.matching(n));
354 371
    while (v != n) {
355 372
      processed[v] = true;
356 373
      ++num;
357 374
      v = graph.target(mwfm.matching(v));
358 375
    }
359 376
    check(num == 2 || num % 2 == 1, "Wrong cycle size");
360 377
    check(allow_loops || num != 1, "Wrong cycle size");
361 378
  }
362 379

	
363 380
  return;
364 381
}
365 382

	
366 383
void checkWeightedPerfectFractionalMatching(const SmartGraph& graph,
367 384
                const SmartGraph::EdgeMap<int>& weight,
368 385
                const MaxWeightedPerfectFractionalMatching<SmartGraph>& mwpfm,
369 386
                bool allow_loops = true) {
370 387
  for (SmartGraph::EdgeIt e(graph); e != INVALID; ++e) {
371 388
    if (graph.u(e) == graph.v(e) && !allow_loops) continue;
372 389
    int rw = mwpfm.nodeValue(graph.u(e)) + mwpfm.nodeValue(graph.v(e))
373 390
      - weight[e] * mwpfm.dualScale;
374 391

	
375 392
    check(rw >= 0, "Negative reduced weight");
376 393
    check(rw == 0 || !mwpfm.matching(e),
377 394
          "Non-zero reduced weight on matching edge");
378 395
  }
379 396

	
380 397
  int pv = 0;
381 398
  for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
382 399
    int indeg = 0;
383 400
    for (InArcIt a(graph, n); a != INVALID; ++a) {
384 401
      if (mwpfm.matching(graph.source(a)) == a) {
385 402
        ++indeg;
386 403
      }
387 404
    }
388 405
    check(mwpfm.matching(n) != INVALID, "Invalid perfect matching");
389 406
    check(indeg == 1, "Invalid perfect matching");
390 407
    pv += weight[mwpfm.matching(n)];
391 408
    SmartGraph::Node o = graph.target(mwpfm.matching(n));
392 409
  }
393 410

	
411
  for (SmartGraph::EdgeIt e(graph); e != INVALID; ++e) {
412
    check((e == mwpfm.matching(graph.u(e)) ? 1 : 0) +
413
          (e == mwpfm.matching(graph.v(e)) ? 1 : 0) == 
414
          mwpfm.matching(e), "Invalid matching");
415
  }
416

	
394 417
  int dv = 0;
395 418
  for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
396 419
    dv += mwpfm.nodeValue(n);
397 420
  }
398 421

	
399 422
  check(pv * mwpfm.dualScale == dv * 2, "Wrong duality");
400 423

	
401 424
  SmartGraph::NodeMap<bool> processed(graph, false);
402 425
  for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
403 426
    if (processed[n]) continue;
404 427
    processed[n] = true;
405 428
    if (mwpfm.matching(n) == INVALID) continue;
406 429
    int num = 1;
407 430
    Node v = graph.target(mwpfm.matching(n));
408 431
    while (v != n) {
409 432
      processed[v] = true;
410 433
      ++num;
411 434
      v = graph.target(mwpfm.matching(v));
412 435
    }
413 436
    check(num == 2 || num % 2 == 1, "Wrong cycle size");
414 437
    check(allow_loops || num != 1, "Wrong cycle size");
415 438
  }
416 439

	
417 440
  return;
418 441
}
419 442

	
420 443

	
421 444
int main() {
422 445

	
423 446
  for (int i = 0; i < lgfn; ++i) {
424 447
    SmartGraph graph;
425 448
    SmartGraph::EdgeMap<int> weight(graph);
426 449

	
427 450
    istringstream lgfs(lgf[i]);
428 451
    graphReader(graph, lgfs).
429 452
      edgeMap("weight", weight).run();
430 453

	
431 454
    bool perfect_with_loops;
432 455
    {
433 456
      MaxFractionalMatching<SmartGraph> mfm(graph, true);
434 457
      mfm.run();
435 458
      checkFractionalMatching(graph, mfm, true);
436 459
      perfect_with_loops = mfm.matchingSize() == countNodes(graph);
437 460
    }
438 461

	
439 462
    bool perfect_without_loops;
440 463
    {
441 464
      MaxFractionalMatching<SmartGraph> mfm(graph, false);
442 465
      mfm.run();
443 466
      checkFractionalMatching(graph, mfm, false);
444 467
      perfect_without_loops = mfm.matchingSize() == countNodes(graph);
445 468
    }
446 469

	
447 470
    {
448 471
      MaxFractionalMatching<SmartGraph> mfm(graph, true);
449 472
      bool result = mfm.runPerfect();
450 473
      checkPerfectFractionalMatching(graph, mfm, result, true);
451 474
      check(result == perfect_with_loops, "Wrong perfect matching");
452 475
    }
453 476

	
454 477
    {
455 478
      MaxFractionalMatching<SmartGraph> mfm(graph, false);
456 479
      bool result = mfm.runPerfect();
457 480
      checkPerfectFractionalMatching(graph, mfm, result, false);
458 481
      check(result == perfect_without_loops, "Wrong perfect matching");
459 482
    }
460 483

	
461 484
    {
462 485
      MaxWeightedFractionalMatching<SmartGraph> mwfm(graph, weight, true);
463 486
      mwfm.run();
464 487
      checkWeightedFractionalMatching(graph, weight, mwfm, true);
465 488
    }
466 489

	
467 490
    {
468 491
      MaxWeightedFractionalMatching<SmartGraph> mwfm(graph, weight, false);
469 492
      mwfm.run();
470 493
      checkWeightedFractionalMatching(graph, weight, mwfm, false);
471 494
    }
472 495

	
473 496
    {
474 497
      MaxWeightedPerfectFractionalMatching<SmartGraph> mwpfm(graph, weight,
475 498
                                                             true);
476 499
      bool perfect = mwpfm.run();
477 500
      check(perfect == (mwpfm.matchingSize() == countNodes(graph)),
478 501
            "Perfect matching found");
479 502
      check(perfect == perfect_with_loops, "Wrong perfect matching");
480 503

	
481 504
      if (perfect) {
482 505
        checkWeightedPerfectFractionalMatching(graph, weight, mwpfm, true);
483 506
      }
484 507
    }
485 508

	
486 509
    {
487 510
      MaxWeightedPerfectFractionalMatching<SmartGraph> mwpfm(graph, weight,
488 511
                                                             false);
489 512
      bool perfect = mwpfm.run();
490 513
      check(perfect == (mwpfm.matchingSize() == countNodes(graph)),
491 514
            "Perfect matching found");
492 515
      check(perfect == perfect_without_loops, "Wrong perfect matching");
493 516

	
494 517
      if (perfect) {
495 518
        checkWeightedPerfectFractionalMatching(graph, weight, mwpfm, false);
496 519
      }
497 520
    }
498 521

	
499 522
  }
500 523

	
501 524
  return 0;
502 525
}
0 comments (0 inline)