gravatar
kpeter (Peter Kovacs)
kpeter@inf.elte.hu
Less map copying in NetworkSimplex (#234) - The graph is copied in the constructor instead of the init() function. It must not be modified after the class is constructed. - The maps are copied once (instead of twice). - Remove FlowMap, PotentialMap typedefs and flowMap(), pontentialMap() setter functions. - flowMap() and potentialMap() query functions copy the values into the given map (reference) instead of returning a const reference to a previously constructed map.
0 2 0
default
2 files changed with 184 insertions and 318 deletions:
↑ Collapse diff ↑
Ignore white space 64 line context
... ...
@@ -43,79 +43,68 @@
43 43
  /// for finding a \ref min_cost_flow "minimum cost flow".
44 44
  /// This algorithm is a specialized version of the linear programming
45 45
  /// simplex method directly for the minimum cost flow problem.
46 46
  /// It is one of the most efficient solution methods.
47 47
  ///
48 48
  /// In general this class is the fastest implementation available
49 49
  /// in LEMON for the minimum cost flow problem.
50 50
  /// Moreover it supports both directions of the supply/demand inequality
51 51
  /// constraints. For more information see \ref SupplyType.
52 52
  ///
53 53
  /// Most of the parameters of the problem (except for the digraph)
54 54
  /// can be given using separate functions, and the algorithm can be
55 55
  /// executed using the \ref run() function. If some parameters are not
56 56
  /// specified, then default values will be used.
57 57
  ///
58 58
  /// \tparam GR The digraph type the algorithm runs on.
59 59
  /// \tparam V The value type used for flow amounts, capacity bounds
60 60
  /// and supply values in the algorithm. By default it is \c int.
61 61
  /// \tparam C The value type used for costs and potentials in the
62 62
  /// algorithm. By default it is the same as \c V.
63 63
  ///
64 64
  /// \warning Both value types must be signed and all input data must
65 65
  /// be integer.
66 66
  ///
67 67
  /// \note %NetworkSimplex provides five different pivot rule
68 68
  /// implementations, from which the most efficient one is used
69 69
  /// by default. For more information see \ref PivotRule.
70 70
  template <typename GR, typename V = int, typename C = V>
71 71
  class NetworkSimplex
72 72
  {
73 73
  public:
74 74

	
75
    /// The flow type of the algorithm
75
    /// The type of the flow amounts, capacity bounds and supply values
76 76
    typedef V Value;
77
    /// The cost type of the algorithm
77
    /// The type of the arc costs
78 78
    typedef C Cost;
79
#ifdef DOXYGEN
80
    /// The type of the flow map
81
    typedef GR::ArcMap<Value> FlowMap;
82
    /// The type of the potential map
83
    typedef GR::NodeMap<Cost> PotentialMap;
84
#else
85
    /// The type of the flow map
86
    typedef typename GR::template ArcMap<Value> FlowMap;
87
    /// The type of the potential map
88
    typedef typename GR::template NodeMap<Cost> PotentialMap;
89
#endif
90 79

	
91 80
  public:
92 81

	
93 82
    /// \brief Problem type constants for the \c run() function.
94 83
    ///
95 84
    /// Enum type containing the problem type constants that can be
96 85
    /// returned by the \ref run() function of the algorithm.
97 86
    enum ProblemType {
98 87
      /// The problem has no feasible solution (flow).
99 88
      INFEASIBLE,
100 89
      /// The problem has optimal solution (i.e. it is feasible and
101 90
      /// bounded), and the algorithm has found optimal flow and node
102 91
      /// potentials (primal and dual solutions).
103 92
      OPTIMAL,
104 93
      /// The objective function of the problem is unbounded, i.e.
105 94
      /// there is a directed cycle having negative total cost and
106 95
      /// infinite upper bound.
107 96
      UNBOUNDED
108 97
    };
109 98
    
110 99
    /// \brief Constants for selecting the type of the supply constraints.
111 100
    ///
112 101
    /// Enum type containing constants for selecting the supply type,
113 102
    /// i.e. the direction of the inequalities in the supply/demand
114 103
    /// constraints of the \ref min_cost_flow "minimum cost flow problem".
115 104
    ///
116 105
    /// The default supply type is \c GEQ, since this form is supported
117 106
    /// by other minimum cost flow algorithms and the \ref Circulation
118 107
    /// algorithm, as well.
119 108
    /// The \c LEQ problem type can be selected using the \ref supplyType()
120 109
    /// function.
121 110
    ///
... ...
@@ -177,118 +166,103 @@
177 166
      /// The First Eligible pivot rule.
178 167
      /// The next eligible arc is selected in a wraparound fashion
179 168
      /// in every iteration.
180 169
      FIRST_ELIGIBLE,
181 170

	
182 171
      /// The Best Eligible pivot rule.
183 172
      /// The best eligible arc is selected in every iteration.
184 173
      BEST_ELIGIBLE,
185 174

	
186 175
      /// The Block Search pivot rule.
187 176
      /// A specified number of arcs are examined in every iteration
188 177
      /// in a wraparound fashion and the best eligible arc is selected
189 178
      /// from this block.
190 179
      BLOCK_SEARCH,
191 180

	
192 181
      /// The Candidate List pivot rule.
193 182
      /// In a major iteration a candidate list is built from eligible arcs
194 183
      /// in a wraparound fashion and in the following minor iterations
195 184
      /// the best eligible arc is selected from this list.
196 185
      CANDIDATE_LIST,
197 186

	
198 187
      /// The Altering Candidate List pivot rule.
199 188
      /// It is a modified version of the Candidate List method.
200 189
      /// It keeps only the several best eligible arcs from the former
201 190
      /// candidate list and extends this list in every iteration.
202 191
      ALTERING_LIST
203 192
    };
204 193
    
205 194
  private:
206 195

	
207 196
    TEMPLATE_DIGRAPH_TYPEDEFS(GR);
208 197

	
209
    typedef typename GR::template ArcMap<Value> ValueArcMap;
210
    typedef typename GR::template ArcMap<Cost> CostArcMap;
211
    typedef typename GR::template NodeMap<Value> ValueNodeMap;
212

	
213 198
    typedef std::vector<Arc> ArcVector;
214 199
    typedef std::vector<Node> NodeVector;
215 200
    typedef std::vector<int> IntVector;
216 201
    typedef std::vector<bool> BoolVector;
217
    typedef std::vector<Value> FlowVector;
202
    typedef std::vector<Value> ValueVector;
218 203
    typedef std::vector<Cost> CostVector;
219 204

	
220 205
    // State constants for arcs
221 206
    enum ArcStateEnum {
222 207
      STATE_UPPER = -1,
223 208
      STATE_TREE  =  0,
224 209
      STATE_LOWER =  1
225 210
    };
226 211

	
227 212
  private:
228 213

	
229 214
    // Data related to the underlying digraph
230 215
    const GR &_graph;
231 216
    int _node_num;
232 217
    int _arc_num;
233 218

	
234 219
    // Parameters of the problem
235
    ValueArcMap *_plower;
236
    ValueArcMap *_pupper;
237
    CostArcMap *_pcost;
238
    ValueNodeMap *_psupply;
239
    bool _pstsup;
240
    Node _psource, _ptarget;
241
    Value _pstflow;
220
    bool _have_lower;
242 221
    SupplyType _stype;
243
    
244 222
    Value _sum_supply;
245 223

	
246
    // Result maps
247
    FlowMap *_flow_map;
248
    PotentialMap *_potential_map;
249
    bool _local_flow;
250
    bool _local_potential;
251

	
252 224
    // Data structures for storing the digraph
253 225
    IntNodeMap _node_id;
254
    ArcVector _arc_ref;
226
    IntArcMap _arc_id;
255 227
    IntVector _source;
256 228
    IntVector _target;
257 229

	
258 230
    // Node and arc data
259
    FlowVector _cap;
231
    ValueVector _lower;
232
    ValueVector _upper;
233
    ValueVector _cap;
260 234
    CostVector _cost;
261
    FlowVector _supply;
262
    FlowVector _flow;
235
    ValueVector _supply;
236
    ValueVector _flow;
263 237
    CostVector _pi;
264 238

	
265 239
    // Data for storing the spanning tree structure
266 240
    IntVector _parent;
267 241
    IntVector _pred;
268 242
    IntVector _thread;
269 243
    IntVector _rev_thread;
270 244
    IntVector _succ_num;
271 245
    IntVector _last_succ;
272 246
    IntVector _dirty_revs;
273 247
    BoolVector _forward;
274 248
    IntVector _state;
275 249
    int _root;
276 250

	
277 251
    // Temporary data used in the current pivot iteration
278 252
    int in_arc, join, u_in, v_in, u_out, v_out;
279 253
    int first, second, right, last;
280 254
    int stem, par_stem, new_stem;
281 255
    Value delta;
282 256

	
283 257
  public:
284 258
  
285 259
    /// \brief Constant for infinite upper bounds (capacities).
286 260
    ///
287 261
    /// Constant for infinite upper bounds (capacities).
288 262
    /// It is \c std::numeric_limits<Value>::infinity() if available,
289 263
    /// \c std::numeric_limits<Value>::max() otherwise.
290 264
    const Value INF;
291 265

	
292 266
  private:
293 267

	
294 268
    // Implementation of the First Eligible pivot rule
... ...
@@ -660,605 +634,504 @@
660 634
            if (--cnt == 0) {
661 635
              if (_curr_length > limit) break;
662 636
              limit = 0;
663 637
              cnt = _block_size;
664 638
            }
665 639
          }
