[Lemon-commits] Peter Kovacs: More options for run() in scaling ...
Lemon HG
hg at lemon.cs.elte.hu
Mon Dec 14 06:17:45 CET 2009
details: http://lemon.cs.elte.hu/hg/lemon/rev/3b53491bf643
changeset: 876:3b53491bf643
user: Peter Kovacs <kpeter [at] inf.elte.hu>
date: Thu Nov 12 23:34:35 2009 +0100
description:
More options for run() in scaling MCF algorithms (#180)
- Three methods can be selected and the scaling factor can be
given for CostScaling.
- The scaling factor can be given for CapacityScaling.
diffstat:
lemon/capacity_scaling.h | 31 ++++++---------
lemon/cost_scaling.h | 82 +++++++++++++++++++++++++++++------------
2 files changed, 71 insertions(+), 42 deletions(-)
diffs (253 lines):
diff --git a/lemon/capacity_scaling.h b/lemon/capacity_scaling.h
--- a/lemon/capacity_scaling.h
+++ b/lemon/capacity_scaling.h
@@ -173,7 +173,7 @@
IntVector _deficit_nodes;
Value _delta;
- int _phase_num;
+ int _factor;
IntVector _pred;
public:
@@ -513,12 +513,11 @@
/// \ref reset() is called, thus only the modified parameters
/// have to be set again. See \ref reset() for examples.
/// However the underlying digraph must not be modified after this
- /// class have been constructed, since it copies the digraph.
+ /// class have been constructed, since it copies and extends the graph.
///
- /// \param scaling Enable or disable capacity scaling.
- /// If the maximum upper bound and/or the amount of total supply
- /// is rather small, the algorithm could be slightly faster without
- /// scaling.
+ /// \param factor The capacity scaling factor. It must be larger than
+ /// one to use scaling. If it is less or equal to one, then scaling
+ /// will be disabled.
///
/// \return \c INFEASIBLE if no feasible flow exists,
/// \n \c OPTIMAL if the problem has optimal solution
@@ -531,8 +530,9 @@
/// these cases.
///
/// \see ProblemType
- ProblemType run(bool scaling = true) {
- ProblemType pt = init(scaling);
+ ProblemType run(int factor = 4) {
+ _factor = factor;
+ ProblemType pt = init();
if (pt != OPTIMAL) return pt;
return start();
}
@@ -546,7 +546,7 @@
/// It is useful for multiple run() calls. If this function is not
/// used, all the parameters given before are kept for the next
/// \ref run() call.
- /// However the underlying digraph must not be modified after this
+ /// However, the underlying digraph must not be modified after this
/// class have been constructed, since it copies and extends the graph.
///
/// For example,
@@ -677,7 +677,7 @@
private:
// Initialize the algorithm
- ProblemType init(bool scaling) {
+ ProblemType init() {
if (_node_num == 0) return INFEASIBLE;
// Check the sum of supply values
@@ -758,7 +758,7 @@
}
// Initialize delta value
- if (scaling) {
+ if (_factor > 1) {
// With scaling
Value max_sup = 0, max_dem = 0;
for (int i = 0; i != _node_num; ++i) {
@@ -770,9 +770,7 @@
if (_res_cap[j] > max_cap) max_cap = _res_cap[j];
}
max_sup = std::min(std::min(max_sup, max_dem), max_cap);
- _phase_num = 0;
- for (_delta = 1; 2 * _delta <= max_sup; _delta *= 2)
- ++_phase_num;
+ for (_delta = 1; 2 * _delta <= max_sup; _delta *= 2) ;
} else {
// Without scaling
_delta = 1;
@@ -811,8 +809,6 @@
ProblemType startWithScaling() {
// Perform capacity scaling phases
int s, t;
- int phase_cnt = 0;
- int factor = 4;
ResidualDijkstra _dijkstra(*this);
while (true) {
// Saturate all arcs not satisfying the optimality condition
@@ -887,8 +883,7 @@
}
if (_delta == 1) break;
- if (++phase_cnt == _phase_num / 4) factor = 2;
- _delta = _delta <= factor ? 1 : _delta / factor;
+ _delta = _delta <= _factor ? 1 : _delta / _factor;
}
return OPTIMAL;
diff --git a/lemon/cost_scaling.h b/lemon/cost_scaling.h
--- a/lemon/cost_scaling.h
+++ b/lemon/cost_scaling.h
@@ -110,6 +110,10 @@
/// be integer.
/// \warning This algorithm does not support negative costs for such
/// arcs that have infinite upper bound.
+ ///
+ /// \note %CostScaling provides three different internal methods,
+ /// from which the most efficient one is used by default.
+ /// For more information, see \ref Method.
#ifdef DOXYGEN
template <typename GR, typename V, typename C, typename TR>
#else
@@ -159,6 +163,33 @@
UNBOUNDED
};
+ /// \brief Constants for selecting the internal method.
+ ///
+ /// Enum type containing constants for selecting the internal method
+ /// for the \ref run() function.
+ ///
+ /// \ref CostScaling provides three internal methods that differ mainly
+ /// in their base operations, which are used in conjunction with the
+ /// relabel operation.
+ /// By default, the so called \ref PARTIAL_AUGMENT
+ /// "Partial Augment-Relabel" method is used, which proved to be
+ /// the most efficient and the most robust on various test inputs.
+ /// However, the other methods can be selected using the \ref run()
+ /// function with the proper parameter.
+ enum Method {
+ /// Local push operations are used, i.e. flow is moved only on one
+ /// admissible arc at once.
+ PUSH,
+ /// Augment operations are used, i.e. flow is moved on admissible
+ /// paths from a node with excess to a node with deficit.
+ AUGMENT,
+ /// Partial augment operations are used, i.e. flow is moved on
+ /// admissible paths started from a node with excess, but the
+ /// lengths of these paths are limited. This method can be viewed
+ /// as a combined version of the previous two operations.
+ PARTIAL_AUGMENT
+ };
+
private:
TEMPLATE_DIGRAPH_TYPEDEFS(GR);
@@ -505,13 +536,12 @@
/// that have been given are kept for the next call, unless
/// \ref reset() is called, thus only the modified parameters
/// have to be set again. See \ref reset() for examples.
- /// However the underlying digraph must not be modified after this
- /// class have been constructed, since it copies the digraph.
+ /// However, the underlying digraph must not be modified after this
+ /// class have been constructed, since it copies and extends the graph.
///
- /// \param partial_augment By default the algorithm performs
- /// partial augment and relabel operations in the cost scaling
- /// phases. Set this parameter to \c false for using local push and
- /// relabel operations instead.
+ /// \param method The internal method that will be used in the
+ /// algorithm. For more information, see \ref Method.
+ /// \param factor The cost scaling factor. It must be larger than one.
///
/// \return \c INFEASIBLE if no feasible flow exists,
/// \n \c OPTIMAL if the problem has optimal solution
@@ -523,11 +553,12 @@
/// bounded over the feasible flows, but this algroithm cannot handle
/// these cases.
///
- /// \see ProblemType
- ProblemType run(bool partial_augment = true) {
+ /// \see ProblemType, Method
+ ProblemType run(Method method = PARTIAL_AUGMENT, int factor = 8) {
+ _alpha = factor;
ProblemType pt = init();
if (pt != OPTIMAL) return pt;
- start(partial_augment);
+ start(method);
return OPTIMAL;
}
@@ -681,9 +712,6 @@
ProblemType init() {
if (_res_node_num == 0) return INFEASIBLE;
- // Scaling factor
- _alpha = 8;
-
// Check the sum of supply values
_sum_supply = 0;
for (int i = 0; i != _root; ++i) {
@@ -817,12 +845,21 @@
}
// Execute the algorithm and transform the results
- void start(bool partial_augment) {
+ void start(Method method) {
+ // Maximum path length for partial augment
+ const int MAX_PATH_LENGTH = 4;
+
// Execute the algorithm
- if (partial_augment) {
- startPartialAugment();
- } else {
- startPushRelabel();
+ switch (method) {
+ case PUSH:
+ startPush();
+ break;
+ case AUGMENT:
+ startAugment();
+ break;
+ case PARTIAL_AUGMENT:
+ startAugment(MAX_PATH_LENGTH);
+ break;
}
// Compute node potentials for the original costs
@@ -851,14 +888,11 @@
}
}
- /// Execute the algorithm performing partial augmentation and
- /// relabel operations
- void startPartialAugment() {
+ /// Execute the algorithm performing augment and relabel operations
+ void startAugment(int max_length = std::numeric_limits<int>::max()) {
// Paramters for heuristics
const int BF_HEURISTIC_EPSILON_BOUND = 1000;
const int BF_HEURISTIC_BOUND_FACTOR = 3;
- // Maximum augment path length
- const int MAX_PATH_LENGTH = 4;
// Perform cost scaling phases
IntVector pred_arc(_res_node_num);
@@ -925,7 +959,7 @@
// Find an augmenting path from the start node
int tip = start;
while (_excess[tip] >= 0 &&
- int(path_nodes.size()) <= MAX_PATH_LENGTH) {
+ int(path_nodes.size()) <= max_length) {
int u;
LargeCost min_red_cost, rc;
int last_out = _sum_supply < 0 ?
@@ -984,7 +1018,7 @@
}
/// Execute the algorithm performing push and relabel operations
- void startPushRelabel() {
+ void startPush() {
// Paramters for heuristics
const int BF_HEURISTIC_EPSILON_BOUND = 1000;
const int BF_HEURISTIC_BOUND_FACTOR = 3;
More information about the Lemon-commits
mailing list