gravatar
kpeter (Peter Kovacs)
kpeter@inf.elte.hu
Rename min mean cycle classes and their members (#179) with respect to the possible introduction of min ratio cycle algorithms in the future. The renamed classes: - Karp --> KarpMmc - HartmannOrlin --> HartmannOrlinMmc - Howard --> HowardMmc The renamed members: - cycleLength() --> cycleCost() - cycleArcNum() --> cycleSize() - findMinMean() --> findCycleMean() - Value --> Cost - LargeValue --> LargeCost - SetLargeValue --> SetLargeCost
3 3 3
default
9 files changed with 386 insertions and 386 deletions:
↑ Collapse diff ↑
Ignore white space 6 line context
... ...
@@ -44,100 +44,100 @@
44 44
if HAVE_SOPLEX
45 45
lemon_libemon_la_SOURCES += lemon/soplex.cc
46 46
endif
47 47

	
48 48
if HAVE_CLP
49 49
lemon_libemon_la_SOURCES += lemon/clp.cc
50 50
endif
51 51

	
52 52
if HAVE_CBC
53 53
lemon_libemon_la_SOURCES += lemon/cbc.cc
54 54
endif
55 55

	
56 56
lemon_HEADERS += \
57 57
	lemon/adaptors.h \
58 58
	lemon/arg_parser.h \
59 59
	lemon/assert.h \
60 60
	lemon/bellman_ford.h \
61 61
	lemon/bfs.h \
62 62
	lemon/bin_heap.h \
63 63
	lemon/binomial_heap.h \
64 64
	lemon/bucket_heap.h \
65 65
	lemon/capacity_scaling.h \
66 66
	lemon/cbc.h \
67 67
	lemon/circulation.h \
68 68
	lemon/clp.h \
69 69
	lemon/color.h \
70 70
	lemon/concept_check.h \
71 71
	lemon/connectivity.h \
72 72
	lemon/core.h \
73 73
	lemon/cost_scaling.h \
74 74
	lemon/counter.h \
75 75
	lemon/cplex.h \
76 76
	lemon/cycle_canceling.h \
77 77
	lemon/dfs.h \
78 78
	lemon/dheap.h \
79 79
	lemon/dijkstra.h \
80 80
	lemon/dim2.h \
81 81
	lemon/dimacs.h \
82 82
	lemon/edge_set.h \
83 83
	lemon/elevator.h \
84 84
	lemon/error.h \
85 85
	lemon/euler.h \
86 86
	lemon/fib_heap.h \
87 87
	lemon/full_graph.h \
88 88
	lemon/glpk.h \
89 89
	lemon/gomory_hu.h \
90 90
	lemon/graph_to_eps.h \
91 91
	lemon/grid_graph.h \
92
	lemon/hartmann_orlin.h \
93
	lemon/howard.h \
92
	lemon/hartmann_orlin_mmc.h \
93
	lemon/howard_mmc.h \
94 94
	lemon/hypercube_graph.h \
95
	lemon/karp.h \
95
	lemon/karp_mmc.h \
96 96
	lemon/kruskal.h \
97 97
	lemon/hao_orlin.h \
98 98
	lemon/lgf_reader.h \
99 99
	lemon/lgf_writer.h \
100 100
	lemon/list_graph.h \
101 101
	lemon/lp.h \
102 102
	lemon/lp_base.h \
103 103
	lemon/lp_skeleton.h \
104 104
	lemon/maps.h \
105 105
	lemon/matching.h \
106 106
	lemon/math.h \
107 107
	lemon/min_cost_arborescence.h \
108 108
	lemon/nauty_reader.h \
109 109
	lemon/network_simplex.h \
110 110
	lemon/pairing_heap.h \
111 111
	lemon/path.h \
112 112
	lemon/planarity.h \
113 113
	lemon/preflow.h \
114 114
	lemon/quad_heap.h \
115 115
	lemon/radix_heap.h \
116 116
	lemon/radix_sort.h \
117 117
	lemon/random.h \
118 118
	lemon/smart_graph.h \
119 119
	lemon/soplex.h \
120 120
	lemon/static_graph.h \
121 121
	lemon/suurballe.h \
122 122
	lemon/time_measure.h \
123 123
	lemon/tolerance.h \
124 124
	lemon/unionfind.h \
125 125
	lemon/bits/windows.h
126 126

	
127 127
bits_HEADERS += \
128 128
	lemon/bits/alteration_notifier.h \
129 129
	lemon/bits/array_map.h \
130 130
	lemon/bits/bezier.h \
131 131
	lemon/bits/default_map.h \
132 132
	lemon/bits/edge_set_extender.h \
133 133
	lemon/bits/enable_if.h \
134 134
	lemon/bits/graph_adaptor_extender.h \
135 135
	lemon/bits/graph_extender.h \
136 136
	lemon/bits/map_extender.h \
137 137
	lemon/bits/path_dump.h \
138 138
	lemon/bits/solver_bits.h \
139 139
	lemon/bits/traits.h \
140 140
	lemon/bits/variant.h \
141 141
	lemon/bits/vector_map.h
142 142

	
143 143
concept_HEADERS += \
Ignore white space 6 line context
1 1
/* -*- C++ -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library
4 4
 *
5 5
 * Copyright (C) 2003-2008
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
#ifndef LEMON_CYCLE_CANCELING_H
20 20
#define LEMON_CYCLE_CANCELING_H
21 21

	
22 22
/// \ingroup min_cost_flow_algs
23 23
/// \file
24 24
/// \brief Cycle-canceling algorithms for finding a minimum cost flow.
25 25

	
26 26
#include <vector>
27 27
#include <limits>
28 28

	
29 29
#include <lemon/core.h>
30 30
#include <lemon/maps.h>
31 31
#include <lemon/path.h>
32 32
#include <lemon/math.h>
33 33
#include <lemon/static_graph.h>
34 34
#include <lemon/adaptors.h>
35 35
#include <lemon/circulation.h>
36 36
#include <lemon/bellman_ford.h>
37
#include <lemon/howard.h>
37
#include <lemon/howard_mmc.h>
38 38

	
39 39
namespace lemon {
40 40

	
41 41
  /// \addtogroup min_cost_flow_algs
42 42
  /// @{
43 43

	
44 44
  /// \brief Implementation of cycle-canceling algorithms for
45 45
  /// finding a \ref min_cost_flow "minimum cost flow".
46 46
  ///
47 47
  /// \ref CycleCanceling implements three different cycle-canceling
48 48
  /// algorithms for finding a \ref min_cost_flow "minimum cost flow"
49 49
  /// \ref amo93networkflows, \ref klein67primal,
50 50
  /// \ref goldberg89cyclecanceling.
51 51
  /// The most efficent one (both theoretically and practically)
52 52
  /// is the \ref CANCEL_AND_TIGHTEN "Cancel and Tighten" algorithm,
53 53
  /// thus it is the default method.
54 54
  /// It is strongly polynomial, but in practice, it is typically much
55 55
  /// slower than the scaling algorithms and NetworkSimplex.
56 56
  ///
57 57
  /// Most of the parameters of the problem (except for the digraph)
58 58
  /// can be given using separate functions, and the algorithm can be
59 59
  /// executed using the \ref run() function. If some parameters are not
60 60
  /// specified, then default values will be used.
61 61
  ///
62 62
  /// \tparam GR The digraph type the algorithm runs on.
63 63
  /// \tparam V The number type used for flow amounts, capacity bounds
64 64
  /// and supply values in the algorithm. By default, it is \c int.
65 65
  /// \tparam C The number type used for costs and potentials in the
66 66
  /// algorithm. By default, it is the same as \c V.
67 67
  ///
68 68
  /// \warning Both number types must be signed and all input data must
69 69
  /// be integer.
70 70
  /// \warning This algorithm does not support negative costs for such
71 71
  /// arcs that have infinite upper bound.
72 72
  ///
73 73
  /// \note For more information about the three available methods,
74 74
  /// see \ref Method.
75 75
#ifdef DOXYGEN
76 76
  template <typename GR, typename V, typename C>
77 77
#else
78 78
  template <typename GR, typename V = int, typename C = V>
79 79
#endif
80 80
  class CycleCanceling
81 81
  {
82 82
  public:
83 83

	
84 84
    /// The type of the digraph
85 85
    typedef GR Digraph;
... ...
@@ -879,104 +879,104 @@
879 879
          } else {
880 880
            // Search for node disjoint negative cycles
881 881
            std::vector<int> state(_res_node_num, 0);
882 882
            int id = 0;
883 883
            for (int u = 0; u != _res_node_num; ++u) {
884 884
              if (state[u] != 0) continue;
885 885
              ++id;
886 886
              int v = u;
887 887
              for (; v != -1 && state[v] == 0; v = pred[v] == INVALID ?
888 888
                   -1 : rgr.id(rgr.source(pred[v]))) {
889 889
                state[v] = id;
890 890
              }
891 891
              if (v != -1 && state[v] == id) {
892 892
                // A negative cycle is found
893 893
                cycle_found = true;
894 894
                cycle.clear();
895 895
                StaticDigraph::Arc a = pred[v];
896 896
                Value d, delta = _res_cap[rgr.id(a)];
897 897
                cycle.push_back(rgr.id(a));
898 898
                while (rgr.id(rgr.source(a)) != v) {
899 899
                  a = pred_map[rgr.source(a)];
900 900
                  d = _res_cap[rgr.id(a)];
901 901
                  if (d < delta) delta = d;
902 902
                  cycle.push_back(rgr.id(a));
903 903
                }
904 904

	
905 905
                // Augment along the cycle
906 906
                for (int i = 0; i < int(cycle.size()); ++i) {
907 907
                  int j = cycle[i];
908 908
                  _res_cap[j] -= delta;
909 909
                  _res_cap[_reverse[j]] += delta;
910 910
                }
911 911
              }
912 912
            }
913 913
          }
914 914

	
915 915
          // Increase iteration limit if no cycle is found
916 916
          if (!cycle_found) {
917 917
            length_bound = static_cast<int>(length_bound * BF_LIMIT_FACTOR);
918 918
          }
919 919
        }
920 920
      }
921 921
    }
922 922

	
923 923
    // Execute the "Minimum Mean Cycle Canceling" method
924 924
    void startMinMeanCycleCanceling() {
925 925
      typedef SimplePath<StaticDigraph> SPath;
926 926
      typedef typename SPath::ArcIt SPathArcIt;
927
      typedef typename Howard<StaticDigraph, CostArcMap>
927
      typedef typename HowardMmc<StaticDigraph, CostArcMap>
928 928
        ::template SetPath<SPath>::Create MMC;
929 929
      
930 930
      SPath cycle;
931 931
      MMC mmc(_sgr, _cost_map);
932 932
      mmc.cycle(cycle);
933 933
      buildResidualNetwork();
934
      while (mmc.findMinMean() && mmc.cycleLength() < 0) {
934
      while (mmc.findCycleMean() && mmc.cycleCost() < 0) {
935 935
        // Find the cycle
936 936
        mmc.findCycle();
937 937

	
938 938
        // Compute delta value
939 939
        Value delta = INF;
940 940
        for (SPathArcIt a(cycle); a != INVALID; ++a) {
941 941
          Value d = _res_cap[_id_vec[_sgr.id(a)]];
942 942
          if (d < delta) delta = d;
943 943
        }
944 944

	
945 945
        // Augment along the cycle
946 946
        for (SPathArcIt a(cycle); a != INVALID; ++a) {
947 947
          int j = _id_vec[_sgr.id(a)];
948 948
          _res_cap[j] -= delta;
949 949
          _res_cap[_reverse[j]] += delta;
950 950
        }
951 951

	
952 952
        // Rebuild the residual network        
953 953
        buildResidualNetwork();
954 954
      }
955 955
    }
956 956

	
957 957
    // Execute the "Cancel And Tighten" method
958 958
    void startCancelAndTighten() {
959 959
      // Constants for the min mean cycle computations
960 960
      const double LIMIT_FACTOR = 1.0;
961 961
      const int MIN_LIMIT = 5;
962 962

	
963 963
      // Contruct auxiliary data vectors
964 964
      DoubleVector pi(_res_node_num, 0.0);
965 965
      IntVector level(_res_node_num);
966 966
      BoolVector reached(_res_node_num);
967 967
      BoolVector processed(_res_node_num);
968 968
      IntVector pred_node(_res_node_num);
969 969
      IntVector pred_arc(_res_node_num);
970 970
      std::vector<int> stack(_res_node_num);
971 971
      std::vector<int> proc_vector(_res_node_num);
972 972

	
973 973
      // Initialize epsilon
974 974
      double epsilon = 0;
975 975
      for (int a = 0; a != _res_arc_num; ++a) {
976 976
        if (_res_cap[a] > 0 && -_cost[a] > epsilon)
977 977
          epsilon = -_cost[a];
978 978
      }
979 979

	
980 980
      // Start phases
981 981
      Tolerance<double> tol;
982 982
      tol.epsilon(1e-6);
... ...
@@ -1087,84 +1087,84 @@
1087 1087
        if (--iter > 0) {
1088 1088
          for (int u = 0; u != _res_node_num; ++u) {
1089 1089
            level[u] = 0;
1090 1090
          }
1091 1091
          for (int i = proc_head; i > 0; --i) {
1092 1092
            int u = proc_vector[i];
1093 1093
            double p = pi[u];
1094 1094
            int l = level[u] + 1;
1095 1095
            int last_out = _first_out[u+1];
1096 1096
            for (int a = _first_out[u]; a != last_out; ++a) {
1097 1097
              int v = _target[a];
1098 1098
              if (_res_cap[a] > 0 && tol.negative(_cost[a] + p - pi[v]) &&
1099 1099
                  l > level[v]) level[v] = l;
1100 1100
            }
1101 1101
          }
1102 1102

	
1103 1103
          // Modify potentials
1104 1104
          double q = std::numeric_limits<double>::max();
1105 1105
          for (int u = 0; u != _res_node_num; ++u) {
1106 1106
            int lu = level[u];
1107 1107
            double p, pu = pi[u];
1108 1108
            int last_out = _first_out[u+1];
1109 1109
            for (int a = _first_out[u]; a != last_out; ++a) {
1110 1110
              if (_res_cap[a] == 0) continue;
1111 1111
              int v = _target[a];
1112 1112
              int ld = lu - level[v];
1113 1113
              if (ld > 0) {
1114 1114
                p = (_cost[a] + pu - pi[v] + epsilon) / (ld + 1);
1115 1115
                if (p < q) q = p;
1116 1116
              }
1117 1117
            }
1118 1118
          }
1119 1119
          for (int u = 0; u != _res_node_num; ++u) {
1120 1120
            pi[u] -= q * level[u];
1121 1121
          }
1122 1122

	
1123 1123
          // Modify epsilon
1124 1124
          epsilon = 0;
1125 1125
          for (int u = 0; u != _res_node_num; ++u) {
1126 1126
            double curr, pu = pi[u];
1127 1127
            int last_out = _first_out[u+1];
1128 1128
            for (int a = _first_out[u]; a != last_out; ++a) {
1129 1129
              if (_res_cap[a] == 0) continue;
1130 1130
              curr = _cost[a] + pu - pi[_target[a]];
1131 1131
              if (-curr > epsilon) epsilon = -curr;
1132 1132
            }
1133 1133
          }
1134 1134
        } else {
1135
          typedef Howard<StaticDigraph, CostArcMap> MMC;
1135
          typedef HowardMmc<StaticDigraph, CostArcMap> MMC;
1136 1136
          typedef typename BellmanFord<StaticDigraph, CostArcMap>
1137 1137
            ::template SetDistMap<CostNodeMap>::Create BF;
1138 1138

	
1139 1139
          // Set epsilon to the minimum cycle mean
1140 1140
          buildResidualNetwork();
1141 1141
          MMC mmc(_sgr, _cost_map);
1142
          mmc.findMinMean();
1142
          mmc.findCycleMean();
1143 1143
          epsilon = -mmc.cycleMean();
1144
          Cost cycle_cost = mmc.cycleLength();
1145
          int cycle_size = mmc.cycleArcNum();
1144
          Cost cycle_cost = mmc.cycleCost();
1145
          int cycle_size = mmc.cycleSize();
1146 1146
          
1147 1147
          // Compute feasible potentials for the current epsilon
1148 1148
          for (int i = 0; i != int(_cost_vec.size()); ++i) {
1149 1149
            _cost_vec[i] = cycle_size * _cost_vec[i] - cycle_cost;
1150 1150
          }
1151 1151
          BF bf(_sgr, _cost_map);
1152 1152
          bf.distMap(_pi_map);
1153 1153
          bf.init(0);
1154 1154
          bf.start();
1155 1155
          for (int u = 0; u != _res_node_num; ++u) {
1156 1156
            pi[u] = static_cast<double>(_pi[u]) / cycle_size;
1157 1157
          }
1158 1158
        
1159 1159
          iter = limit;
1160 1160
        }
1161 1161
      }
1162 1162
    }
1163 1163

	
1164 1164
  }; //class CycleCanceling
1165 1165

	
1166 1166
  ///@}
1167 1167

	
1168 1168
} //namespace lemon
1169 1169

	
1170 1170
#endif //LEMON_CYCLE_CANCELING_H
Ignore white space 96 line context
1 1
/* -*- C++ -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library
4 4
 *
5 5
 * Copyright (C) 2003-2008
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19
#ifndef LEMON_HARTMANN_ORLIN_H
20
#define LEMON_HARTMANN_ORLIN_H
19
#ifndef LEMON_HARTMANN_ORLIN_MMC_H
20
#define LEMON_HARTMANN_ORLIN_MMC_H
21 21

	
22 22
/// \ingroup min_mean_cycle
23 23
///
24 24
/// \file
25 25
/// \brief Hartmann-Orlin's algorithm for finding a minimum mean cycle.
26 26

	
27 27
#include <vector>
28 28
#include <limits>
29 29
#include <lemon/core.h>
30 30
#include <lemon/path.h>
31 31
#include <lemon/tolerance.h>
32 32
#include <lemon/connectivity.h>
33 33

	
34 34
namespace lemon {
35 35

	
36
  /// \brief Default traits class of HartmannOrlin algorithm.
36
  /// \brief Default traits class of HartmannOrlinMmc class.
37 37
  ///
38
  /// Default traits class of HartmannOrlin algorithm.
38
  /// Default traits class of HartmannOrlinMmc class.
39 39
  /// \tparam GR The type of the digraph.
40
  /// \tparam LEN The type of the length map.
40
  /// \tparam CM The type of the cost map.
41 41
  /// It must conform to the \ref concepts::Rea_data "Rea_data" concept.
42 42
#ifdef DOXYGEN
43
  template <typename GR, typename LEN>
43
  template <typename GR, typename CM>
44 44
#else
45
  template <typename GR, typename LEN,
46
    bool integer = std::numeric_limits<typename LEN::Value>::is_integer>
45
  template <typename GR, typename CM,
46
    bool integer = std::numeric_limits<typename CM::Value>::is_integer>
47 47
#endif
48
  struct HartmannOrlinDefaultTraits
48
  struct HartmannOrlinMmcDefaultTraits
49 49
  {
50 50
    /// The type of the digraph
51 51
    typedef GR Digraph;
52
    /// The type of the length map
53
    typedef LEN LengthMap;
54
    /// The type of the arc lengths
55
    typedef typename LengthMap::Value Value;
52
    /// The type of the cost map
53
    typedef CM CostMap;
54
    /// The type of the arc costs
55
    typedef typename CostMap::Value Cost;
56 56

	
57
    /// \brief The large value type used for internal computations
57
    /// \brief The large cost type used for internal computations
58 58
    ///
59
    /// The large value type used for internal computations.
60
    /// It is \c long \c long if the \c Value type is integer,
59
    /// The large cost type used for internal computations.
60
    /// It is \c long \c long if the \c Cost type is integer,
61 61
    /// otherwise it is \c double.
62
    /// \c Value must be convertible to \c LargeValue.
63
    typedef double LargeValue;
62
    /// \c Cost must be convertible to \c LargeCost.
63
    typedef double LargeCost;
64 64

	
65 65
    /// The tolerance type used for internal computations
66
    typedef lemon::Tolerance<LargeValue> Tolerance;
66
    typedef lemon::Tolerance<LargeCost> Tolerance;
67 67

	
68 68
    /// \brief The path type of the found cycles
69 69
    ///
70 70
    /// The path type of the found cycles.
71 71
    /// It must conform to the \ref lemon::concepts::Path "Path" concept
72 72
    /// and it must have an \c addFront() function.
73 73
    typedef lemon::Path<Digraph> Path;
74 74
  };
75 75

	
76
  // Default traits class for integer value types
77
  template <typename GR, typename LEN>
78
  struct HartmannOrlinDefaultTraits<GR, LEN, true>
76
  // Default traits class for integer cost types
77
  template <typename GR, typename CM>
78
  struct HartmannOrlinMmcDefaultTraits<GR, CM, true>
79 79
  {
80 80
    typedef GR Digraph;
81
    typedef LEN LengthMap;
82
    typedef typename LengthMap::Value Value;
81
    typedef CM CostMap;
82
    typedef typename CostMap::Value Cost;
83 83
#ifdef LEMON_HAVE_LONG_LONG
84
    typedef long long LargeValue;
84
    typedef long long LargeCost;
85 85
#else
86
    typedef long LargeValue;
86
    typedef long LargeCost;
87 87
#endif
88
    typedef lemon::Tolerance<LargeValue> Tolerance;
88
    typedef lemon::Tolerance<LargeCost> Tolerance;
89 89
    typedef lemon::Path<Digraph> Path;
90 90
  };
91 91

	
92 92

	
93 93
  /// \addtogroup min_mean_cycle
94 94
  /// @{
95 95

	
96 96
  /// \brief Implementation of the Hartmann-Orlin algorithm for finding
97 97
  /// a minimum mean cycle.
98 98
  ///
99 99
  /// This class implements the Hartmann-Orlin algorithm for finding
100
  /// a directed cycle of minimum mean length (cost) in a digraph
100
  /// a directed cycle of minimum mean cost in a digraph
101 101
  /// \ref amo93networkflows, \ref dasdan98minmeancycle.
102 102
  /// It is an improved version of \ref Karp "Karp"'s original algorithm,
103 103
  /// it applies an efficient early termination scheme.
104 104
  /// It runs in time O(ne) and uses space O(n<sup>2</sup>+e).
105 105
  ///
106 106
  /// \tparam GR The type of the digraph the algorithm runs on.
107
  /// \tparam LEN The type of the length map. The default
107
  /// \tparam CM The type of the cost map. The default
108 108
  /// map type is \ref concepts::Digraph::ArcMap "GR::ArcMap<int>".
109 109
  /// \tparam TR The traits class that defines various types used by the
110
  /// algorithm. By default, it is \ref HartmannOrlinDefaultTraits
111
  /// "HartmannOrlinDefaultTraits<GR, LEN>".
110
  /// algorithm. By default, it is \ref HartmannOrlinMmcDefaultTraits
111
  /// "HartmannOrlinMmcDefaultTraits<GR, CM>".
112 112
  /// In most cases, this parameter should not be set directly,
113 113
  /// consider to use the named template parameters instead.
114 114
#ifdef DOXYGEN
115
  template <typename GR, typename LEN, typename TR>
115
  template <typename GR, typename CM, typename TR>
116 116
#else
117 117
  template < typename GR,
118
             typename LEN = typename GR::template ArcMap<int>,
119
             typename TR = HartmannOrlinDefaultTraits<GR, LEN> >
118
             typename CM = typename GR::template ArcMap<int>,
119
             typename TR = HartmannOrlinMmcDefaultTraits<GR, CM> >
120 120
#endif
121
  class HartmannOrlin
121
  class HartmannOrlinMmc
122 122
  {
123 123
  public:
124 124

	
125 125
    /// The type of the digraph
126 126
    typedef typename TR::Digraph Digraph;
127
    /// The type of the length map
128
    typedef typename TR::LengthMap LengthMap;
129
    /// The type of the arc lengths
130
    typedef typename TR::Value Value;
127
    /// The type of the cost map
128
    typedef typename TR::CostMap CostMap;
129
    /// The type of the arc costs
130
    typedef typename TR::Cost Cost;
131 131

	
132
    /// \brief The large value type
132
    /// \brief The large cost type
133 133
    ///
134
    /// The large value type used for internal computations.
135
    /// By default, it is \c long \c long if the \c Value type is integer,
134
    /// The large cost type used for internal computations.
135
    /// By default, it is \c long \c long if the \c Cost type is integer,
136 136
    /// otherwise it is \c double.
137
    typedef typename TR::LargeValue LargeValue;
137
    typedef typename TR::LargeCost LargeCost;
138 138

	
139 139
    /// The tolerance type
140 140
    typedef typename TR::Tolerance Tolerance;
141 141

	
142 142
    /// \brief The path type of the found cycles
143 143
    ///
144 144
    /// The path type of the found cycles.
145
    /// Using the \ref HartmannOrlinDefaultTraits "default traits class",
145
    /// Using the \ref HartmannOrlinMmcDefaultTraits "default traits class",
146 146
    /// it is \ref lemon::Path "Path<Digraph>".
147 147
    typedef typename TR::Path Path;
148 148

	
149
    /// The \ref HartmannOrlinDefaultTraits "traits class" of the algorithm
149
    /// The \ref HartmannOrlinMmcDefaultTraits "traits class" of the algorithm
150 150
    typedef TR Traits;
151 151

	
152 152
  private:
153 153

	
154 154
    TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
155 155

	
156 156
    // Data sturcture for path data
157 157
    struct PathData
158 158
    {
159
      LargeValue dist;
159
      LargeCost dist;
160 160
      Arc pred;
161
      PathData(LargeValue d, Arc p = INVALID) :
161
      PathData(LargeCost d, Arc p = INVALID) :
162 162
        dist(d), pred(p) {}
163 163
    };
164 164

	
165 165
    typedef typename Digraph::template NodeMap<std::vector<PathData> >
166 166
      PathDataNodeMap;
167 167

	
168 168
  private:
169 169

	
170 170
    // The digraph the algorithm runs on
171 171
    const Digraph &_gr;
172
    // The length of the arcs
173
    const LengthMap &_length;
172
    // The cost of the arcs
173
    const CostMap &_cost;
174 174

	
175 175
    // Data for storing the strongly connected components
176 176
    int _comp_num;
177 177
    typename Digraph::template NodeMap<int> _comp;
178 178
    std::vector<std::vector<Node> > _comp_nodes;
179 179
    std::vector<Node>* _nodes;
180 180
    typename Digraph::template NodeMap<std::vector<Arc> > _out_arcs;
181 181

	
182 182
    // Data for the found cycles
183 183
    bool _curr_found, _best_found;
184
    LargeValue _curr_length, _best_length;
184
    LargeCost _curr_cost, _best_cost;
185 185
    int _curr_size, _best_size;
186 186
    Node _curr_node, _best_node;
187 187
    int _curr_level, _best_level;
188 188

	
189 189
    Path *_cycle_path;
190 190
    bool _local_path;
191 191

	
192 192
    // Node map for storing path data
193 193
    PathDataNodeMap _data;
194 194
    // The processed nodes in the last round
195 195
    std::vector<Node> _process;
196 196

	
197 197
    Tolerance _tolerance;
198 198

	
199 199
    // Infinite constant
200
    const LargeValue INF;
200
    const LargeCost INF;
201 201

	
202 202
  public:
203 203

	
204 204
    /// \name Named Template Parameters
205 205
    /// @{
206 206

	
207 207
    template <typename T>
208
    struct SetLargeValueTraits : public Traits {
209
      typedef T LargeValue;
208
    struct SetLargeCostTraits : public Traits {
209
      typedef T LargeCost;
210 210
      typedef lemon::Tolerance<T> Tolerance;
211 211
    };
212 212

	
213 213
    /// \brief \ref named-templ-param "Named parameter" for setting
214
    /// \c LargeValue type.
214
    /// \c LargeCost type.
215 215
    ///
216
    /// \ref named-templ-param "Named parameter" for setting \c LargeValue
216
    /// \ref named-templ-param "Named parameter" for setting \c LargeCost
217 217
    /// type. It is used for internal computations in the algorithm.
218 218
    template <typename T>
219
    struct SetLargeValue
220
      : public HartmannOrlin<GR, LEN, SetLargeValueTraits<T> > {
221
      typedef HartmannOrlin<GR, LEN, SetLargeValueTraits<T> > Create;
219
    struct SetLargeCost
220
      : public HartmannOrlinMmc<GR, CM, SetLargeCostTraits<T> > {
221
      typedef HartmannOrlinMmc<GR, CM, SetLargeCostTraits<T> > Create;
222 222
    };
223 223

	
224 224
    template <typename T>
225 225
    struct SetPathTraits : public Traits {
226 226
      typedef T Path;
227 227
    };
228 228

	
229 229
    /// \brief \ref named-templ-param "Named parameter" for setting
230 230
    /// \c %Path type.
231 231
    ///
232 232
    /// \ref named-templ-param "Named parameter" for setting the \c %Path
233 233
    /// type of the found cycles.
234 234
    /// It must conform to the \ref lemon::concepts::Path "Path" concept
235 235
    /// and it must have an \c addFront() function.
236 236
    template <typename T>
237 237
    struct SetPath
238
      : public HartmannOrlin<GR, LEN, SetPathTraits<T> > {
239
      typedef HartmannOrlin<GR, LEN, SetPathTraits<T> > Create;
238
      : public HartmannOrlinMmc<GR, CM, SetPathTraits<T> > {
239
      typedef HartmannOrlinMmc<GR, CM, SetPathTraits<T> > Create;
240 240
    };
241 241

	
242 242
    /// @}
243 243

	
244 244
  protected:
245 245

	
246
    HartmannOrlin() {}
246
    HartmannOrlinMmc() {}
247 247

	
248 248
  public:
249 249

	
250 250
    /// \brief Constructor.
251 251
    ///
252 252
    /// The constructor of the class.
253 253
    ///
254 254
    /// \param digraph The digraph the algorithm runs on.
255
    /// \param length The lengths (costs) of the arcs.
256
    HartmannOrlin( const Digraph &digraph,
257
                   const LengthMap &length ) :
258
      _gr(digraph), _length(length), _comp(digraph), _out_arcs(digraph),
259
      _best_found(false), _best_length(0), _best_size(1),
255
    /// \param cost The costs of the arcs.
256
    HartmannOrlinMmc( const Digraph &digraph,
257
                      const CostMap &cost ) :
258
      _gr(digraph), _cost(cost), _comp(digraph), _out_arcs(digraph),
259
      _best_found(false), _best_cost(0), _best_size(1),
260 260
      _cycle_path(NULL), _local_path(false), _data(digraph),
261
      INF(std::numeric_limits<LargeValue>::has_infinity ?
262
          std::numeric_limits<LargeValue>::infinity() :
263
          std::numeric_limits<LargeValue>::max())
261
      INF(std::numeric_limits<LargeCost>::has_infinity ?
262
          std::numeric_limits<LargeCost>::infinity() :
263
          std::numeric_limits<LargeCost>::max())
264 264
    {}
265 265

	
266 266
    /// Destructor.
267
    ~HartmannOrlin() {
267
    ~HartmannOrlinMmc() {
268 268
      if (_local_path) delete _cycle_path;
269 269
    }
270 270

	
271 271
    /// \brief Set the path structure for storing the found cycle.
272 272
    ///
273 273
    /// This function sets an external path structure for storing the
274 274
    /// found cycle.
275 275
    ///
276 276
    /// If you don't call this function before calling \ref run() or
277
    /// \ref findMinMean(), it will allocate a local \ref Path "path"
277
    /// \ref findCycleMean(), it will allocate a local \ref Path "path"
278 278
    /// structure. The destuctor deallocates this automatically
279 279
    /// allocated object, of course.
280 280
    ///
281 281
    /// \note The algorithm calls only the \ref lemon::Path::addFront()
282 282
    /// "addFront()" function of the given path structure.
283 283
    ///
284 284
    /// \return <tt>(*this)</tt>
285
    HartmannOrlin& cycle(Path &path) {
285
    HartmannOrlinMmc& cycle(Path &path) {
286 286
      if (_local_path) {
287 287
        delete _cycle_path;
288 288
        _local_path = false;
289 289
      }
290 290
      _cycle_path = &path;
291 291
      return *this;
292 292
    }
293 293

	
294 294
    /// \brief Set the tolerance used by the algorithm.
295 295
    ///
296 296
    /// This function sets the tolerance object used by the algorithm.
297 297
    ///
298 298
    /// \return <tt>(*this)</tt>
299
    HartmannOrlin& tolerance(const Tolerance& tolerance) {
299
    HartmannOrlinMmc& tolerance(const Tolerance& tolerance) {
300 300
      _tolerance = tolerance;
301 301
      return *this;
302 302
    }
303 303

	
304 304
    /// \brief Return a const reference to the tolerance.
305 305
    ///
306 306
    /// This function returns a const reference to the tolerance object
307 307
    /// used by the algorithm.
308 308
    const Tolerance& tolerance() const {
309 309
      return _tolerance;
310 310
    }
311 311

	
312 312
    /// \name Execution control
313 313
    /// The simplest way to execute the algorithm is to call the \ref run()
314 314
    /// function.\n
315
    /// If you only need the minimum mean length, you may call
316
    /// \ref findMinMean().
315
    /// If you only need the minimum mean cost, you may call
316
    /// \ref findCycleMean().
317 317

	
318 318
    /// @{
319 319

	
320 320
    /// \brief Run the algorithm.
321 321
    ///
322 322
    /// This function runs the algorithm.
323 323
    /// It can be called more than once (e.g. if the underlying digraph
324
    /// and/or the arc lengths have been modified).
324
    /// and/or the arc costs have been modified).
325 325
    ///
326 326
    /// \return \c true if a directed cycle exists in the digraph.
327 327
    ///
328 328
    /// \note <tt>mmc.run()</tt> is just a shortcut of the following code.
329 329
    /// \code
330
    ///   return mmc.findMinMean() && mmc.findCycle();
330
    ///   return mmc.findCycleMean() && mmc.findCycle();
331 331
    /// \endcode
332 332
    bool run() {
333
      return findMinMean() && findCycle();
333
      return findCycleMean() && findCycle();
334 334
    }
335 335

	
336 336
    /// \brief Find the minimum cycle mean.
337 337
    ///
338
    /// This function finds the minimum mean length of the directed
338
    /// This function finds the minimum mean cost of the directed
339 339
    /// cycles in the digraph.
340 340
    ///
341 341
    /// \return \c true if a directed cycle exists in the digraph.
342
    bool findMinMean() {
342
    bool findCycleMean() {
343 343
      // Initialization and find strongly connected components
344 344
      init();
345 345
      findComponents();
346 346
      
347 347
      // Find the minimum cycle mean in the components
348 348
      for (int comp = 0; comp < _comp_num; ++comp) {
349 349
        if (!initComponent(comp)) continue;
350 350
        processRounds();
351 351
        
352 352
        // Update the best cycle (global minimum mean cycle)
353 353
        if ( _curr_found && (!_best_found || 
354
             _curr_length * _best_size < _best_length * _curr_size) ) {
354
             _curr_cost * _best_size < _best_cost * _curr_size) ) {
355 355
          _best_found = true;
356
          _best_length = _curr_length;
356
          _best_cost = _curr_cost;
357 357
          _best_size = _curr_size;
358 358
          _best_node = _curr_node;
359 359
          _best_level = _curr_level;
360 360
        }
361 361
      }
362 362
      return _best_found;
363 363
    }
364 364

	
365 365
    /// \brief Find a minimum mean directed cycle.
366 366
    ///
367
    /// This function finds a directed cycle of minimum mean length
368
    /// in the digraph using the data computed by findMinMean().
367
    /// This function finds a directed cycle of minimum mean cost
368
    /// in the digraph using the data computed by findCycleMean().
369 369
    ///
370 370
    /// \return \c true if a directed cycle exists in the digraph.
371 371
    ///
372
    /// \pre \ref findMinMean() must be called before using this function.
372
    /// \pre \ref findCycleMean() must be called before using this function.
373 373
    bool findCycle() {
374 374
      if (!_best_found) return false;
375 375
      IntNodeMap reached(_gr, -1);
376 376
      int r = _best_level + 1;
377 377
      Node u = _best_node;
378 378
      while (reached[u] < 0) {
379 379
        reached[u] = --r;
380 380
        u = _gr.source(_data[u][r].pred);
381 381
      }
382 382
      r = reached[u];
383 383
      Arc e = _data[u][r].pred;
384 384
      _cycle_path->addFront(e);
385
      _best_length = _length[e];
385
      _best_cost = _cost[e];
386 386
      _best_size = 1;
387 387
      Node v;
388 388
      while ((v = _gr.source(e)) != u) {
389 389
        e = _data[v][--r].pred;
390 390
        _cycle_path->addFront(e);
391
        _best_length += _length[e];
391
        _best_cost += _cost[e];
392 392
        ++_best_size;
393 393
      }
394 394
      return true;
395 395
    }
396 396

	
397 397
    /// @}
398 398

	
399 399
    /// \name Query Functions
400 400
    /// The results of the algorithm can be obtained using these
401 401
    /// functions.\n
402 402
    /// The algorithm should be executed before using them.
403 403

	
404 404
    /// @{
405 405

	
406
    /// \brief Return the total length of the found cycle.
406
    /// \brief Return the total cost of the found cycle.
407 407
    ///
408
    /// This function returns the total length of the found cycle.
408
    /// This function returns the total cost of the found cycle.
409 409
    ///
410
    /// \pre \ref run() or \ref findMinMean() must be called before
410
    /// \pre \ref run() or \ref findCycleMean() must be called before
411 411
    /// using this function.
412
    Value cycleLength() const {
413
      return static_cast<Value>(_best_length);
412
    Cost cycleCost() const {
413
      return static_cast<Cost>(_best_cost);
414 414
    }
415 415

	
416 416
    /// \brief Return the number of arcs on the found cycle.
417 417
    ///
418 418
    /// This function returns the number of arcs on the found cycle.
419 419
    ///
420
    /// \pre \ref run() or \ref findMinMean() must be called before
420
    /// \pre \ref run() or \ref findCycleMean() must be called before
421 421
    /// using this function.
422
    int cycleArcNum() const {
422
    int cycleSize() const {
423 423
      return _best_size;
424 424
    }
425 425

	
426
    /// \brief Return the mean length of the found cycle.
426
    /// \brief Return the mean cost of the found cycle.
427 427
    ///
428
    /// This function returns the mean length of the found cycle.
428
    /// This function returns the mean cost of the found cycle.
429 429
    ///
430 430
    /// \note <tt>alg.cycleMean()</tt> is just a shortcut of the
431 431
    /// following code.
432 432
    /// \code
433
    ///   return static_cast<double>(alg.cycleLength()) / alg.cycleArcNum();
433
    ///   return static_cast<double>(alg.cycleCost()) / alg.cycleSize();
434 434
    /// \endcode
435 435
    ///
436
    /// \pre \ref run() or \ref findMinMean() must be called before
436
    /// \pre \ref run() or \ref findCycleMean() must be called before
437 437
    /// using this function.
438 438
    double cycleMean() const {
439
      return static_cast<double>(_best_length) / _best_size;
439
      return static_cast<double>(_best_cost) / _best_size;
440 440
    }
441 441

	
442 442
    /// \brief Return the found cycle.
443 443
    ///
444 444
    /// This function returns a const reference to the path structure
445 445
    /// storing the found cycle.
446 446
    ///
447 447
    /// \pre \ref run() or \ref findCycle() must be called before using
448 448
    /// this function.
449 449
    const Path& cycle() const {
450 450
      return *_cycle_path;
451 451
    }
452 452

	
453 453
    ///@}
454 454

	
455 455
  private:
456 456

	
457 457
    // Initialization
458 458
    void init() {
459 459
      if (!_cycle_path) {
460 460
        _local_path = true;
461 461
        _cycle_path = new Path;
462 462
      }
463 463
      _cycle_path->clear();
464 464
      _best_found = false;
465
      _best_length = 0;
465
      _best_cost = 0;
466 466
      _best_size = 1;
467 467
      _cycle_path->clear();
468 468
      for (NodeIt u(_gr); u != INVALID; ++u)
469 469
        _data[u].clear();
470 470
    }
471 471

	
472 472
    // Find strongly connected components and initialize _comp_nodes
473 473
    // and _out_arcs
474 474
    void findComponents() {
475 475
      _comp_num = stronglyConnectedComponents(_gr, _comp);
476 476
      _comp_nodes.resize(_comp_num);
477 477
      if (_comp_num == 1) {
478 478
        _comp_nodes[0].clear();
479 479
        for (NodeIt n(_gr); n != INVALID; ++n) {
480 480
          _comp_nodes[0].push_back(n);
481 481
          _out_arcs[n].clear();
482 482
          for (OutArcIt a(_gr, n); a != INVALID; ++a) {
483 483
            _out_arcs[n].push_back(a);
484 484
          }
485 485
        }
486 486
      } else {
487 487
        for (int i = 0; i < _comp_num; ++i)
488 488
          _comp_nodes[i].clear();
489 489
        for (NodeIt n(_gr); n != INVALID; ++n) {
490 490
          int k = _comp[n];
491 491
          _comp_nodes[k].push_back(n);
492 492
          _out_arcs[n].clear();
493 493
          for (OutArcIt a(_gr, n); a != INVALID; ++a) {
494 494
            if (_comp[_gr.target(a)] == k) _out_arcs[n].push_back(a);
495 495
          }
496 496
        }
497 497
      }
498 498
    }
499 499

	
500 500
    // Initialize path data for the current component
501 501
    bool initComponent(int comp) {
502 502
      _nodes = &(_comp_nodes[comp]);
503 503
      int n = _nodes->size();
504 504
      if (n < 1 || (n == 1 && _out_arcs[(*_nodes)[0]].size() == 0)) {
505 505
        return false;
506 506
      }      
507 507
      for (int i = 0; i < n; ++i) {
508 508
        _data[(*_nodes)[i]].resize(n + 1, PathData(INF));
509 509
      }
510 510
      return true;
511 511
    }
512 512

	
513 513
    // Process all rounds of computing path data for the current component.
514
    // _data[v][k] is the length of a shortest directed walk from the root
514
    // _data[v][k] is the cost of a shortest directed walk from the root
515 515
    // node to node v containing exactly k arcs.
516 516
    void processRounds() {
517 517
      Node start = (*_nodes)[0];
518 518
      _data[start][0] = PathData(0);
519 519
      _process.clear();
520 520
      _process.push_back(start);
521 521

	
522 522
      int k, n = _nodes->size();
523 523
      int next_check = 4;
524 524
      bool terminate = false;
525 525
      for (k = 1; k <= n && int(_process.size()) < n && !terminate; ++k) {
526 526
        processNextBuildRound(k);
527 527
        if (k == next_check || k == n) {
528 528
          terminate = checkTermination(k);
529 529
          next_check = next_check * 3 / 2;
530 530
        }
531 531
      }
532 532
      for ( ; k <= n && !terminate; ++k) {
533 533
        processNextFullRound(k);
534 534
        if (k == next_check || k == n) {
535 535
          terminate = checkTermination(k);
536 536
          next_check = next_check * 3 / 2;
537 537
        }
538 538
      }
539 539
    }
540 540

	
541 541
    // Process one round and rebuild _process
542 542
    void processNextBuildRound(int k) {
543 543
      std::vector<Node> next;
544 544
      Node u, v;
545 545
      Arc e;
546
      LargeValue d;
546
      LargeCost d;
547 547
      for (int i = 0; i < int(_process.size()); ++i) {
548 548
        u = _process[i];
549 549
        for (int j = 0; j < int(_out_arcs[u].size()); ++j) {
550 550
          e = _out_arcs[u][j];
551 551
          v = _gr.target(e);
552
          d = _data[u][k-1].dist + _length[e];
552
          d = _data[u][k-1].dist + _cost[e];
553 553
          if (_tolerance.less(d, _data[v][k].dist)) {
554 554
            if (_data[v][k].dist == INF) next.push_back(v);
555 555
            _data[v][k] = PathData(d, e);
556 556
          }
557 557
        }
558 558
      }
559 559
      _process.swap(next);
560 560
    }
561 561

	
562 562
    // Process one round using _nodes instead of _process
563 563
    void processNextFullRound(int k) {
564 564
      Node u, v;
565 565
      Arc e;
566
      LargeValue d;
566
      LargeCost d;
567 567
      for (int i = 0; i < int(_nodes->size()); ++i) {
568 568
        u = (*_nodes)[i];
569 569
        for (int j = 0; j < int(_out_arcs[u].size()); ++j) {
570 570
          e = _out_arcs[u][j];
571 571
          v = _gr.target(e);
572
          d = _data[u][k-1].dist + _length[e];
572
          d = _data[u][k-1].dist + _cost[e];
573 573
          if (_tolerance.less(d, _data[v][k].dist)) {
574 574
            _data[v][k] = PathData(d, e);
575 575
          }
576 576
        }
577 577
      }
578 578
    }
579 579
    
580 580
    // Check early termination
581 581
    bool checkTermination(int k) {
582 582
      typedef std::pair<int, int> Pair;
583 583
      typename GR::template NodeMap<Pair> level(_gr, Pair(-1, 0));
584
      typename GR::template NodeMap<LargeValue> pi(_gr);
584
      typename GR::template NodeMap<LargeCost> pi(_gr);
585 585
      int n = _nodes->size();
586
      LargeValue length;
586
      LargeCost cost;
587 587
      int size;
588 588
      Node u;
589 589
      
590 590
      // Search for cycles that are already found
591 591
      _curr_found = false;
592 592
      for (int i = 0; i < n; ++i) {
593 593
        u = (*_nodes)[i];
594 594
        if (_data[u][k].dist == INF) continue;
595 595
        for (int j = k; j >= 0; --j) {
596 596
          if (level[u].first == i && level[u].second > 0) {
597 597
            // A cycle is found
598
            length = _data[u][level[u].second].dist - _data[u][j].dist;
598
            cost = _data[u][level[u].second].dist - _data[u][j].dist;
599 599
            size = level[u].second - j;
600
            if (!_curr_found || length * _curr_size < _curr_length * size) {
601
              _curr_length = length;
600
            if (!_curr_found || cost * _curr_size < _curr_cost * size) {
601
              _curr_cost = cost;
602 602
              _curr_size = size;
603 603
              _curr_node = u;
604 604
              _curr_level = level[u].second;
605 605
              _curr_found = true;
606 606
            }
607 607
          }
608 608
          level[u] = Pair(i, j);
609 609
          if (j != 0) {
610 610
	    u = _gr.source(_data[u][j].pred);
611 611
	  }
612 612
        }
613 613
      }
614 614

	
615 615
      // If at least one cycle is found, check the optimality condition
616
      LargeValue d;
616
      LargeCost d;
617 617
      if (_curr_found && k < n) {
618 618
        // Find node potentials
619 619
        for (int i = 0; i < n; ++i) {
620 620
          u = (*_nodes)[i];
621 621
          pi[u] = INF;
622 622
          for (int j = 0; j <= k; ++j) {
623 623
            if (_data[u][j].dist < INF) {
624
              d = _data[u][j].dist * _curr_size - j * _curr_length;
624
              d = _data[u][j].dist * _curr_size - j * _curr_cost;
625 625
              if (_tolerance.less(d, pi[u])) pi[u] = d;
626 626
            }
627 627
          }
628 628
        }
629 629

	
630 630
        // Check the optimality condition for all arcs
631 631
        bool done = true;
632 632
        for (ArcIt a(_gr); a != INVALID; ++a) {
633
          if (_tolerance.less(_length[a] * _curr_size - _curr_length,
633
          if (_tolerance.less(_cost[a] * _curr_size - _curr_cost,
634 634
                              pi[_gr.target(a)] - pi[_gr.source(a)]) ) {
635 635
            done = false;
636 636
            break;
637 637
          }
638 638
        }
639 639
        return done;
640 640
      }
641 641
      return (k == n);
642 642
    }
643 643

	
644
  }; //class HartmannOrlin
644
  }; //class HartmannOrlinMmc
645 645

	
646 646
  ///@}
647 647

	
648 648
} //namespace lemon
649 649

	
650
#endif //LEMON_HARTMANN_ORLIN_H
650
#endif //LEMON_HARTMANN_ORLIN_MMC_H
Ignore white space 6 line context
1 1
/* -*- C++ -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library
4 4
 *
5 5
 * Copyright (C) 2003-2008
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19
#ifndef LEMON_HOWARD_H
20
#define LEMON_HOWARD_H
19
#ifndef LEMON_HOWARD_MMC_H
20
#define LEMON_HOWARD_MMC_H
21 21

	
22 22
/// \ingroup min_mean_cycle
23 23
///
24 24
/// \file
25 25
/// \brief Howard's algorithm for finding a minimum mean cycle.
26 26

	
27 27
#include <vector>
28 28
#include <limits>
29 29
#include <lemon/core.h>
30 30
#include <lemon/path.h>
31 31
#include <lemon/tolerance.h>
32 32
#include <lemon/connectivity.h>
33 33

	
34 34
namespace lemon {
35 35

	
36
  /// \brief Default traits class of Howard class.
36
  /// \brief Default traits class of HowardMmc class.
37 37
  ///
38
  /// Default traits class of Howard class.
38
  /// Default traits class of HowardMmc class.
39 39
  /// \tparam GR The type of the digraph.
40
  /// \tparam LEN The type of the length map.
40
  /// \tparam CM The type of the cost map.
41 41
  /// It must conform to the \ref concepts::ReadMap "ReadMap" concept.
42 42
#ifdef DOXYGEN
43
  template <typename GR, typename LEN>
43
  template <typename GR, typename CM>
44 44
#else
45
  template <typename GR, typename LEN,
46
    bool integer = std::numeric_limits<typename LEN::Value>::is_integer>
45
  template <typename GR, typename CM,
46
    bool integer = std::numeric_limits<typename CM::Value>::is_integer>
47 47
#endif
48
  struct HowardDefaultTraits
48
  struct HowardMmcDefaultTraits
49 49
  {
50 50
    /// The type of the digraph
51 51
    typedef GR Digraph;
52
    /// The type of the length map
53
    typedef LEN LengthMap;
54
    /// The type of the arc lengths
55
    typedef typename LengthMap::Value Value;
52
    /// The type of the cost map
53
    typedef CM CostMap;
54
    /// The type of the arc costs
55
    typedef typename CostMap::Value Cost;
56 56

	
57
    /// \brief The large value type used for internal computations
57
    /// \brief The large cost type used for internal computations
58 58
    ///
59
    /// The large value type used for internal computations.
60
    /// It is \c long \c long if the \c Value type is integer,
59
    /// The large cost type used for internal computations.
60
    /// It is \c long \c long if the \c Cost type is integer,
61 61
    /// otherwise it is \c double.
62
    /// \c Value must be convertible to \c LargeValue.
63
    typedef double LargeValue;
62
    /// \c Cost must be convertible to \c LargeCost.
63
    typedef double LargeCost;
64 64

	
65 65
    /// The tolerance type used for internal computations
66
    typedef lemon::Tolerance<LargeValue> Tolerance;
66
    typedef lemon::Tolerance<LargeCost> Tolerance;
67 67

	
68 68
    /// \brief The path type of the found cycles
69 69
    ///
70 70
    /// The path type of the found cycles.
71 71
    /// It must conform to the \ref lemon::concepts::Path "Path" concept
72 72
    /// and it must have an \c addBack() function.
73 73
    typedef lemon::Path<Digraph> Path;
74 74
  };
75 75

	
76
  // Default traits class for integer value types
77
  template <typename GR, typename LEN>
78
  struct HowardDefaultTraits<GR, LEN, true>
76
  // Default traits class for integer cost types
77
  template <typename GR, typename CM>
78
  struct HowardMmcDefaultTraits<GR, CM, true>
79 79
  {
80 80
    typedef GR Digraph;
81
    typedef LEN LengthMap;
82
    typedef typename LengthMap::Value Value;
81
    typedef CM CostMap;
82
    typedef typename CostMap::Value Cost;
83 83
#ifdef LEMON_HAVE_LONG_LONG
84
    typedef long long LargeValue;
84
    typedef long long LargeCost;
85 85
#else
86
    typedef long LargeValue;
86
    typedef long LargeCost;
87 87
#endif
88
    typedef lemon::Tolerance<LargeValue> Tolerance;
88
    typedef lemon::Tolerance<LargeCost> Tolerance;
89 89
    typedef lemon::Path<Digraph> Path;
90 90
  };
91 91

	
92 92

	
93 93
  /// \addtogroup min_mean_cycle
94 94
  /// @{
95 95

	
96 96
  /// \brief Implementation of Howard's algorithm for finding a minimum
97 97
  /// mean cycle.
98 98
  ///
99 99
  /// This class implements Howard's policy iteration algorithm for finding
100
  /// a directed cycle of minimum mean length (cost) in a digraph
100
  /// a directed cycle of minimum mean cost in a digraph
101 101
  /// \ref amo93networkflows, \ref dasdan98minmeancycle.
102 102
  /// This class provides the most efficient algorithm for the
103 103
  /// minimum mean cycle problem, though the best known theoretical
104 104
  /// bound on its running time is exponential.
105 105
  ///
106 106
  /// \tparam GR The type of the digraph the algorithm runs on.
107
  /// \tparam LEN The type of the length map. The default
107
  /// \tparam CM The type of the cost map. The default
108 108
  /// map type is \ref concepts::Digraph::ArcMap "GR::ArcMap<int>".
109 109
  /// \tparam TR The traits class that defines various types used by the
110
  /// algorithm. By default, it is \ref HowardDefaultTraits
111
  /// "HowardDefaultTraits<GR, LEN>".
110
  /// algorithm. By default, it is \ref HowardMmcDefaultTraits
111
  /// "HowardMmcDefaultTraits<GR, CM>".
112 112
  /// In most cases, this parameter should not be set directly,
113 113
  /// consider to use the named template parameters instead.
114 114
#ifdef DOXYGEN
115
  template <typename GR, typename LEN, typename TR>
115
  template <typename GR, typename CM, typename TR>
116 116
#else
117 117
  template < typename GR,
118
             typename LEN = typename GR::template ArcMap<int>,
119
             typename TR = HowardDefaultTraits<GR, LEN> >
118
             typename CM = typename GR::template ArcMap<int>,
119
             typename TR = HowardMmcDefaultTraits<GR, CM> >
120 120
#endif
121
  class Howard
121
  class HowardMmc
122 122
  {
123 123
  public:
124 124
  
125 125
    /// The type of the digraph
126 126
    typedef typename TR::Digraph Digraph;
127
    /// The type of the length map
128
    typedef typename TR::LengthMap LengthMap;
129
    /// The type of the arc lengths
130
    typedef typename TR::Value Value;
127
    /// The type of the cost map
128
    typedef typename TR::CostMap CostMap;
129
    /// The type of the arc costs
130
    typedef typename TR::Cost Cost;
131 131

	
132
    /// \brief The large value type
132
    /// \brief The large cost type
133 133
    ///
134
    /// The large value type used for internal computations.
135
    /// By default, it is \c long \c long if the \c Value type is integer,
134
    /// The large cost type used for internal computations.
135
    /// By default, it is \c long \c long if the \c Cost type is integer,
136 136
    /// otherwise it is \c double.
137
    typedef typename TR::LargeValue LargeValue;
137
    typedef typename TR::LargeCost LargeCost;
138 138

	
139 139
    /// The tolerance type
140 140
    typedef typename TR::Tolerance Tolerance;
141 141

	
142 142
    /// \brief The path type of the found cycles
143 143
    ///
144 144
    /// The path type of the found cycles.
145
    /// Using the \ref HowardDefaultTraits "default traits class",
145
    /// Using the \ref HowardMmcDefaultTraits "default traits class",
146 146
    /// it is \ref lemon::Path "Path<Digraph>".
147 147
    typedef typename TR::Path Path;
148 148

	
149
    /// The \ref HowardDefaultTraits "traits class" of the algorithm
149
    /// The \ref HowardMmcDefaultTraits "traits class" of the algorithm
150 150
    typedef TR Traits;
151 151

	
152 152
  private:
153 153

	
154 154
    TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
155 155
  
156 156
    // The digraph the algorithm runs on
157 157
    const Digraph &_gr;
158
    // The length of the arcs
159
    const LengthMap &_length;
158
    // The cost of the arcs
159
    const CostMap &_cost;
160 160

	
161 161
    // Data for the found cycles
162 162
    bool _curr_found, _best_found;
163
    LargeValue _curr_length, _best_length;
163
    LargeCost _curr_cost, _best_cost;
164 164
    int _curr_size, _best_size;
165 165
    Node _curr_node, _best_node;
166 166

	
167 167
    Path *_cycle_path;
168 168
    bool _local_path;
169 169

	
170 170
    // Internal data used by the algorithm
171 171
    typename Digraph::template NodeMap<Arc> _policy;
172 172
    typename Digraph::template NodeMap<bool> _reached;
173 173
    typename Digraph::template NodeMap<int> _level;
174
    typename Digraph::template NodeMap<LargeValue> _dist;
174
    typename Digraph::template NodeMap<LargeCost> _dist;
175 175

	
176 176
    // Data for storing the strongly connected components
177 177
    int _comp_num;
178 178
    typename Digraph::template NodeMap<int> _comp;
179 179
    std::vector<std::vector<Node> > _comp_nodes;
180 180
    std::vector<Node>* _nodes;
181 181
    typename Digraph::template NodeMap<std::vector<Arc> > _in_arcs;
182 182
    
183 183
    // Queue used for BFS search
184 184
    std::vector<Node> _queue;
185 185
    int _qfront, _qback;
186 186

	
187 187
    Tolerance _tolerance;
188 188
  
189 189
    // Infinite constant
190
    const LargeValue INF;
190
    const LargeCost INF;
191 191

	
192 192
  public:
193 193
  
194 194
    /// \name Named Template Parameters
195 195
    /// @{
196 196

	
197 197
    template <typename T>
198
    struct SetLargeValueTraits : public Traits {
199
      typedef T LargeValue;
198
    struct SetLargeCostTraits : public Traits {
199
      typedef T LargeCost;
200 200
      typedef lemon::Tolerance<T> Tolerance;
201 201
    };
202 202

	
203 203
    /// \brief \ref named-templ-param "Named parameter" for setting
204
    /// \c LargeValue type.
204
    /// \c LargeCost type.
205 205
    ///
206
    /// \ref named-templ-param "Named parameter" for setting \c LargeValue
206
    /// \ref named-templ-param "Named parameter" for setting \c LargeCost
207 207
    /// type. It is used for internal computations in the algorithm.
208 208
    template <typename T>
209
    struct SetLargeValue
210
      : public Howard<GR, LEN, SetLargeValueTraits<T> > {
211
      typedef Howard<GR, LEN, SetLargeValueTraits<T> > Create;
209
    struct SetLargeCost
210
      : public HowardMmc<GR, CM, SetLargeCostTraits<T> > {
211
      typedef HowardMmc<GR, CM, SetLargeCostTraits<T> > Create;
212 212
    };
213 213

	
214 214
    template <typename T>
215 215
    struct SetPathTraits : public Traits {
216 216
      typedef T Path;
217 217
    };
218 218

	
219 219
    /// \brief \ref named-templ-param "Named parameter" for setting
220 220
    /// \c %Path type.
221 221
    ///
222 222
    /// \ref named-templ-param "Named parameter" for setting the \c %Path
223 223
    /// type of the found cycles.
224 224
    /// It must conform to the \ref lemon::concepts::Path "Path" concept
225 225
    /// and it must have an \c addBack() function.
226 226
    template <typename T>
227 227
    struct SetPath
228
      : public Howard<GR, LEN, SetPathTraits<T> > {
229
      typedef Howard<GR, LEN, SetPathTraits<T> > Create;
228
      : public HowardMmc<GR, CM, SetPathTraits<T> > {
229
      typedef HowardMmc<GR, CM, SetPathTraits<T> > Create;
230 230
    };
231 231
    
232 232
    /// @}
233 233

	
234 234
  protected:
235 235

	
236
    Howard() {}
236
    HowardMmc() {}
237 237

	
238 238
  public:
239 239

	
240 240
    /// \brief Constructor.
241 241
    ///
242 242
    /// The constructor of the class.
243 243
    ///
244 244
    /// \param digraph The digraph the algorithm runs on.
245
    /// \param length The lengths (costs) of the arcs.
246
    Howard( const Digraph &digraph,
247
            const LengthMap &length ) :
248
      _gr(digraph), _length(length), _best_found(false),
249
      _best_length(0), _best_size(1), _cycle_path(NULL), _local_path(false),
245
    /// \param cost The costs of the arcs.
246
    HowardMmc( const Digraph &digraph,
247
               const CostMap &cost ) :
248
      _gr(digraph), _cost(cost), _best_found(false),
249
      _best_cost(0), _best_size(1), _cycle_path(NULL), _local_path(false),
250 250
      _policy(digraph), _reached(digraph), _level(digraph), _dist(digraph),
251 251
      _comp(digraph), _in_arcs(digraph),
252
      INF(std::numeric_limits<LargeValue>::has_infinity ?
253
          std::numeric_limits<LargeValue>::infinity() :
254
          std::numeric_limits<LargeValue>::max())
252
      INF(std::numeric_limits<LargeCost>::has_infinity ?
253
          std::numeric_limits<LargeCost>::infinity() :
254
          std::numeric_limits<LargeCost>::max())
255 255
    {}
256 256

	
257 257
    /// Destructor.
258
    ~Howard() {
258
    ~HowardMmc() {
259 259
      if (_local_path) delete _cycle_path;
260 260
    }
261 261

	
262 262
    /// \brief Set the path structure for storing the found cycle.
263 263
    ///
264 264
    /// This function sets an external path structure for storing the
265 265
    /// found cycle.
266 266
    ///
267 267
    /// If you don't call this function before calling \ref run() or
268
    /// \ref findMinMean(), it will allocate a local \ref Path "path"
268
    /// \ref findCycleMean(), it will allocate a local \ref Path "path"
269 269
    /// structure. The destuctor deallocates this automatically
270 270
    /// allocated object, of course.
271 271
    ///
272 272
    /// \note The algorithm calls only the \ref lemon::Path::addBack()
273 273
    /// "addBack()" function of the given path structure.
274 274
    ///
275 275
    /// \return <tt>(*this)</tt>
276
    Howard& cycle(Path &path) {
276
    HowardMmc& cycle(Path &path) {
277 277
      if (_local_path) {
278 278
        delete _cycle_path;
279 279
        _local_path = false;
280 280
      }
281 281
      _cycle_path = &path;
282 282
      return *this;
283 283
    }
284 284

	
285 285
    /// \brief Set the tolerance used by the algorithm.
286 286
    ///
287 287
    /// This function sets the tolerance object used by the algorithm.
288 288
    ///
289 289
    /// \return <tt>(*this)</tt>
290
    Howard& tolerance(const Tolerance& tolerance) {
290
    HowardMmc& tolerance(const Tolerance& tolerance) {
291 291
      _tolerance = tolerance;
292 292
      return *this;
293 293
    }
294 294

	
295 295
    /// \brief Return a const reference to the tolerance.
296 296
    ///
297 297
    /// This function returns a const reference to the tolerance object
298 298
    /// used by the algorithm.
299 299
    const Tolerance& tolerance() const {
300 300
      return _tolerance;
301 301
    }
302 302

	
303 303
    /// \name Execution control
304 304
    /// The simplest way to execute the algorithm is to call the \ref run()
305 305
    /// function.\n
306
    /// If you only need the minimum mean length, you may call
307
    /// \ref findMinMean().
306
    /// If you only need the minimum mean cost, you may call
307
    /// \ref findCycleMean().
308 308

	
309 309
    /// @{
310 310

	
311 311
    /// \brief Run the algorithm.
312 312
    ///
313 313
    /// This function runs the algorithm.
314 314
    /// It can be called more than once (e.g. if the underlying digraph
315
    /// and/or the arc lengths have been modified).
315
    /// and/or the arc costs have been modified).
316 316
    ///
317 317
    /// \return \c true if a directed cycle exists in the digraph.
318 318
    ///
319 319
    /// \note <tt>mmc.run()</tt> is just a shortcut of the following code.
320 320
    /// \code
321
    ///   return mmc.findMinMean() && mmc.findCycle();
321
    ///   return mmc.findCycleMean() && mmc.findCycle();
322 322
    /// \endcode
323 323
    bool run() {
324
      return findMinMean() && findCycle();
324
      return findCycleMean() && findCycle();
325 325
    }
326 326

	
327 327
    /// \brief Find the minimum cycle mean.
328 328
    ///
329
    /// This function finds the minimum mean length of the directed
329
    /// This function finds the minimum mean cost of the directed
330 330
    /// cycles in the digraph.
331 331
    ///
332 332
    /// \return \c true if a directed cycle exists in the digraph.
333
    bool findMinMean() {
333
    bool findCycleMean() {
334 334
      // Initialize and find strongly connected components
335 335
      init();
336 336
      findComponents();
337 337
      
338 338
      // Find the minimum cycle mean in the components
339 339
      for (int comp = 0; comp < _comp_num; ++comp) {
340 340
        // Find the minimum mean cycle in the current component
341 341
        if (!buildPolicyGraph(comp)) continue;
342 342
        while (true) {
343 343
          findPolicyCycle();
344 344
          if (!computeNodeDistances()) break;
345 345
        }
346 346
        // Update the best cycle (global minimum mean cycle)
347 347
        if ( _curr_found && (!_best_found ||
348
             _curr_length * _best_size < _best_length * _curr_size) ) {
348
             _curr_cost * _best_size < _best_cost * _curr_size) ) {
349 349
          _best_found = true;
350
          _best_length = _curr_length;
350
          _best_cost = _curr_cost;
351 351
          _best_size = _curr_size;
352 352
          _best_node = _curr_node;
353 353
        }
354 354
      }
355 355
      return _best_found;
356 356
    }
357 357

	
358 358
    /// \brief Find a minimum mean directed cycle.
359 359
    ///
360
    /// This function finds a directed cycle of minimum mean length
361
    /// in the digraph using the data computed by findMinMean().
360
    /// This function finds a directed cycle of minimum mean cost
361
    /// in the digraph using the data computed by findCycleMean().
362 362
    ///
363 363
    /// \return \c true if a directed cycle exists in the digraph.
364 364
    ///
365
    /// \pre \ref findMinMean() must be called before using this function.
365
    /// \pre \ref findCycleMean() must be called before using this function.
366 366
    bool findCycle() {
367 367
      if (!_best_found) return false;
368 368
      _cycle_path->addBack(_policy[_best_node]);
369 369
      for ( Node v = _best_node;
370 370
            (v = _gr.target(_policy[v])) != _best_node; ) {
371 371
        _cycle_path->addBack(_policy[v]);
372 372
      }
373 373
      return true;
374 374
    }
375 375

	
376 376
    /// @}
377 377

	
378 378
    /// \name Query Functions
379 379
    /// The results of the algorithm can be obtained using these
380 380
    /// functions.\n
381 381
    /// The algorithm should be executed before using them.
382 382

	
383 383
    /// @{
384 384

	
385
    /// \brief Return the total length of the found cycle.
385
    /// \brief Return the total cost of the found cycle.
386 386
    ///
387
    /// This function returns the total length of the found cycle.
387
    /// This function returns the total cost of the found cycle.
388 388
    ///
389
    /// \pre \ref run() or \ref findMinMean() must be called before
389
    /// \pre \ref run() or \ref findCycleMean() must be called before
390 390
    /// using this function.
391
    Value cycleLength() const {
392
      return static_cast<Value>(_best_length);
391
    Cost cycleCost() const {
392
      return static_cast<Cost>(_best_cost);
393 393
    }
394 394

	
395 395
    /// \brief Return the number of arcs on the found cycle.
396 396
    ///
397 397
    /// This function returns the number of arcs on the found cycle.
398 398
    ///
399
    /// \pre \ref run() or \ref findMinMean() must be called before
399
    /// \pre \ref run() or \ref findCycleMean() must be called before
400 400
    /// using this function.
401
    int cycleArcNum() const {
401
    int cycleSize() const {
402 402
      return _best_size;
403 403
    }
404 404

	
405
    /// \brief Return the mean length of the found cycle.
405
    /// \brief Return the mean cost of the found cycle.
406 406
    ///
407
    /// This function returns the mean length of the found cycle.
407
    /// This function returns the mean cost of the found cycle.
408 408
    ///
409 409
    /// \note <tt>alg.cycleMean()</tt> is just a shortcut of the
410 410
    /// following code.
411 411
    /// \code
412
    ///   return static_cast<double>(alg.cycleLength()) / alg.cycleArcNum();
412
    ///   return static_cast<double>(alg.cycleCost()) / alg.cycleSize();
413 413
    /// \endcode
414 414
    ///
415
    /// \pre \ref run() or \ref findMinMean() must be called before
415
    /// \pre \ref run() or \ref findCycleMean() must be called before
416 416
    /// using this function.
417 417
    double cycleMean() const {
418
      return static_cast<double>(_best_length) / _best_size;
418
      return static_cast<double>(_best_cost) / _best_size;
419 419
    }
420 420

	
421 421
    /// \brief Return the found cycle.
422 422
    ///
423 423
    /// This function returns a const reference to the path structure
424 424
    /// storing the found cycle.
425 425
    ///
426 426
    /// \pre \ref run() or \ref findCycle() must be called before using
427 427
    /// this function.
428 428
    const Path& cycle() const {
429 429
      return *_cycle_path;
430 430
    }
431 431

	
432 432
    ///@}
433 433

	
434 434
  private:
435 435

	
436 436
    // Initialize
437 437
    void init() {
438 438
      if (!_cycle_path) {
439 439
        _local_path = true;
440 440
        _cycle_path = new Path;
441 441
      }
442 442
      _queue.resize(countNodes(_gr));
443 443
      _best_found = false;
444
      _best_length = 0;
444
      _best_cost = 0;
445 445
      _best_size = 1;
446 446
      _cycle_path->clear();
447 447
    }
448 448
    
449 449
    // Find strongly connected components and initialize _comp_nodes
450 450
    // and _in_arcs
451 451
    void findComponents() {
452 452
      _comp_num = stronglyConnectedComponents(_gr, _comp);
453 453
      _comp_nodes.resize(_comp_num);
454 454
      if (_comp_num == 1) {
455 455
        _comp_nodes[0].clear();
456 456
        for (NodeIt n(_gr); n != INVALID; ++n) {
457 457
          _comp_nodes[0].push_back(n);
458 458
          _in_arcs[n].clear();
459 459
          for (InArcIt a(_gr, n); a != INVALID; ++a) {
460 460
            _in_arcs[n].push_back(a);
461 461
          }
462 462
        }
463 463
      } else {
464 464
        for (int i = 0; i < _comp_num; ++i)
465 465
          _comp_nodes[i].clear();
466 466
        for (NodeIt n(_gr); n != INVALID; ++n) {
467 467
          int k = _comp[n];
468 468
          _comp_nodes[k].push_back(n);
469 469
          _in_arcs[n].clear();
470 470
          for (InArcIt a(_gr, n); a != INVALID; ++a) {
471 471
            if (_comp[_gr.source(a)] == k) _in_arcs[n].push_back(a);
472 472
          }
473 473
        }
474 474
      }
475 475
    }
476 476

	
477 477
    // Build the policy graph in the given strongly connected component
478 478
    // (the out-degree of every node is 1)
479 479
    bool buildPolicyGraph(int comp) {
480 480
      _nodes = &(_comp_nodes[comp]);
481 481
      if (_nodes->size() < 1 ||
482 482
          (_nodes->size() == 1 && _in_arcs[(*_nodes)[0]].size() == 0)) {
483 483
        return false;
484 484
      }
485 485
      for (int i = 0; i < int(_nodes->size()); ++i) {
486 486
        _dist[(*_nodes)[i]] = INF;
487 487
      }
488 488
      Node u, v;
489 489
      Arc e;
490 490
      for (int i = 0; i < int(_nodes->size()); ++i) {
491 491
        v = (*_nodes)[i];
492 492
        for (int j = 0; j < int(_in_arcs[v].size()); ++j) {
493 493
          e = _in_arcs[v][j];
494 494
          u = _gr.source(e);
495
          if (_length[e] < _dist[u]) {
496
            _dist[u] = _length[e];
495
          if (_cost[e] < _dist[u]) {
496
            _dist[u] = _cost[e];
497 497
            _policy[u] = e;
498 498
          }
499 499
        }
500 500
      }
501 501
      return true;
502 502
    }
503 503

	
504 504
    // Find the minimum mean cycle in the policy graph
505 505
    void findPolicyCycle() {
506 506
      for (int i = 0; i < int(_nodes->size()); ++i) {
507 507
        _level[(*_nodes)[i]] = -1;
508 508
      }
509
      LargeValue clength;
509
      LargeCost ccost;
510 510
      int csize;
511 511
      Node u, v;
512 512
      _curr_found = false;
513 513
      for (int i = 0; i < int(_nodes->size()); ++i) {
514 514
        u = (*_nodes)[i];
515 515
        if (_level[u] >= 0) continue;
516 516
        for (; _level[u] < 0; u = _gr.target(_policy[u])) {
517 517
          _level[u] = i;
518 518
        }
519 519
        if (_level[u] == i) {
520 520
          // A cycle is found
521
          clength = _length[_policy[u]];
521
          ccost = _cost[_policy[u]];
522 522
          csize = 1;
523 523
          for (v = u; (v = _gr.target(_policy[v])) != u; ) {
524
            clength += _length[_policy[v]];
524
            ccost += _cost[_policy[v]];
525 525
            ++csize;
526 526
          }
527 527
          if ( !_curr_found ||
528
               (clength * _curr_size < _curr_length * csize) ) {
528
               (ccost * _curr_size < _curr_cost * csize) ) {
529 529
            _curr_found = true;
530
            _curr_length = clength;
530
            _curr_cost = ccost;
531 531
            _curr_size = csize;
532 532
            _curr_node = u;
533 533
          }
534 534
        }
535 535
      }
536 536
    }
537 537

	
538 538
    // Contract the policy graph and compute node distances
539 539
    bool computeNodeDistances() {
540 540
      // Find the component of the main cycle and compute node distances
541 541
      // using reverse BFS
542 542
      for (int i = 0; i < int(_nodes->size()); ++i) {
543 543
        _reached[(*_nodes)[i]] = false;
544 544
      }
545 545
      _qfront = _qback = 0;
546 546
      _queue[0] = _curr_node;
547 547
      _reached[_curr_node] = true;
548 548
      _dist[_curr_node] = 0;
549 549
      Node u, v;
550 550
      Arc e;
551 551
      while (_qfront <= _qback) {
552 552
        v = _queue[_qfront++];
553 553
        for (int j = 0; j < int(_in_arcs[v].size()); ++j) {
554 554
          e = _in_arcs[v][j];
555 555
          u = _gr.source(e);
556 556
          if (_policy[u] == e && !_reached[u]) {
557 557
            _reached[u] = true;
558
            _dist[u] = _dist[v] + _length[e] * _curr_size - _curr_length;
558
            _dist[u] = _dist[v] + _cost[e] * _curr_size - _curr_cost;
559 559
            _queue[++_qback] = u;
560 560
          }
561 561
        }
562 562
      }
563 563

	
564 564
      // Connect all other nodes to this component and compute node
565 565
      // distances using reverse BFS
566 566
      _qfront = 0;
567 567
      while (_qback < int(_nodes->size())-1) {
568 568
        v = _queue[_qfront++];
569 569
        for (int j = 0; j < int(_in_arcs[v].size()); ++j) {
570 570
          e = _in_arcs[v][j];
571 571
          u = _gr.source(e);
572 572
          if (!_reached[u]) {
573 573
            _reached[u] = true;
574 574
            _policy[u] = e;
575
            _dist[u] = _dist[v] + _length[e] * _curr_size - _curr_length;
575
            _dist[u] = _dist[v] + _cost[e] * _curr_size - _curr_cost;
576 576
            _queue[++_qback] = u;
577 577
          }
578 578
        }
579 579
      }
580 580

	
581 581
      // Improve node distances
582 582
      bool improved = false;
583 583
      for (int i = 0; i < int(_nodes->size()); ++i) {
584 584
        v = (*_nodes)[i];
585 585
        for (int j = 0; j < int(_in_arcs[v].size()); ++j) {
586 586
          e = _in_arcs[v][j];
587 587
          u = _gr.source(e);
588
          LargeValue delta = _dist[v] + _length[e] * _curr_size - _curr_length;
588
          LargeCost delta = _dist[v] + _cost[e] * _curr_size - _curr_cost;
589 589
          if (_tolerance.less(delta, _dist[u])) {
590 590
            _dist[u] = delta;
591 591
            _policy[u] = e;
592 592
            improved = true;
593 593
          }
594 594
        }
595 595
      }
596 596
      return improved;
597 597
    }
598 598

	
599
  }; //class Howard
599
  }; //class HowardMmc
600 600

	
601 601
  ///@}
602 602

	
603 603
} //namespace lemon
604 604

	
605
#endif //LEMON_HOWARD_H
605
#endif //LEMON_HOWARD_MMC_H
Ignore white space 6 line context
1 1
/* -*- C++ -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library
4 4
 *
5 5
 * Copyright (C) 2003-2008
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19
#ifndef LEMON_KARP_H
20
#define LEMON_KARP_H
19
#ifndef LEMON_KARP_MMC_H
20
#define LEMON_KARP_MMC_H
21 21

	
22 22
/// \ingroup min_mean_cycle
23 23
///
24 24
/// \file
25 25
/// \brief Karp's algorithm for finding a minimum mean cycle.
26 26

	
27 27
#include <vector>
28 28
#include <limits>
29 29
#include <lemon/core.h>
30 30
#include <lemon/path.h>
31 31
#include <lemon/tolerance.h>
32 32
#include <lemon/connectivity.h>
33 33

	
34 34
namespace lemon {
35 35

	
36
  /// \brief Default traits class of Karp algorithm.
36
  /// \brief Default traits class of KarpMmc class.
37 37
  ///
38
  /// Default traits class of Karp algorithm.
38
  /// Default traits class of KarpMmc class.
39 39
  /// \tparam GR The type of the digraph.
40
  /// \tparam LEN The type of the length map.
40
  /// \tparam CM The type of the cost map.
41 41
  /// It must conform to the \ref concepts::ReadMap "ReadMap" concept.
42 42
#ifdef DOXYGEN
43
  template <typename GR, typename LEN>
43
  template <typename GR, typename CM>
44 44
#else
45
  template <typename GR, typename LEN,
46
    bool integer = std::numeric_limits<typename LEN::Value>::is_integer>
45
  template <typename GR, typename CM,
46
    bool integer = std::numeric_limits<typename CM::Value>::is_integer>
47 47
#endif
48
  struct KarpDefaultTraits
48
  struct KarpMmcDefaultTraits
49 49
  {
50 50
    /// The type of the digraph
51 51
    typedef GR Digraph;
52
    /// The type of the length map
53
    typedef LEN LengthMap;
54
    /// The type of the arc lengths
55
    typedef typename LengthMap::Value Value;
52
    /// The type of the cost map
53
    typedef CM CostMap;
54
    /// The type of the arc costs
55
    typedef typename CostMap::Value Cost;
56 56

	
57
    /// \brief The large value type used for internal computations
57
    /// \brief The large cost type used for internal computations
58 58
    ///
59
    /// The large value type used for internal computations.
60
    /// It is \c long \c long if the \c Value type is integer,
59
    /// The large cost type used for internal computations.
60
    /// It is \c long \c long if the \c Cost type is integer,
61 61
    /// otherwise it is \c double.
62
    /// \c Value must be convertible to \c LargeValue.
63
    typedef double LargeValue;
62
    /// \c Cost must be convertible to \c LargeCost.
63
    typedef double LargeCost;
64 64

	
65 65
    /// The tolerance type used for internal computations
66
    typedef lemon::Tolerance<LargeValue> Tolerance;
66
    typedef lemon::Tolerance<LargeCost> Tolerance;
67 67

	
68 68
    /// \brief The path type of the found cycles
69 69
    ///
70 70
    /// The path type of the found cycles.
71 71
    /// It must conform to the \ref lemon::concepts::Path "Path" concept
72 72
    /// and it must have an \c addFront() function.
73 73
    typedef lemon::Path<Digraph> Path;
74 74
  };
75 75

	
76
  // Default traits class for integer value types
77
  template <typename GR, typename LEN>
78
  struct KarpDefaultTraits<GR, LEN, true>
76
  // Default traits class for integer cost types
77
  template <typename GR, typename CM>
78
  struct KarpMmcDefaultTraits<GR, CM, true>
79 79
  {
80 80
    typedef GR Digraph;
81
    typedef LEN LengthMap;
82
    typedef typename LengthMap::Value Value;
81
    typedef CM CostMap;
82
    typedef typename CostMap::Value Cost;
83 83
#ifdef LEMON_HAVE_LONG_LONG
84
    typedef long long LargeValue;
84
    typedef long long LargeCost;
85 85
#else
86
    typedef long LargeValue;
86
    typedef long LargeCost;
87 87
#endif
88
    typedef lemon::Tolerance<LargeValue> Tolerance;
88
    typedef lemon::Tolerance<LargeCost> Tolerance;
89 89
    typedef lemon::Path<Digraph> Path;
90 90
  };
91 91

	
92 92

	
93 93
  /// \addtogroup min_mean_cycle
94 94
  /// @{
95 95

	
96 96
  /// \brief Implementation of Karp's algorithm for finding a minimum
97 97
  /// mean cycle.
98 98
  ///
99 99
  /// This class implements Karp's algorithm for finding a directed
100
  /// cycle of minimum mean length (cost) in a digraph
100
  /// cycle of minimum mean cost in a digraph
101 101
  /// \ref amo93networkflows, \ref dasdan98minmeancycle.
102 102
  /// It runs in time O(ne) and uses space O(n<sup>2</sup>+e).
103 103
  ///
104 104
  /// \tparam GR The type of the digraph the algorithm runs on.
105
  /// \tparam LEN The type of the length map. The default
105
  /// \tparam CM The type of the cost map. The default
106 106
  /// map type is \ref concepts::Digraph::ArcMap "GR::ArcMap<int>".
107 107
  /// \tparam TR The traits class that defines various types used by the
108
  /// algorithm. By default, it is \ref KarpDefaultTraits
109
  /// "KarpDefaultTraits<GR, LEN>".
108
  /// algorithm. By default, it is \ref KarpMmcDefaultTraits
109
  /// "KarpMmcDefaultTraits<GR, CM>".
110 110
  /// In most cases, this parameter should not be set directly,
111 111
  /// consider to use the named template parameters instead.
112 112
#ifdef DOXYGEN
113
  template <typename GR, typename LEN, typename TR>
113
  template <typename GR, typename CM, typename TR>
114 114
#else
115 115
  template < typename GR,
116
             typename LEN = typename GR::template ArcMap<int>,
117
             typename TR = KarpDefaultTraits<GR, LEN> >
116
             typename CM = typename GR::template ArcMap<int>,
117
             typename TR = KarpMmcDefaultTraits<GR, CM> >
118 118
#endif
119
  class Karp
119
  class KarpMmc
120 120
  {
121 121
  public:
122 122

	
123 123
    /// The type of the digraph
124 124
    typedef typename TR::Digraph Digraph;
125
    /// The type of the length map
126
    typedef typename TR::LengthMap LengthMap;
127
    /// The type of the arc lengths
128
    typedef typename TR::Value Value;
125
    /// The type of the cost map
126
    typedef typename TR::CostMap CostMap;
127
    /// The type of the arc costs
128
    typedef typename TR::Cost Cost;
129 129

	
130
    /// \brief The large value type
130
    /// \brief The large cost type
131 131
    ///
132
    /// The large value type used for internal computations.
133
    /// By default, it is \c long \c long if the \c Value type is integer,
132
    /// The large cost type used for internal computations.
133
    /// By default, it is \c long \c long if the \c Cost type is integer,
134 134
    /// otherwise it is \c double.
135
    typedef typename TR::LargeValue LargeValue;
135
    typedef typename TR::LargeCost LargeCost;
136 136

	
137 137
    /// The tolerance type
138 138
    typedef typename TR::Tolerance Tolerance;
139 139

	
140 140
    /// \brief The path type of the found cycles
141 141
    ///
142 142
    /// The path type of the found cycles.
143
    /// Using the \ref KarpDefaultTraits "default traits class",
143
    /// Using the \ref KarpMmcDefaultTraits "default traits class",
144 144
    /// it is \ref lemon::Path "Path<Digraph>".
145 145
    typedef typename TR::Path Path;
146 146

	
147
    /// The \ref KarpDefaultTraits "traits class" of the algorithm
147
    /// The \ref KarpMmcDefaultTraits "traits class" of the algorithm
148 148
    typedef TR Traits;
149 149

	
150 150
  private:
151 151

	
152 152
    TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
153 153

	
154 154
    // Data sturcture for path data
155 155
    struct PathData
156 156
    {
157
      LargeValue dist;
157
      LargeCost dist;
158 158
      Arc pred;
159
      PathData(LargeValue d, Arc p = INVALID) :
159
      PathData(LargeCost d, Arc p = INVALID) :
160 160
        dist(d), pred(p) {}
161 161
    };
162 162

	
163 163
    typedef typename Digraph::template NodeMap<std::vector<PathData> >
164 164
      PathDataNodeMap;
165 165

	
166 166
  private:
167 167

	
168 168
    // The digraph the algorithm runs on
169 169
    const Digraph &_gr;
170
    // The length of the arcs
171
    const LengthMap &_length;
170
    // The cost of the arcs
171
    const CostMap &_cost;
172 172

	
173 173
    // Data for storing the strongly connected components
174 174
    int _comp_num;
175 175
    typename Digraph::template NodeMap<int> _comp;
176 176
    std::vector<std::vector<Node> > _comp_nodes;
177 177
    std::vector<Node>* _nodes;
178 178
    typename Digraph::template NodeMap<std::vector<Arc> > _out_arcs;
179 179

	
180 180
    // Data for the found cycle
181
    LargeValue _cycle_length;
181
    LargeCost _cycle_cost;
182 182
    int _cycle_size;
183 183
    Node _cycle_node;
184 184

	
185 185
    Path *_cycle_path;
186 186
    bool _local_path;
187 187

	
188 188
    // Node map for storing path data
189 189
    PathDataNodeMap _data;
190 190
    // The processed nodes in the last round
191 191
    std::vector<Node> _process;
192 192

	
193 193
    Tolerance _tolerance;
194 194
    
195 195
    // Infinite constant
196
    const LargeValue INF;
196
    const LargeCost INF;
197 197

	
198 198
  public:
199 199

	
200 200
    /// \name Named Template Parameters
201 201
    /// @{
202 202

	
203 203
    template <typename T>
204
    struct SetLargeValueTraits : public Traits {
205
      typedef T LargeValue;
204
    struct SetLargeCostTraits : public Traits {
205
      typedef T LargeCost;
206 206
      typedef lemon::Tolerance<T> Tolerance;
207 207
    };
208 208

	
209 209
    /// \brief \ref named-templ-param "Named parameter" for setting
210
    /// \c LargeValue type.
210
    /// \c LargeCost type.
211 211
    ///
212
    /// \ref named-templ-param "Named parameter" for setting \c LargeValue
212
    /// \ref named-templ-param "Named parameter" for setting \c LargeCost
213 213
    /// type. It is used for internal computations in the algorithm.
214 214
    template <typename T>
215
    struct SetLargeValue
216
      : public Karp<GR, LEN, SetLargeValueTraits<T> > {
217
      typedef Karp<GR, LEN, SetLargeValueTraits<T> > Create;
215
    struct SetLargeCost
216
      : public KarpMmc<GR, CM, SetLargeCostTraits<T> > {
217
      typedef KarpMmc<GR, CM, SetLargeCostTraits<T> > Create;
218 218
    };
219 219

	
220 220
    template <typename T>
221 221
    struct SetPathTraits : public Traits {
222 222
      typedef T Path;
223 223
    };
224 224

	
225 225
    /// \brief \ref named-templ-param "Named parameter" for setting
226 226
    /// \c %Path type.
227 227
    ///
228 228
    /// \ref named-templ-param "Named parameter" for setting the \c %Path
229 229
    /// type of the found cycles.
230 230
    /// It must conform to the \ref lemon::concepts::Path "Path" concept
231 231
    /// and it must have an \c addFront() function.
232 232
    template <typename T>
233 233
    struct SetPath
234
      : public Karp<GR, LEN, SetPathTraits<T> > {
235
      typedef Karp<GR, LEN, SetPathTraits<T> > Create;
234
      : public KarpMmc<GR, CM, SetPathTraits<T> > {
235
      typedef KarpMmc<GR, CM, SetPathTraits<T> > Create;
236 236
    };
237 237

	
238 238
    /// @}
239 239

	
240 240
  protected:
241 241

	
242
    Karp() {}
242
    KarpMmc() {}
243 243

	
244 244
  public:
245 245

	
246 246
    /// \brief Constructor.
247 247
    ///
248 248
    /// The constructor of the class.
249 249
    ///
250 250
    /// \param digraph The digraph the algorithm runs on.
251
    /// \param length The lengths (costs) of the arcs.
252
    Karp( const Digraph &digraph,
253
          const LengthMap &length ) :
254
      _gr(digraph), _length(length), _comp(digraph), _out_arcs(digraph),
255
      _cycle_length(0), _cycle_size(1), _cycle_node(INVALID),
251
    /// \param cost The costs of the arcs.
252
    KarpMmc( const Digraph &digraph,
253
             const CostMap &cost ) :
254
      _gr(digraph), _cost(cost), _comp(digraph), _out_arcs(digraph),
255
      _cycle_cost(0), _cycle_size(1), _cycle_node(INVALID),
256 256
      _cycle_path(NULL), _local_path(false), _data(digraph),
257
      INF(std::numeric_limits<LargeValue>::has_infinity ?
258
          std::numeric_limits<LargeValue>::infinity() :
259
          std::numeric_limits<LargeValue>::max())
257
      INF(std::numeric_limits<LargeCost>::has_infinity ?
258
          std::numeric_limits<LargeCost>::infinity() :
259
          std::numeric_limits<LargeCost>::max())
260 260
    {}
261 261

	
262 262
    /// Destructor.
263
    ~Karp() {
263
    ~KarpMmc() {
264 264
      if (_local_path) delete _cycle_path;
265 265
    }
266 266

	
267 267
    /// \brief Set the path structure for storing the found cycle.
268 268
    ///
269 269
    /// This function sets an external path structure for storing the
270 270
    /// found cycle.
271 271
    ///
272 272
    /// If you don't call this function before calling \ref run() or
273
    /// \ref findMinMean(), it will allocate a local \ref Path "path"
273
    /// \ref findCycleMean(), it will allocate a local \ref Path "path"
274 274
    /// structure. The destuctor deallocates this automatically
275 275
    /// allocated object, of course.
276 276
    ///
277 277
    /// \note The algorithm calls only the \ref lemon::Path::addFront()
278 278
    /// "addFront()" function of the given path structure.
279 279
    ///
280 280
    /// \return <tt>(*this)</tt>
281
    Karp& cycle(Path &path) {
281
    KarpMmc& cycle(Path &path) {
282 282
      if (_local_path) {
283 283
        delete _cycle_path;
284 284
        _local_path = false;
285 285
      }
286 286
      _cycle_path = &path;
287 287
      return *this;
288 288
    }
289 289

	
290 290
    /// \brief Set the tolerance used by the algorithm.
291 291
    ///
292 292
    /// This function sets the tolerance object used by the algorithm.
293 293
    ///
294 294
    /// \return <tt>(*this)</tt>
295
    Karp& tolerance(const Tolerance& tolerance) {
295
    KarpMmc& tolerance(const Tolerance& tolerance) {
296 296
      _tolerance = tolerance;
297 297
      return *this;
298 298
    }
299 299

	
300 300
    /// \brief Return a const reference to the tolerance.
301 301
    ///
302 302
    /// This function returns a const reference to the tolerance object
303 303
    /// used by the algorithm.
304 304
    const Tolerance& tolerance() const {
305 305
      return _tolerance;
306 306
    }
307 307

	
308 308
    /// \name Execution control
309 309
    /// The simplest way to execute the algorithm is to call the \ref run()
310 310
    /// function.\n
311
    /// If you only need the minimum mean length, you may call
312
    /// \ref findMinMean().
311
    /// If you only need the minimum mean cost, you may call
312
    /// \ref findCycleMean().
313 313

	
314 314
    /// @{
315 315

	
316 316
    /// \brief Run the algorithm.
317 317
    ///
318 318
    /// This function runs the algorithm.
319 319
    /// It can be called more than once (e.g. if the underlying digraph
320
    /// and/or the arc lengths have been modified).
320
    /// and/or the arc costs have been modified).
321 321
    ///
322 322
    /// \return \c true if a directed cycle exists in the digraph.
323 323
    ///
324 324
    /// \note <tt>mmc.run()</tt> is just a shortcut of the following code.
325 325
    /// \code
326
    ///   return mmc.findMinMean() && mmc.findCycle();
326
    ///   return mmc.findCycleMean() && mmc.findCycle();
327 327
    /// \endcode
328 328
    bool run() {
329
      return findMinMean() && findCycle();
329
      return findCycleMean() && findCycle();
330 330
    }
331 331

	
332 332
    /// \brief Find the minimum cycle mean.
333 333
    ///
334
    /// This function finds the minimum mean length of the directed
334
    /// This function finds the minimum mean cost of the directed
335 335
    /// cycles in the digraph.
336 336
    ///
337 337
    /// \return \c true if a directed cycle exists in the digraph.
338
    bool findMinMean() {
338
    bool findCycleMean() {
339 339
      // Initialization and find strongly connected components
340 340
      init();
341 341
      findComponents();
342 342
      
343 343
      // Find the minimum cycle mean in the components
344 344
      for (int comp = 0; comp < _comp_num; ++comp) {
345 345
        if (!initComponent(comp)) continue;
346 346
        processRounds();
347 347
        updateMinMean();
348 348
      }
349 349
      return (_cycle_node != INVALID);
350 350
    }
351 351

	
352 352
    /// \brief Find a minimum mean directed cycle.
353 353
    ///
354
    /// This function finds a directed cycle of minimum mean length
355
    /// in the digraph using the data computed by findMinMean().
354
    /// This function finds a directed cycle of minimum mean cost
355
    /// in the digraph using the data computed by findCycleMean().
356 356
    ///
357 357
    /// \return \c true if a directed cycle exists in the digraph.
358 358
    ///
359
    /// \pre \ref findMinMean() must be called before using this function.
359
    /// \pre \ref findCycleMean() must be called before using this function.
360 360
    bool findCycle() {
361 361
      if (_cycle_node == INVALID) return false;
362 362
      IntNodeMap reached(_gr, -1);
363 363
      int r = _data[_cycle_node].size();
364 364
      Node u = _cycle_node;
365 365
      while (reached[u] < 0) {
366 366
        reached[u] = --r;
367 367
        u = _gr.source(_data[u][r].pred);
368 368
      }
369 369
      r = reached[u];
370 370
      Arc e = _data[u][r].pred;
371 371
      _cycle_path->addFront(e);
372
      _cycle_length = _length[e];
372
      _cycle_cost = _cost[e];
373 373
      _cycle_size = 1;
374 374
      Node v;
375 375
      while ((v = _gr.source(e)) != u) {
376 376
        e = _data[v][--r].pred;
377 377
        _cycle_path->addFront(e);
378
        _cycle_length += _length[e];
378
        _cycle_cost += _cost[e];
379 379
        ++_cycle_size;
380 380
      }
381 381
      return true;
382 382
    }
383 383

	
384 384
    /// @}
385 385

	
386 386
    /// \name Query Functions
387 387
    /// The results of the algorithm can be obtained using these
388 388
    /// functions.\n
389 389
    /// The algorithm should be executed before using them.
390 390

	
391 391
    /// @{
392 392

	
393
    /// \brief Return the total length of the found cycle.
393
    /// \brief Return the total cost of the found cycle.
394 394
    ///
395
    /// This function returns the total length of the found cycle.
395
    /// This function returns the total cost of the found cycle.
396 396
    ///
397
    /// \pre \ref run() or \ref findMinMean() must be called before
397
    /// \pre \ref run() or \ref findCycleMean() must be called before
398 398
    /// using this function.
399
    Value cycleLength() const {
400
      return static_cast<Value>(_cycle_length);
399
    Cost cycleCost() const {
400
      return static_cast<Cost>(_cycle_cost);
401 401
    }
402 402

	
403 403
    /// \brief Return the number of arcs on the found cycle.
404 404
    ///
405 405
    /// This function returns the number of arcs on the found cycle.
406 406
    ///
407
    /// \pre \ref run() or \ref findMinMean() must be called before
407
    /// \pre \ref run() or \ref findCycleMean() must be called before
408 408
    /// using this function.
409
    int cycleArcNum() const {
409
    int cycleSize() const {
410 410
      return _cycle_size;
411 411
    }
412 412

	
413
    /// \brief Return the mean length of the found cycle.
413
    /// \brief Return the mean cost of the found cycle.
414 414
    ///
415
    /// This function returns the mean length of the found cycle.
415
    /// This function returns the mean cost of the found cycle.
416 416
    ///
417 417
    /// \note <tt>alg.cycleMean()</tt> is just a shortcut of the
418 418
    /// following code.
419 419
    /// \code
420
    ///   return static_cast<double>(alg.cycleLength()) / alg.cycleArcNum();
420
    ///   return static_cast<double>(alg.cycleCost()) / alg.cycleSize();
421 421
    /// \endcode
422 422
    ///
423
    /// \pre \ref run() or \ref findMinMean() must be called before
423
    /// \pre \ref run() or \ref findCycleMean() must be called before
424 424
    /// using this function.
425 425
    double cycleMean() const {
426
      return static_cast<double>(_cycle_length) / _cycle_size;
426
      return static_cast<double>(_cycle_cost) / _cycle_size;
427 427
    }
428 428

	
429 429
    /// \brief Return the found cycle.
430 430
    ///
431 431
    /// This function returns a const reference to the path structure
432 432
    /// storing the found cycle.
433 433
    ///
434 434
    /// \pre \ref run() or \ref findCycle() must be called before using
435 435
    /// this function.
436 436
    const Path& cycle() const {
437 437
      return *_cycle_path;
438 438
    }
439 439

	
440 440
    ///@}
441 441

	
442 442
  private:
443 443

	
444 444
    // Initialization
445 445
    void init() {
446 446
      if (!_cycle_path) {
447 447
        _local_path = true;
448 448
        _cycle_path = new Path;
449 449
      }
450 450
      _cycle_path->clear();
451
      _cycle_length = 0;
451
      _cycle_cost = 0;
452 452
      _cycle_size = 1;
453 453
      _cycle_node = INVALID;
454 454
      for (NodeIt u(_gr); u != INVALID; ++u)
455 455
        _data[u].clear();
456 456
    }
457 457

	
458 458
    // Find strongly connected components and initialize _comp_nodes
459 459
    // and _out_arcs
460 460
    void findComponents() {
461 461
      _comp_num = stronglyConnectedComponents(_gr, _comp);
462 462
      _comp_nodes.resize(_comp_num);
463 463
      if (_comp_num == 1) {
464 464
        _comp_nodes[0].clear();
465 465
        for (NodeIt n(_gr); n != INVALID; ++n) {
466 466
          _comp_nodes[0].push_back(n);
467 467
          _out_arcs[n].clear();
468 468
          for (OutArcIt a(_gr, n); a != INVALID; ++a) {
469 469
            _out_arcs[n].push_back(a);
470 470
          }
471 471
        }
472 472
      } else {
473 473
        for (int i = 0; i < _comp_num; ++i)
474 474
          _comp_nodes[i].clear();
475 475
        for (NodeIt n(_gr); n != INVALID; ++n) {
476 476
          int k = _comp[n];
477 477
          _comp_nodes[k].push_back(n);
478 478
          _out_arcs[n].clear();
479 479
          for (OutArcIt a(_gr, n); a != INVALID; ++a) {
480 480
            if (_comp[_gr.target(a)] == k) _out_arcs[n].push_back(a);
481 481
          }
482 482
        }
483 483
      }
484 484
    }
485 485

	
486 486
    // Initialize path data for the current component
487 487
    bool initComponent(int comp) {
488 488
      _nodes = &(_comp_nodes[comp]);
489 489
      int n = _nodes->size();
490 490
      if (n < 1 || (n == 1 && _out_arcs[(*_nodes)[0]].size() == 0)) {
491 491
        return false;
492 492
      }      
493 493
      for (int i = 0; i < n; ++i) {
494 494
        _data[(*_nodes)[i]].resize(n + 1, PathData(INF));
495 495
      }
496 496
      return true;
497 497
    }
498 498

	
499 499
    // Process all rounds of computing path data for the current component.
500
    // _data[v][k] is the length of a shortest directed walk from the root
500
    // _data[v][k] is the cost of a shortest directed walk from the root
501 501
    // node to node v containing exactly k arcs.
502 502
    void processRounds() {
503 503
      Node start = (*_nodes)[0];
504 504
      _data[start][0] = PathData(0);
505 505
      _process.clear();
506 506
      _process.push_back(start);
507 507

	
508 508
      int k, n = _nodes->size();
509 509
      for (k = 1; k <= n && int(_process.size()) < n; ++k) {
510 510
        processNextBuildRound(k);
511 511
      }
512 512
      for ( ; k <= n; ++k) {
513 513
        processNextFullRound(k);
514 514
      }
515 515
    }
516 516

	
517 517
    // Process one round and rebuild _process
518 518
    void processNextBuildRound(int k) {
519 519
      std::vector<Node> next;
520 520
      Node u, v;
521 521
      Arc e;
522
      LargeValue d;
522
      LargeCost d;
523 523
      for (int i = 0; i < int(_process.size()); ++i) {
524 524
        u = _process[i];
525 525
        for (int j = 0; j < int(_out_arcs[u].size()); ++j) {
526 526
          e = _out_arcs[u][j];
527 527
          v = _gr.target(e);
528
          d = _data[u][k-1].dist + _length[e];
528
          d = _data[u][k-1].dist + _cost[e];
529 529
          if (_tolerance.less(d, _data[v][k].dist)) {
530 530
            if (_data[v][k].dist == INF) next.push_back(v);
531 531
            _data[v][k] = PathData(d, e);
532 532
          }
533 533
        }
534 534
      }
535 535
      _process.swap(next);
536 536
    }
537 537

	
538 538
    // Process one round using _nodes instead of _process
539 539
    void processNextFullRound(int k) {
540 540
      Node u, v;
541 541
      Arc e;
542
      LargeValue d;
542
      LargeCost d;
543 543
      for (int i = 0; i < int(_nodes->size()); ++i) {
544 544
        u = (*_nodes)[i];
545 545
        for (int j = 0; j < int(_out_arcs[u].size()); ++j) {
546 546
          e = _out_arcs[u][j];
547 547
          v = _gr.target(e);
548
          d = _data[u][k-1].dist + _length[e];
548
          d = _data[u][k-1].dist + _cost[e];
549 549
          if (_tolerance.less(d, _data[v][k].dist)) {
550 550
            _data[v][k] = PathData(d, e);
551 551
          }
552 552
        }
553 553
      }
554 554
    }
555 555

	
556 556
    // Update the minimum cycle mean
557 557
    void updateMinMean() {
558 558
      int n = _nodes->size();
559 559
      for (int i = 0; i < n; ++i) {
560 560
        Node u = (*_nodes)[i];
561 561
        if (_data[u][n].dist == INF) continue;
562
        LargeValue length, max_length = 0;
562
        LargeCost cost, max_cost = 0;
563 563
        int size, max_size = 1;
564 564
        bool found_curr = false;
565 565
        for (int k = 0; k < n; ++k) {
566 566
          if (_data[u][k].dist == INF) continue;
567
          length = _data[u][n].dist - _data[u][k].dist;
567
          cost = _data[u][n].dist - _data[u][k].dist;
568 568
          size = n - k;
569
          if (!found_curr || length * max_size > max_length * size) {
569
          if (!found_curr || cost * max_size > max_cost * size) {
570 570
            found_curr = true;
571
            max_length = length;
571
            max_cost = cost;
572 572
            max_size = size;
573 573
          }
574 574
        }
575 575
        if ( found_curr && (_cycle_node == INVALID ||
576
             max_length * _cycle_size < _cycle_length * max_size) ) {
577
          _cycle_length = max_length;
576
             max_cost * _cycle_size < _cycle_cost * max_size) ) {
577
          _cycle_cost = max_cost;
578 578
          _cycle_size = max_size;
579 579
          _cycle_node = u;
580 580
        }
581 581
      }
582 582
    }
583 583

	
584
  }; //class Karp
584
  }; //class KarpMmc
585 585

	
586 586
  ///@}
587 587

	
588 588
} //namespace lemon
589 589

	
590
#endif //LEMON_KARP_H
590
#endif //LEMON_KARP_MMC_H
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5 5
 * Copyright (C) 2003-2009
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
#include <iostream>
20 20
#include <sstream>
21 21

	
22 22
#include <lemon/smart_graph.h>
23 23
#include <lemon/lgf_reader.h>
24 24
#include <lemon/path.h>
25 25
#include <lemon/concepts/digraph.h>
26 26
#include <lemon/concept_check.h>
27 27

	
28
#include <lemon/karp.h>
29
#include <lemon/hartmann_orlin.h>
30
#include <lemon/howard.h>
28
#include <lemon/karp_mmc.h>
29
#include <lemon/hartmann_orlin_mmc.h>
30
#include <lemon/howard_mmc.h>
31 31

	
32 32
#include "test_tools.h"
33 33

	
34 34
using namespace lemon;
35 35

	
36 36
char test_lgf[] =
37 37
  "@nodes\n"
38 38
  "label\n"
39 39
  "1\n"
40 40
  "2\n"
41 41
  "3\n"
42 42
  "4\n"
43 43
  "5\n"
44 44
  "6\n"
45 45
  "7\n"
46 46
  "@arcs\n"
47 47
  "    len1 len2 len3 len4  c1 c2 c3 c4\n"
48 48
  "1 2    1    1    1    1   0  0  0  0\n"
49 49
  "2 4    5    5    5    5   1  0  0  0\n"
50 50
  "2 3    8    8    8    8   0  0  0  0\n"
51 51
  "3 2   -2    0    0    0   1  0  0  0\n"
52 52
  "3 4    4    4    4    4   0  0  0  0\n"
53 53
  "3 7   -4   -4   -4   -4   0  0  0  0\n"
54 54
  "4 1    2    2    2    2   0  0  0  0\n"
55 55
  "4 3    3    3    3    3   1  0  0  0\n"
56 56
  "4 4    3    3    0    0   0  0  1  0\n"
57 57
  "5 2    4    4    4    4   0  0  0  0\n"
58 58
  "5 6    3    3    3    3   0  1  0  0\n"
59 59
  "6 5    2    2    2    2   0  1  0  0\n"
60 60
  "6 4   -1   -1   -1   -1   0  0  0  0\n"
61 61
  "6 7    1    1    1    1   0  0  0  0\n"
62 62
  "7 7    4    4    4   -1   0  0  0  1\n";
63 63

	
64 64
                        
65 65
// Check the interface of an MMC algorithm
66
template <typename GR, typename Value>
66
template <typename GR, typename Cost>
67 67
struct MmcClassConcept
68 68
{
69 69
  template <typename MMC>
70 70
  struct Constraints {
71 71
    void constraints() {
72 72
      const Constraints& me = *this;
73 73

	
74 74
      typedef typename MMC
75 75
        ::template SetPath<ListPath<GR> >
76
        ::template SetLargeValue<Value>
76
        ::template SetLargeCost<Cost>
77 77
        ::Create MmcAlg;
78
      MmcAlg mmc(me.g, me.length);
78
      MmcAlg mmc(me.g, me.cost);
79 79
      const MmcAlg& const_mmc = mmc;
80 80
      
81 81
      typename MmcAlg::Tolerance tol = const_mmc.tolerance();
82 82
      mmc.tolerance(tol);
83 83
      
84 84
      b = mmc.cycle(p).run();
85
      b = mmc.findMinMean();
85
      b = mmc.findCycleMean();
86 86
      b = mmc.findCycle();
87 87

	
88
      v = const_mmc.cycleLength();
89
      i = const_mmc.cycleArcNum();
88
      v = const_mmc.cycleCost();
89
      i = const_mmc.cycleSize();
90 90
      d = const_mmc.cycleMean();
91 91
      p = const_mmc.cycle();
92 92
    }
93 93

	
94
    typedef concepts::ReadMap<typename GR::Arc, Value> LM;
94
    typedef concepts::ReadMap<typename GR::Arc, Cost> CM;
95 95
  
96 96
    GR g;
97
    LM length;
97
    CM cost;
98 98
    ListPath<GR> p;
99
    Value v;
99
    Cost v;
100 100
    int i;
101 101
    double d;
102 102
    bool b;
103 103
  };
104 104
};
105 105

	
106 106
// Perform a test with the given parameters
107 107
template <typename MMC>
108 108
void checkMmcAlg(const SmartDigraph& gr,
109 109
                 const SmartDigraph::ArcMap<int>& lm,
110 110
                 const SmartDigraph::ArcMap<int>& cm,
111
                 int length, int size) {
111
                 int cost, int size) {
112 112
  MMC alg(gr, lm);
113
  alg.findMinMean();
114
  check(alg.cycleMean() == static_cast<double>(length) / size,
113
  alg.findCycleMean();
114
  check(alg.cycleMean() == static_cast<double>(cost) / size,
115 115
        "Wrong cycle mean");
116 116
  alg.findCycle();
117
  check(alg.cycleLength() == length && alg.cycleArcNum() == size,
117
  check(alg.cycleCost() == cost && alg.cycleSize() == size,
118 118
        "Wrong path");
119 119
  SmartDigraph::ArcMap<int> cycle(gr, 0);
120 120
  for (typename MMC::Path::ArcIt a(alg.cycle()); a != INVALID; ++a) {
121 121
    ++cycle[a];
122 122
  }
123 123
  for (SmartDigraph::ArcIt a(gr); a != INVALID; ++a) {
124 124
    check(cm[a] == cycle[a], "Wrong path");
125 125
  }
126 126
}
127 127

	
128 128
// Class for comparing types
129 129
template <typename T1, typename T2>
130 130
struct IsSameType {
131 131
  static const int result = 0;
132 132
};
133 133

	
134 134
template <typename T>
135 135
struct IsSameType<T,T> {
136 136
  static const int result = 1;
137 137
};
138 138

	
139 139

	
140 140
int main() {
141 141
  #ifdef LEMON_HAVE_LONG_LONG
142 142
    typedef long long long_int;
143 143
  #else
144 144
    typedef long long_int;
145 145
  #endif
146 146

	
147 147
  // Check the interface
148 148
  {
149 149
    typedef concepts::Digraph GR;
150 150

	
151
    // Karp
151
    // KarpMmc
152 152
    checkConcept< MmcClassConcept<GR, int>,
153
                  Karp<GR, concepts::ReadMap<GR::Arc, int> > >();
153
                  KarpMmc<GR, concepts::ReadMap<GR::Arc, int> > >();
154 154
    checkConcept< MmcClassConcept<GR, float>,
155
                  Karp<GR, concepts::ReadMap<GR::Arc, float> > >();
155
                  KarpMmc<GR, concepts::ReadMap<GR::Arc, float> > >();
156 156
    
157
    // HartmannOrlin
157
    // HartmannOrlinMmc
158 158
    checkConcept< MmcClassConcept<GR, int>,
159
                  HartmannOrlin<GR, concepts::ReadMap<GR::Arc, int> > >();
159
                  HartmannOrlinMmc<GR, concepts::ReadMap<GR::Arc, int> > >();
160 160
    checkConcept< MmcClassConcept<GR, float>,
161
                  HartmannOrlin<GR, concepts::ReadMap<GR::Arc, float> > >();
161
                  HartmannOrlinMmc<GR, concepts::ReadMap<GR::Arc, float> > >();
162 162
    
163
    // Howard
163
    // HowardMmc
164 164
    checkConcept< MmcClassConcept<GR, int>,
165
                  Howard<GR, concepts::ReadMap<GR::Arc, int> > >();
165
                  HowardMmc<GR, concepts::ReadMap<GR::Arc, int> > >();
166 166
    checkConcept< MmcClassConcept<GR, float>,
167
                  Howard<GR, concepts::ReadMap<GR::Arc, float> > >();
167
                  HowardMmc<GR, concepts::ReadMap<GR::Arc, float> > >();
168 168

	
169
    if (IsSameType<Howard<GR, concepts::ReadMap<GR::Arc, int> >::LargeValue,
170
          long_int>::result == 0) check(false, "Wrong LargeValue type");
171
    if (IsSameType<Howard<GR, concepts::ReadMap<GR::Arc, float> >::LargeValue,
172
          double>::result == 0) check(false, "Wrong LargeValue type");
169
    check((IsSameType<HowardMmc<GR, concepts::ReadMap<GR::Arc, int> >
170
           ::LargeCost, long_int>::result == 1), "Wrong LargeCost type");
171
    check((IsSameType<HowardMmc<GR, concepts::ReadMap<GR::Arc, float> >
172
           ::LargeCost, double>::result == 1), "Wrong LargeCost type");
173 173
  }
174 174

	
175 175
  // Run various tests
176 176
  {
177 177
    typedef SmartDigraph GR;
178 178
    DIGRAPH_TYPEDEFS(GR);
179 179
    
180 180
    GR gr;
181 181
    IntArcMap l1(gr), l2(gr), l3(gr), l4(gr);
182 182
    IntArcMap c1(gr), c2(gr), c3(gr), c4(gr);
183 183
    
184 184
    std::istringstream input(test_lgf);
185 185
    digraphReader(gr, input).
186 186
      arcMap("len1", l1).
187 187
      arcMap("len2", l2).
188 188
      arcMap("len3", l3).
189 189
      arcMap("len4", l4).
190 190
      arcMap("c1", c1).
191 191
      arcMap("c2", c2).
192 192
      arcMap("c3", c3).
193 193
      arcMap("c4", c4).
194 194
      run();
195 195

	
196 196
    // Karp
197
    checkMmcAlg<Karp<GR, IntArcMap> >(gr, l1, c1,  6, 3);
198
    checkMmcAlg<Karp<GR, IntArcMap> >(gr, l2, c2,  5, 2);
199
    checkMmcAlg<Karp<GR, IntArcMap> >(gr, l3, c3,  0, 1);
200
    checkMmcAlg<Karp<GR, IntArcMap> >(gr, l4, c4, -1, 1);
197
    checkMmcAlg<KarpMmc<GR, IntArcMap> >(gr, l1, c1,  6, 3);
198
    checkMmcAlg<KarpMmc<GR, IntArcMap> >(gr, l2, c2,  5, 2);
199
    checkMmcAlg<KarpMmc<GR, IntArcMap> >(gr, l3, c3,  0, 1);
200
    checkMmcAlg<KarpMmc<GR, IntArcMap> >(gr, l4, c4, -1, 1);
201 201

	
202 202
    // HartmannOrlin
203
    checkMmcAlg<HartmannOrlin<GR, IntArcMap> >(gr, l1, c1,  6, 3);
204
    checkMmcAlg<HartmannOrlin<GR, IntArcMap> >(gr, l2, c2,  5, 2);
205
    checkMmcAlg<HartmannOrlin<GR, IntArcMap> >(gr, l3, c3,  0, 1);
206
    checkMmcAlg<HartmannOrlin<GR, IntArcMap> >(gr, l4, c4, -1, 1);
203
    checkMmcAlg<HartmannOrlinMmc<GR, IntArcMap> >(gr, l1, c1,  6, 3);
204
    checkMmcAlg<HartmannOrlinMmc<GR, IntArcMap> >(gr, l2, c2,  5, 2);
205
    checkMmcAlg<HartmannOrlinMmc<GR, IntArcMap> >(gr, l3, c3,  0, 1);
206
    checkMmcAlg<HartmannOrlinMmc<GR, IntArcMap> >(gr, l4, c4, -1, 1);
207 207

	
208 208
    // Howard
209
    checkMmcAlg<Howard<GR, IntArcMap> >(gr, l1, c1,  6, 3);
210
    checkMmcAlg<Howard<GR, IntArcMap> >(gr, l2, c2,  5, 2);
211
    checkMmcAlg<Howard<GR, IntArcMap> >(gr, l3, c3,  0, 1);
212
    checkMmcAlg<Howard<GR, IntArcMap> >(gr, l4, c4, -1, 1);
209
    checkMmcAlg<HowardMmc<GR, IntArcMap> >(gr, l1, c1,  6, 3);
210
    checkMmcAlg<HowardMmc<GR, IntArcMap> >(gr, l2, c2,  5, 2);
211
    checkMmcAlg<HowardMmc<GR, IntArcMap> >(gr, l3, c3,  0, 1);
212
    checkMmcAlg<HowardMmc<GR, IntArcMap> >(gr, l4, c4, -1, 1);
213 213
  }
214 214

	
215 215
  return 0;
216 216
}
0 comments (0 inline)