666 640
        }
667 641
        if (_curr_length == 0) return false;
668 642
        _next_arc = last_arc + 1;
669 643

	
670 644
        // Make heap of the candidate list (approximating a partial sort)
671 645
        make_heap( _candidates.begin(), _candidates.begin() + _curr_length,
672 646
                   _sort_func );
673 647

	
674 648
        // Pop the first element of the heap
675 649
        _in_arc = _candidates[0];
676 650
        pop_heap( _candidates.begin(), _candidates.begin() + _curr_length,
677 651
                  _sort_func );
678 652
        _curr_length = std::min(_head_length, _curr_length - 1);
679 653
        return true;
680 654
      }
681 655

	
682 656
    }; //class AlteringListPivotRule
683 657

	
684 658
  public:
685 659

	
686 660
    /// \brief Constructor.
687 661
    ///
688 662
    /// The constructor of the class.
689 663
    ///
690 664
    /// \param graph The digraph the algorithm runs on.
691 665
    NetworkSimplex(const GR& graph) :
692
      _graph(graph),
693
      _plower(NULL), _pupper(NULL), _pcost(NULL),
694
      _psupply(NULL), _pstsup(false), _stype(GEQ),
695
      _flow_map(NULL), _potential_map(NULL),
696
      _local_flow(false), _local_potential(false),
697
      _node_id(graph),
666
      _graph(graph), _node_id(graph), _arc_id(graph),
698 667
      INF(std::numeric_limits<Value>::has_infinity ?
699 668
          std::numeric_limits<Value>::infinity() :
700 669
          std::numeric_limits<Value>::max())
701 670
    {
702 671
      // Check the value types
703 672
      LEMON_ASSERT(std::numeric_limits<Value>::is_signed,
704 673
        "The flow type of NetworkSimplex must be signed");
705 674
      LEMON_ASSERT(std::numeric_limits<Cost>::is_signed,
706 675
        "The cost type of NetworkSimplex must be signed");
707
    }
676
        
677
      // Resize vectors
678
      _node_num = countNodes(_graph);
679
      _arc_num = countArcs(_graph);
680
      int all_node_num = _node_num + 1;
681
      int all_arc_num = _arc_num + _node_num;
708 682

	
709
    /// Destructor.
710
    ~NetworkSimplex() {
711
      if (_local_flow) delete _flow_map;
712
      if (_local_potential) delete _potential_map;
683
      _source.resize(all_arc_num);
684
      _target.resize(all_arc_num);
685

	
686
      _lower.resize(all_arc_num);
687
      _upper.resize(all_arc_num);
688
      _cap.resize(all_arc_num);
689
      _cost.resize(all_arc_num);
690
      _supply.resize(all_node_num);
691
      _flow.resize(all_arc_num);
692
      _pi.resize(all_node_num);
693

	
694
      _parent.resize(all_node_num);
695
      _pred.resize(all_node_num);
696
      _forward.resize(all_node_num);
697
      _thread.resize(all_node_num);
698
      _rev_thread.resize(all_node_num);
699
      _succ_num.resize(all_node_num);
700
      _last_succ.resize(all_node_num);
701
      _state.resize(all_arc_num);
702

	
703
      // Copy the graph (store the arcs in a mixed order)
704
      int i = 0;
705
      for (NodeIt n(_graph); n != INVALID; ++n, ++i) {
706
        _node_id[n] = i;
707
      }
708
      int k = std::max(int(std::sqrt(double(_arc_num))), 10);
709
      i = 0;
710
      for (ArcIt a(_graph); a != INVALID; ++a) {
711
        _arc_id[a] = i;
712
        _source[i] = _node_id[_graph.source(a)];
713
        _target[i] = _node_id[_graph.target(a)];
714
        if ((i += k) >= _arc_num) i = (i % k) + 1;
715
      }
716
      
717
      // Initialize maps
718
      for (int i = 0; i != _node_num; ++i) {
719
        _supply[i] = 0;
720
      }
721
      for (int i = 0; i != _arc_num; ++i) {
722
        _lower[i] = 0;
723
        _upper[i] = INF;
724
        _cost[i] = 1;
725
      }
726
      _have_lower = false;
727
      _stype = GEQ;
713 728
    }
714 729

	
715 730
    /// \name Parameters
716 731
    /// The parameters of the algorithm can be specified using these
717 732
    /// functions.
718 733

	
719 734
    /// @{
720 735

	
721 736
    /// \brief Set the lower bounds on the arcs.
722 737
    ///
723 738
    /// This function sets the lower bounds on the arcs.
724 739
    /// If it is not used before calling \ref run(), the lower bounds
725 740
    /// will be set to zero on all arcs.
726 741
    ///
727 742
    /// \param map An arc map storing the lower bounds.
728 743
    /// Its \c Value type must be convertible to the \c Value type
729 744
    /// of the algorithm.
730 745
    ///
731 746
    /// \return <tt>(*this)</tt>
732 747
    template <typename LowerMap>
733 748
    NetworkSimplex& lowerMap(const LowerMap& map) {
734
      delete _plower;
735
      _plower = new ValueArcMap(_graph);
749
      _have_lower = true;
736 750
      for (ArcIt a(_graph); a != INVALID; ++a) {
737
        (*_plower)[a] = map[a];
751
        _lower[_arc_id[a]] = map[a];
738 752
      }
739 753
      return *this;
740 754
    }
741 755

	
742 756
    /// \brief Set the upper bounds (capacities) on the arcs.
743 757
    ///
744 758
    /// This function sets the upper bounds (capacities) on the arcs.
745 759
    /// If it is not used before calling \ref run(), the upper bounds
746 760
    /// will be set to \ref INF on all arcs (i.e. the flow value will be
747 761
    /// unbounded from above on each arc).
748 762
    ///
749 763
    /// \param map An arc map storing the upper bounds.
750 764
    /// Its \c Value type must be convertible to the \c Value type
751 765
    /// of the algorithm.
752 766
    ///
753 767
    /// \return <tt>(*this)</tt>
754 768
    template<typename UpperMap>
755 769
    NetworkSimplex& upperMap(const UpperMap& map) {
756
      delete _pupper;
757
      _pupper = new ValueArcMap(_graph);
758 770
      for (ArcIt a(_graph); a != INVALID; ++a) {
759
        (*_pupper)[a] = map[a];
771
        _upper[_arc_id[a]] = map[a];
760 772
      }
761 773
      return *this;
762 774
    }
763 775

	
764 776
    /// \brief Set the costs of the arcs.
765 777
    ///
766 778
    /// This function sets the costs of the arcs.
767 779
    /// If it is not used before calling \ref run(), the costs
768 780
    /// will be set to \c 1 on all arcs.
769 781
    ///
770 782
    /// \param map An arc map storing the costs.
771 783
    /// Its \c Value type must be convertible to the \c Cost type
772 784
    /// of the algorithm.
773 785
    ///
774 786
    /// \return <tt>(*this)</tt>
775 787
    template<typename CostMap>
776 788
    NetworkSimplex& costMap(const CostMap& map) {
777
      delete _pcost;
778
      _pcost = new CostArcMap(_graph);
779 789
      for (ArcIt a(_graph); a != INVALID; ++a) {
780
        (*_pcost)[a] = map[a];
790
        _cost[_arc_id[a]] = map[a];
781 791
      }
782 792
      return *this;
783 793
    }
784 794

	
785 795
    /// \brief Set the supply values of the nodes.
786 796
    ///
787 797
    /// This function sets the supply values of the nodes.
788 798
    /// If neither this function nor \ref stSupply() is used before
789 799
    /// calling \ref run(), the supply of each node will be set to zero.
790 800
    /// (It makes sense only if non-zero lower bounds are given.)
791 801
    ///
792 802
    /// \param map A node map storing the supply values.
793 803
    /// Its \c Value type must be convertible to the \c Value type
794 804
    /// of the algorithm.
795 805
    ///
796 806
    /// \return <tt>(*this)</tt>
797 807
    template<typename SupplyMap>
798 808
    NetworkSimplex& supplyMap(const SupplyMap& map) {
799
      delete _psupply;
800
      _pstsup = false;
801
      _psupply = new ValueNodeMap(_graph);
802 809
      for (NodeIt n(_graph); n != INVALID; ++n) {
803
        (*_psupply)[n] = map[n];
810
        _supply[_node_id[n]] = map[n];
804 811
      }
805 812
      return *this;
806 813
    }
807 814

	
808 815
    /// \brief Set single source and target nodes and a supply value.
809 816
    ///
810 817
    /// This function sets a single source node and a single target node
811 818
    /// and the required flow value.
812 819
    /// If neither this function nor \ref supplyMap() is used before
813 820
    /// calling \ref run(), the supply of each node will be set to zero.
814 821
    /// (It makes sense only if non-zero lower bounds are given.)
815 822
    ///
816 823
    /// Using this function has the same effect as using \ref supplyMap()
817 824
    /// with such a map in which \c k is assigned to \c s, \c -k is
818 825
    /// assigned to \c t and all other nodes have zero supply value.
819 826
    ///
820 827
    /// \param s The source node.
821 828
    /// \param t The target node.
822 829
    /// \param k The required amount of flow from node \c s to node \c t
823 830
    /// (i.e. the supply of \c s and the demand of \c t).
824 831
    ///
825 832
    /// \return <tt>(*this)</tt>
826 833
    NetworkSimplex& stSupply(const Node& s, const Node& t, Value k) {
827
      delete _psupply;
828
      _psupply = NULL;
829
      _pstsup = true;
830
      _psource = s;
831
      _ptarget = t;
832
      _pstflow = k;
834
      for (int i = 0; i != _node_num; ++i) {
835
        _supply[i] = 0;
836
      }
837
      _supply[_node_id[s]] =  k;
838
      _supply[_node_id[t]] = -k;
833 839
      return *this;
834 840
    }
835 841
    
836 842
    /// \brief Set the type of the supply constraints.
837 843
    ///
838 844
    /// This function sets the type of the supply/demand constraints.
839 845
    /// If it is not used before calling \ref run(), the \ref GEQ supply
840 846
    /// type will be used.
841 847
    ///
842 848
    /// For more information see \ref SupplyType.
843 849
    ///
844 850
    /// \return <tt>(*this)</tt>
845 851
    NetworkSimplex& supplyType(SupplyType supply_type) {
846 852
      _stype = supply_type;
847 853
      return *this;
848 854
    }
849 855

	
850
    /// \brief Set the flow map.
851
    ///
852
    /// This function sets the flow map.
853
    /// If it is not used before calling \ref run(), an instance will
854
    /// be allocated automatically. The destructor deallocates this
855
    /// automatically allocated map, of course.
856
    ///
857
    /// \return <tt>(*this)</tt>
858
    NetworkSimplex& flowMap(FlowMap& map) {
859
      if (_local_flow) {
860
        delete _flow_map;
861
        _local_flow = false;
862
      }
863
      _flow_map = &map;
864
      return *this;
865
    }
866

	
867
    /// \brief Set the potential map.
868
    ///
869
    /// This function sets the potential map, which is used for storing
870
    /// the dual solution.
871
    /// If it is not used before calling \ref run(), an instance will
872
    /// be allocated automatically. The destructor deallocates this
873
    /// automatically allocated map, of course.
874
    ///
875
    /// \return <tt>(*this)</tt>
876
    NetworkSimplex& potentialMap(PotentialMap& map) {
877
      if (_local_potential) {
878
        delete _potential_map;
879
        _local_potential = false;
880
      }
881
      _potential_map = &map;
882
      return *this;
883
    }
884
    
885 856
    /// @}
886 857

	
887 858
    /// \name Execution Control
888 859
    /// The algorithm can be executed using \ref run().
889 860

	
890 861
    /// @{
891 862

	
892 863
    /// \brief Run the algorithm.
893 864
    ///
894 865
    /// This function runs the algorithm.
895 866
    /// The paramters can be specified using functions \ref lowerMap(),
896 867
    /// \ref upperMap(), \ref costMap(), \ref supplyMap(), \ref stSupply(), 
897
    /// \ref supplyType(), \ref flowMap() and \ref potentialMap().
868
    /// \ref supplyType().
898 869
    /// For example,
899 870
    /// \code
900 871
    ///   NetworkSimplex<ListDigraph> ns(graph);
901 872
    ///   ns.lowerMap(lower).upperMap(upper).costMap(cost)
902 873
    ///     .supplyMap(sup).run();
903 874
    /// \endcode
904 875
    ///
905 876
    /// This function can be called more than once. All the parameters
906 877
    /// that have been given are kept for the next call, unless
907 878
    /// \ref reset() is called, thus only the modified parameters
908 879
    /// have to be set again. See \ref reset() for examples.
880
    /// However the underlying digraph must not be modified after this
881
    /// class have been constructed, since it copies and extends the graph.
909 882
    ///
910 883
    /// \param pivot_rule The pivot rule that will be used during the
911 884
    /// algorithm. For more information see \ref PivotRule.
912 885
    ///
913 886
    /// \return \c INFEASIBLE if no feasible flow exists,
914 887
    /// \n \c OPTIMAL if the problem has optimal solution
915 888
    /// (i.e. it is feasible and bounded), and the algorithm has found
916 889
    /// optimal flow and node potentials (primal and dual solutions),
917 890
    /// \n \c UNBOUNDED if the objective function of the problem is
918 891
    /// unbounded, i.e. there is a directed cycle having negative total
919 892
    /// cost and infinite upper bound.
920 893
    ///
921 894
    /// \see ProblemType, PivotRule
922 895
    ProblemType run(PivotRule pivot_rule = BLOCK_SEARCH) {
923 896
      if (!init()) return INFEASIBLE;
924 897
      return start(pivot_rule);
925 898
    }
926 899

	
927 900
    /// \brief Reset all the parameters that have been given before.
928 901
    ///
929 902
    /// This function resets all the paramaters that have been given
930 903
    /// before using functions \ref lowerMap(), \ref upperMap(),
931
    /// \ref costMap(), \ref supplyMap(), \ref stSupply(), \ref supplyType(),
932
    /// \ref flowMap() and \ref potentialMap().
904
    /// \ref costMap(), \ref supplyMap(), \ref stSupply(), \ref supplyType().
933 905
    ///
934 906
    /// It is useful for multiple run() calls. If this function is not
935 907
    /// used, all the parameters given before are kept for the next
936 908
    /// \ref run() call.
909
    /// However the underlying digraph must not be modified after this
910
    /// class have been constructed, since it copies and extends the graph.
937 911
    ///
938 912
    /// For example,
939 913
    /// \code
940 914
    ///   NetworkSimplex<ListDigraph> ns(graph);
941 915
    ///
942 916
    ///   // First run
943 917
    ///   ns.lowerMap(lower).upperMap(upper).costMap(cost)
944 918
    ///     .supplyMap(sup).run();
945 919
    ///
946 920
    ///   // Run again with modified cost map (reset() is not called,
947 921
    ///   // so only the cost map have to be set again)
948 922
    ///   cost[e] += 100;
949 923
    ///   ns.costMap(cost).run();
950 924
    ///
951 925
    ///   // Run again from scratch using reset()
952 926
    ///   // (the lower bounds will be set to zero on all arcs)
953 927
    ///   ns.reset();
954 928
    ///   ns.upperMap(capacity).costMap(cost)
955 929
    ///     .supplyMap(sup).run();
956 930
    /// \endcode
957 931
    ///
958 932
    /// \return <tt>(*this)</tt>
959 933
    NetworkSimplex& reset() {
960
      delete _plower;
961
      delete _pupper;
962
      delete _pcost;
963
      delete _psupply;
964
      _plower = NULL;
965
      _pupper = NULL;
966
      _pcost = NULL;
967
      _psupply = NULL;
968
      _pstsup = false;
934
      for (int i = 0; i != _node_num; ++i) {
935
        _supply[i] = 0;
936
      }
937
      for (int i = 0; i != _arc_num; ++i) {
938
        _lower[i] = 0;
939
        _upper[i] = INF;
940
        _cost[i] = 1;
941
      }
942
      _have_lower = false;
969 943
      _stype = GEQ;
970
      if (_local_flow) delete _flow_map;
971
      if (_local_potential) delete _potential_map;
972
      _flow_map = NULL;
973
      _potential_map = NULL;
974
      _local_flow = false;
975
      _local_potential = false;
976

	
977 944
      return *this;
978 945
    }
979 946

	
980 947
    /// @}
981 948

	
982 949
    /// \name Query Functions
983 950
    /// The results of the algorithm can be obtained using these
984 951
    /// functions.\n
985 952
    /// The \ref run() function must be called before using them.
986 953

	
987 954
    /// @{
988 955

	
989 956
    /// \brief Return the total cost of the found flow.
990 957
    ///
991 958
    /// This function returns the total cost of the found flow.
992 959
    /// Its complexity is O(e).
993 960
    ///
994 961
    /// \note The return type of the function can be specified as a
995 962
    /// template parameter. For example,
996 963
    /// \code
997 964
    ///   ns.totalCost<double>();
998 965
    /// \endcode
999 966
    /// It is useful if the total cost cannot be stored in the \c Cost
1000 967
    /// type of the algorithm, which is the default return type of the
1001 968
    /// function.
1002 969
    ///
1003 970
    /// \pre \ref run() must be called before using this function.
1004
    template <typename Value>
1005
    Value totalCost() const {
1006
      Value c = 0;
1007
      if (_pcost) {
1008
        for (ArcIt e(_graph); e != INVALID; ++e)
1009
          c += (*_flow_map)[e] * (*_pcost)[e];
1010
      } else {
1011
        for (ArcIt e(_graph); e != INVALID; ++e)
1012
          c += (*_flow_map)[e];
971
    template <typename Number>
972
    Number totalCost() const {
973
      Number c = 0;
974
      for (ArcIt a(_graph); a != INVALID; ++a) {
975
        int i = _arc_id[a];
976
        c += Number(_flow[i]) * Number(_cost[i]);
1013 977
      }
1014 978
      return c;
1015 979
    }
1016 980

	
1017 981
#ifndef DOXYGEN
1018 982
    Cost totalCost() const {
1019 983
      return totalCost<Cost>();
1020 984
    }
1021 985
#endif
1022 986

	
1023 987
    /// \brief Return the flow on the given arc.
1024 988
    ///
1025 989
    /// This function returns the flow on the given arc.
1026 990
    ///
1027 991
    /// \pre \ref run() must be called before using this function.
1028 992
    Value flow(const Arc& a) const {
1029
      return (*_flow_map)[a];
993
      return _flow[_arc_id[a]];
1030 994
    }
1031 995

	
1032
    /// \brief Return a const reference to the flow map.
996
    /// \brief Return the flow map (the primal solution).
1033 997
    ///
1034
    /// This function returns a const reference to an arc map storing
1035
    /// the found flow.
998
    /// This function copies the flow value on each arc into the given
999
    /// map. The \c Value type of the algorithm must be convertible to
1000
    /// the \c Value type of the map.
1036 1001
    ///
1037 1002
    /// \pre \ref run() must be called before using this function.
1038
    const FlowMap& flowMap() const {
1039
      return *_flow_map;
1003
    template <typename FlowMap>
1004
    void flowMap(FlowMap &map) const {
1005
      for (ArcIt a(_graph); a != INVALID; ++a) {
1006
        map.set(a, _flow[_arc_id[a]]);
1007
      }
1040 1008
    }
1041 1009

	
1042 1010
    /// \brief Return the potential (dual value) of the given node.
1043 1011
    ///
1044 1012
    /// This function returns the potential (dual value) of the
1045 1013
    /// given node.
1046 1014
    ///
1047 1015
    /// \pre \ref run() must be called before using this function.
1048 1016
    Cost potential(const Node& n) const {
1049
      return (*_potential_map)[n];
1017
      return _pi[_node_id[n]];
1050 1018
    }
1051 1019

	
1052
    /// \brief Return a const reference to the potential map
1053
    /// (the dual solution).
1020
    /// \brief Return the potential map (the dual solution).
1054 1021
    ///
1055
    /// This function returns a const reference to a node map storing
1056
    /// the found potentials, which form the dual solution of the
1057
    /// \ref min_cost_flow "minimum cost flow problem".
1022
    /// This function copies the potential (dual value) of each node
1023
    /// into the given map.
1024
    /// The \c Cost type of the algorithm must be convertible to the
1025
    /// \c Value type of the map.
1058 1026
    ///
1059 1027
    /// \pre \ref run() must be called before using this function.
1060
    const PotentialMap& potentialMap() const {
1061
      return *_potential_map;
1028
    template <typename PotentialMap>
1029
    void potentialMap(PotentialMap &map) const {
1030
      for (NodeIt n(_graph); n != INVALID; ++n) {
1031
        map.set(n, _pi[_node_id[n]]);
1032
      }
1062 1033
    }
1063 1034

	
1064 1035
    /// @}
1065 1036

	
1066 1037
  private:
1067 1038

	
1068 1039
    // Initialize internal data structures
1069 1040
    bool init() {
1070
      // Initialize result maps
1071
      if (!_flow_map) {
1072
        _flow_map = new FlowMap(_graph);
1073
        _local_flow = true;
1074
      }
1075
      if (!_potential_map) {
1076
        _potential_map = new PotentialMap(_graph);
1077
        _local_potential = true;
1078
      }
1079

	
1080
      // Initialize vectors
1081
      _node_num = countNodes(_graph);
1082
      _arc_num = countArcs(_graph);
1083
      int all_node_num = _node_num + 1;
1084
      int all_arc_num = _arc_num + _node_num;
1085 1041
      if (_node_num == 0) return false;
1086 1042

	
1087
      _arc_ref.resize(_arc_num);
1088
      _source.resize(all_arc_num);
1089
      _target.resize(all_arc_num);
1043
      // Check the sum of supply values
1044
      _sum_supply = 0;
1045
      for (int i = 0; i != _node_num; ++i) {
1046
        _sum_supply += _supply[i];
1047
      }
1048
      if ( !(_stype == GEQ && _sum_supply <= 0 ||
1049
             _stype == LEQ && _sum_supply >= 0) ) return false;
1090 1050

	
1091
      _cap.resize(all_arc_num);
1092
      _cost.resize(all_arc_num);
1093
      _supply.resize(all_node_num);
1094
      _flow.resize(all_arc_num);
1095
      _pi.resize(all_node_num);
1096

	
1097
      _parent.resize(all_node_num);
1098
      _pred.resize(all_node_num);
1099
      _forward.resize(all_node_num);
1100
      _thread.resize(all_node_num);
1101
      _rev_thread.resize(all_node_num);
1102
      _succ_num.resize(all_node_num);
1103
      _last_succ.resize(all_node_num);
1104
      _state.resize(all_arc_num);
1105

	
1106
      // Initialize node related data
1107
      bool valid_supply = true;
1108
      _sum_supply = 0;
1109
      if (!_pstsup && !_psupply) {
1110
        _pstsup = true;
1111
        _psource = _ptarget = NodeIt(_graph);
1112
        _pstflow = 0;
1051
      // Remove non-zero lower bounds
1052
      if (_have_lower) {
1053
        for (int i = 0; i != _arc_num; ++i) {
1054
          Value c = _lower[i];
1055
          if (c >= 0) {
1056
            _cap[i] = _upper[i] < INF ? _upper[i] - c : INF;
1057
          } else {
1058
            _cap[i] = _upper[i] < INF + c ? _upper[i] - c : INF;
1059
          }
1060
          _supply[_source[i]] -= c;
1061
          _supply[_target[i]] += c;
1062
        }
1063
      } else {
1064
        for (int i = 0; i != _arc_num; ++i) {
1065
          _cap[i] = _upper[i];
1066
        }
1113 1067
      }
1114
      if (_psupply) {
1115
        int i = 0;
1116
        for (NodeIt n(_graph); n != INVALID; ++n, ++i) {
1117
          _node_id[n] = i;
1118
          _supply[i] = (*_psupply)[n];
1119
          _sum_supply += _supply[i];
1120
        }
1121
        valid_supply = (_stype == GEQ && _sum_supply <= 0) ||
1122
                       (_stype == LEQ && _sum_supply >= 0);
1123
      } else {
1124
        int i = 0;
1125
        for (NodeIt n(_graph); n != INVALID; ++n, ++i) {
1126
          _node_id[n] = i;
1127
          _supply[i] = 0;
1128
        }
1129
        _supply[_node_id[_psource]] =  _pstflow;
1130
        _supply[_node_id[_ptarget]] = -_pstflow;
1131
      }
1132
      if (!valid_supply) return false;
1133 1068

	
1134 1069
      // Initialize artifical cost
1135 1070
      Cost ART_COST;
1136 1071
      if (std::numeric_limits<Cost>::is_exact) {
1137 1072
        ART_COST = std::numeric_limits<Cost>::max() / 4 + 1;
1138 1073
      } else {
1139 1074
        ART_COST = std::numeric_limits<Cost>::min();
1140 1075
        for (int i = 0; i != _arc_num; ++i) {
1141 1076
          if (_cost[i] > ART_COST) ART_COST = _cost[i];
1142 1077
        }
1143 1078
        ART_COST = (ART_COST + 1) * _node_num;
1144 1079
      }
1145 1080

	
1081
      // Initialize arc maps
1082
      for (int i = 0; i != _arc_num; ++i) {
1083
        _flow[i] = 0;
1084
        _state[i] = STATE_LOWER;
1085
      }
1086
      
1146 1087
      // Set data for the artificial root node
1147 1088
      _root = _node_num;
1148 1089
      _parent[_root] = -1;
1149 1090
      _pred[_root] = -1;
1150 1091
      _thread[_root] = 0;
1151 1092
      _rev_thread[0] = _root;
1152
      _succ_num[_root] = all_node_num;
1093
      _succ_num[_root] = _node_num + 1;
1153 1094
      _last_succ[_root] = _root - 1;
1154 1095
      _supply[_root] = -_sum_supply;
1155
      if (_sum_supply < 0) {
1156
        _pi[_root] = -ART_COST;
1157
      } else {
1158
        _pi[_root] = ART_COST;
1159
      }
1160

	
1161
      // Store the arcs in a mixed order
1162
      int k = std::max(int(std::sqrt(double(_arc_num))), 10);
1163
      int i = 0;
1164
      for (ArcIt e(_graph); e != INVALID; ++e) {
1165
        _arc_ref[i] = e;
1166
        if ((i += k) >= _arc_num) i = (i % k) + 1;
1167
      }
1168

	
1169
      // Initialize arc maps
1170
      if (_pupper && _pcost) {
1171
        for (int i = 0; i != _arc_num; ++i) {
1172
          Arc e = _arc_ref[i];
1173
          _source[i] = _node_id[_graph.source(e)];
1174
          _target[i] = _node_id[_graph.target(e)];
1175
          _cap[i] = (*_pupper)[e];
1176
          _cost[i] = (*_pcost)[e];
1177
          _flow[i] = 0;
1178
          _state[i] = STATE_LOWER;
1179
        }
1180
      } else {
1181
        for (int i = 0; i != _arc_num; ++i) {
1182
          Arc e = _arc_ref[i];
1183
          _source[i] = _node_id[_graph.source(e)];
1184
          _target[i] = _node_id[_graph.target(e)];
1185
          _flow[i] = 0;
1186
          _state[i] = STATE_LOWER;
1187
        }
1188
        if (_pupper) {
1189
          for (int i = 0; i != _arc_num; ++i)
1190
            _cap[i] = (*_pupper)[_arc_ref[i]];
1191
        } else {
1192
          for (int i = 0; i != _arc_num; ++i)
1193
            _cap[i] = INF;
1194
        }
1195
        if (_pcost) {
1196
          for (int i = 0; i != _arc_num; ++i)
1197
            _cost[i] = (*_pcost)[_arc_ref[i]];
1198
        } else {
1199
          for (int i = 0; i != _arc_num; ++i)
1200
            _cost[i] = 1;
1201
        }
1202
      }
1203
      
1204
      // Remove non-zero lower bounds
1205
      if (_plower) {
1206
        for (int i = 0; i != _arc_num; ++i) {
1207
          Value c = (*_plower)[_arc_ref[i]];
1208
          if (c > 0) {
1209
            if (_cap[i] < INF) _cap[i] -= c;
1210
            _supply[_source[i]] -= c;
1211
            _supply[_target[i]] += c;
1212
          }
1213
          else if (c < 0) {
1214
            if (_cap[i] < INF + c) {
1215
              _cap[i] -= c;
1216
            } else {
1217
              _cap[i] = INF;
1218
            }
1219
            _supply[_source[i]] -= c;
1220
            _supply[_target[i]] += c;
1221
          }
1222
        }
1223
      }
1096
      _pi[_root] = _sum_supply < 0 ? -ART_COST : ART_COST;
1224 1097

	
1225 1098
      // Add artificial arcs and initialize the spanning tree data structure
1226 1099
      for (int u = 0, e = _arc_num; u != _node_num; ++u, ++e) {
1100
        _parent[u] = _root;
1101
        _pred[u] = e;
1227 1102
        _thread[u] = u + 1;
1228 1103
        _rev_thread[u + 1] = u;
1229 1104
        _succ_num[u] = 1;
1230 1105
        _last_succ[u] = u;
1231
        _parent[u] = _root;
1232
        _pred[u] = e;
1233 1106
        _cost[e] = ART_COST;
1234 1107
        _cap[e] = INF;
1235 1108
        _state[e] = STATE_TREE;
1236 1109
        if (_supply[u] > 0 || (_supply[u] == 0 && _sum_supply <= 0)) {
1237 1110
          _flow[e] = _supply[u];
1238 1111
          _forward[u] = true;
1239 1112
          _pi[u] = -ART_COST + _pi[_root];
1240 1113
        } else {
1241 1114
          _flow[e] = -_supply[u];
1242 1115
          _forward[u] = false;
1243 1116
          _pi[u] = ART_COST + _pi[_root];
1244 1117
        }
1245 1118
      }
1246 1119

	
1247 1120
      return true;
1248 1121
    }
1249 1122

	
1250 1123
    // Find the join node
1251 1124
    void findJoinNode() {
1252 1125
      int u = _source[in_arc];
1253 1126
      int v = _target[in_arc];
1254 1127
      while (u != v) {
1255 1128
        if (_succ_num[u] < _succ_num[v]) {
1256 1129
          u = _parent[u];
1257 1130
        } else {
1258 1131
          v = _parent[v];
1259 1132
        }
1260 1133
      }
1261 1134
      join = u;
1262 1135
    }
1263 1136

	
1264 1137
    // Find the leaving arc of the cycle and returns true if the
... ...
@@ -1488,58 +1361,54 @@
1488 1361
    ProblemType start() {
1489 1362
      PivotRuleImpl pivot(*this);
1490 1363

	
1491 1364
      // Execute the Network Simplex algorithm
1492 1365
      while (pivot.findEnteringArc()) {
1493 1366
        findJoinNode();
1494 1367
        bool change = findLeavingArc();
1495 1368
        if (delta >= INF) return UNBOUNDED;
1496 1369
        changeFlow(change);
1497 1370
        if (change) {
1498 1371
          updateTreeStructure();
1499 1372
          updatePotential();
1500 1373
        }
1501 1374
      }
1502 1375
      
1503 1376
      // Check feasibility
1504 1377
      if (_sum_supply < 0) {
1505 1378
        for (int u = 0, e = _arc_num; u != _node_num; ++u, ++e) {
1506 1379
          if (_supply[u] >= 0 && _flow[e] != 0) return INFEASIBLE;
1507 1380
        }
1508 1381
      }
1509 1382
      else if (_sum_supply > 0) {
1510 1383
        for (int u = 0, e = _arc_num; u != _node_num; ++u, ++e) {
1511 1384
          if (_supply[u] <= 0 && _flow[e] != 0) return INFEASIBLE;
1512 1385
        }
1513 1386
      }
1514 1387
      else {
1515 1388
        for (int u = 0, e = _arc_num; u != _node_num; ++u, ++e) {
1516 1389
          if (_flow[e] != 0) return INFEASIBLE;
1517 1390
        }
1518 1391
      }
1519 1392

	
1520
      // Copy flow values to _flow_map
1521
      if (_plower) {
1393
      // Transform the solution and the supply map to the original form
1394
      if (_have_lower) {
1522 1395
        for (int i = 0; i != _arc_num; ++i) {
1523
          Arc e = _arc_ref[i];
1524
          _flow_map->set(e, (*_plower)[e] + _flow[i]);
1396
          Value c = _lower[i];
1397
          if (c != 0) {
1398
            _flow[i] += c;
1399
            _supply[_source[i]] += c;
1400
            _supply[_target[i]] -= c;
1401
          }
1525 1402
        }
1526
      } else {
1527
        for (int i = 0; i != _arc_num; ++i) {
1528
          _flow_map->set(_arc_ref[i], _flow[i]);
1529
        }
1530
      }
1531
      // Copy potential values to _potential_map
1532
      for (NodeIt n(_graph); n != INVALID; ++n) {
1533
        _potential_map->set(n, _pi[_node_id[n]]);
1534 1403
      }
1535 1404

	
1536 1405
      return OPTIMAL;
1537 1406
    }
1538 1407

	
1539 1408
  }; //class NetworkSimplex
1540 1409

	
1541 1410
  ///@}
1542 1411

	
1543 1412
} //namespace lemon
1544 1413

	
1545 1414
#endif //LEMON_NETWORK_SIMPLEX_H
Ignore white space 64 line context
... ...
@@ -55,123 +55,115 @@
55 55
  " 1  4    80   15    0    2    2\n"
56 56
  " 2  8    80   12    0    0    0\n"
57 57
  " 3  5   140    5    0    3    1\n"
58 58
  " 4  6    60   10    0    1    0\n"
59 59
  " 4  7    80    2    0    0    0\n"
60 60
  " 4  8   110    3    0    0    0\n"
61 61
  " 5  7    60   14    0    0    0\n"
62 62
  " 5 11   120   12    0    0    0\n"
63 63
  " 6  3     0    3    0    0    0\n"
64 64
  " 6  9   140    4    0    0    0\n"
65 65
  " 6 10    90    8    0    0    0\n"
66 66
  " 7  1    30    5    0    0   -5\n"
67 67
  " 8 12    60   16    0    4    3\n"
68 68
  " 9 12    50    6    0    0    0\n"
69 69
  "10 12    70   13    0    5    2\n"
70 70
  "10  2   100    7    0    0    0\n"
71 71
  "10  7    60   10    0    0   -3\n"
72 72
  "11 10    20   14    0    6  -20\n"
73 73
  "12 11    30   10    0    0  -10\n"
74 74
  "\n"
75 75
  "@attributes\n"
76 76
  "source 1\n"
77 77
  "target 12\n";
78 78

	
79 79

	
80 80
enum SupplyType {
81 81
  EQ,
82 82
  GEQ,
83 83
  LEQ
84 84
};
85 85

	
86 86
// Check the interface of an MCF algorithm
87
template <typename GR, typename Flow, typename Cost>
87
template <typename GR, typename Value, typename Cost>
88 88
class McfClassConcept
89 89
{
90 90
public:
91 91

	
92 92
  template <typename MCF>
93 93
  struct Constraints {
94 94
    void constraints() {
95 95
      checkConcept<concepts::Digraph, GR>();
96 96

	
97 97
      MCF mcf(g);
98
      const MCF& const_mcf = mcf;
98 99

	
99 100
      b = mcf.reset()
100 101
             .lowerMap(lower)
101 102
             .upperMap(upper)
102 103
             .costMap(cost)
103 104
             .supplyMap(sup)
104 105
             .stSupply(n, n, k)
105
             .flowMap(flow)
106
             .potentialMap(pot)
107 106
             .run();
108
      
109
      const MCF& const_mcf = mcf;
110

	
111
      const typename MCF::FlowMap &fm = const_mcf.flowMap();
112
      const typename MCF::PotentialMap &pm = const_mcf.potentialMap();
113 107

	
114 108
      c = const_mcf.totalCost();
115
      double x = const_mcf.template totalCost<double>();
109
      x = const_mcf.template totalCost<double>();
116 110
      v = const_mcf.flow(a);
117 111
      c = const_mcf.potential(n);
118
      
119
      v = const_mcf.INF;
120

	
121
      ignore_unused_variable_warning(fm);
122
      ignore_unused_variable_warning(pm);
123
      ignore_unused_variable_warning(x);
112
      const_mcf.flowMap(fm);
113
      const_mcf.potentialMap(pm);
124 114
    }
125 115

	
126 116
    typedef typename GR::Node Node;
127 117
    typedef typename GR::Arc Arc;
128
    typedef concepts::ReadMap<Node, Flow> NM;
129
    typedef concepts::ReadMap<Arc, Flow> FAM;
118
    typedef concepts::ReadMap<Node, Value> NM;
119
    typedef concepts::ReadMap<Arc, Value> VAM;
130 120
    typedef concepts::ReadMap<Arc, Cost> CAM;
121
    typedef concepts::WriteMap<Arc, Value> FlowMap;
122
    typedef concepts::WriteMap<Node, Cost> PotMap;
131 123

	
132 124
    const GR &g;
133
    const FAM &lower;
134
    const FAM &upper;
125
    const VAM &lower;
126
    const VAM &upper;
135 127
    const CAM &cost;
136 128
    const NM &sup;
137 129
    const Node &n;
138 130
    const Arc &a;
139
    const Flow &k;
140
    Flow v;
141
    Cost c;
131
    const Value &k;
132
    FlowMap fm;
133
    PotMap pm;
142 134
    bool b;
143

	
144
    typename MCF::FlowMap &flow;
145
    typename MCF::PotentialMap &pot;
135
    double x;
136
    typename MCF::Value v;
137
    typename MCF::Cost c;
146 138
  };
147 139

	
148 140
};
149 141

	
150 142

	
151 143
// Check the feasibility of the given flow (primal soluiton)
152 144
template < typename GR, typename LM, typename UM,
153 145
           typename SM, typename FM >
154 146
bool checkFlow( const GR& gr, const LM& lower, const UM& upper,
155 147
                const SM& supply, const FM& flow,
156 148
                SupplyType type = EQ )
157 149
{
158 150
  TEMPLATE_DIGRAPH_TYPEDEFS(GR);
159 151

	
160 152
  for (ArcIt e(gr); e != INVALID; ++e) {
161 153
    if (flow[e] < lower[e] || flow[e] > upper[e]) return false;
162 154
  }
163 155

	
164 156
  for (NodeIt n(gr); n != INVALID; ++n) {
165 157
    typename SM::Value sum = 0;
166 158
    for (OutArcIt e(gr, n); e != INVALID; ++e)
167 159
      sum += flow[e];
168 160
    for (InArcIt e(gr, n); e != INVALID; ++e)
169 161
      sum -= flow[e];
170 162
    bool b = (type ==  EQ && sum == supply[n]) ||
171 163
             (type == GEQ && sum >= supply[n]) ||
172 164
             (type == LEQ && sum <= supply[n]);
173 165
    if (!b) return false;
174 166
  }
175 167

	
176 168
  return true;
177 169
}
... ...
@@ -192,82 +184,87 @@
192 184
      cost[e] + pi[gr.source(e)] - pi[gr.target(e)];
193 185
    opt = red_cost == 0 ||
194 186
          (red_cost > 0 && flow[e] == lower[e]) ||
195 187
          (red_cost < 0 && flow[e] == upper[e]);
196 188
  }
197 189
  
198 190
  for (NodeIt n(gr); opt && n != INVALID; ++n) {
199 191
    typename SM::Value sum = 0;
200 192
    for (OutArcIt e(gr, n); e != INVALID; ++e)
201 193
      sum += flow[e];
202 194
    for (InArcIt e(gr, n); e != INVALID; ++e)
203 195
      sum -= flow[e];
204 196
    opt = (sum == supply[n]) || (pi[n] == 0);
205 197
  }
206 198
  
207 199
  return opt;
208 200
}
209 201

	
210 202
// Run a minimum cost flow algorithm and check the results
211 203
template < typename MCF, typename GR,
212 204
           typename LM, typename UM,
213 205
           typename CM, typename SM,
214 206
           typename PT >
215 207
void checkMcf( const MCF& mcf, PT mcf_result,
216 208
               const GR& gr, const LM& lower, const UM& upper,
217 209
               const CM& cost, const SM& supply,
218 210
               PT result, bool optimal, typename CM::Value total,
219 211
               const std::string &test_id = "",
220 212
               SupplyType type = EQ )
221 213
{
222 214
  check(mcf_result == result, "Wrong result " + test_id);
223 215
  if (optimal) {
224
    check(checkFlow(gr, lower, upper, supply, mcf.flowMap(), type),
216
    typename GR::template ArcMap<typename SM::Value> flow(gr);
217
    typename GR::template NodeMap<typename CM::Value> pi(gr);
218
    mcf.flowMap(flow);
219
    mcf.potentialMap(pi);
220
    check(checkFlow(gr, lower, upper, supply, flow, type),
225 221
          "The flow is not feasible " + test_id);
226 222
    check(mcf.totalCost() == total, "The flow is not optimal " + test_id);
227
    check(checkPotential(gr, lower, upper, cost, supply, mcf.flowMap(),
228
                         mcf.potentialMap()),
223
    check(checkPotential(gr, lower, upper, cost, supply, flow, pi),
229 224
          "Wrong potentials " + test_id);
230 225
  }
231 226
}
232 227

	
233 228
int main()
234 229
{
235 230
  // Check the interfaces
236 231
  {
237
    typedef int Flow;
238
    typedef int Cost;
239 232
    typedef concepts::Digraph GR;
240
    checkConcept< McfClassConcept<GR, Flow, Cost>,
241
                  NetworkSimplex<GR, Flow, Cost> >();
233
    checkConcept< McfClassConcept<GR, int, int>,
234
                  NetworkSimplex<GR> >();
235
    checkConcept< McfClassConcept<GR, double, double>,
236
                  NetworkSimplex<GR, double> >();
237
    checkConcept< McfClassConcept<GR, int, double>,
238
                  NetworkSimplex<GR, int, double> >();
242 239
  }
243 240

	
244 241
  // Run various MCF tests
245 242
  typedef ListDigraph Digraph;
246 243
  DIGRAPH_TYPEDEFS(ListDigraph);
247 244

	
248 245
  // Read the test digraph
249 246
  Digraph gr;
250 247
  Digraph::ArcMap<int> c(gr), l1(gr), l2(gr), l3(gr), u(gr);
251 248
  Digraph::NodeMap<int> s1(gr), s2(gr), s3(gr), s4(gr), s5(gr), s6(gr);
252 249
  ConstMap<Arc, int> cc(1), cu(std::numeric_limits<int>::max());
253 250
  Node v, w;
254 251

	
255 252
  std::istringstream input(test_lgf);
256 253
  DigraphReader<Digraph>(gr, input)
257 254
    .arcMap("cost", c)
258 255
    .arcMap("cap", u)
259 256
    .arcMap("low1", l1)
260 257
    .arcMap("low2", l2)
261 258
    .arcMap("low3", l3)
262 259
    .nodeMap("sup1", s1)
263 260
    .nodeMap("sup2", s2)
264 261
    .nodeMap("sup3", s3)
265 262
    .nodeMap("sup4", s4)
266 263
    .nodeMap("sup5", s5)
267 264
    .nodeMap("sup6", s6)
268 265
    .node("source", v)
269 266
    .node("target", w)
270 267
    .run();
271 268
  
272 269
  // Build a test digraph for testing negative costs
273 270
  Digraph ngr;
0 comments (0 inline)