[Lemon-commits] Alpar Juttner: Merge and fix

Lemon HG hg at lemon.cs.elte.hu
Tue Apr 21 16:33:33 CEST 2009


details:   http://lemon.cs.elte.hu/hg/lemon/rev/85cb3aa71cce
changeset: 643:85cb3aa71cce
user:      Alpar Juttner <alpar [at] cs.elte.hu>
date:      Tue Apr 21 15:18:54 2009 +0100
description:
	Merge and fix

diffstat:

 doc/groups.dox             |   116 ++-
 lemon/Makefile.am          |     1 +
 lemon/circulation.h        |   227 +++---
 lemon/network_simplex.h    |  1582 +++++++++++++++++++++++++++++++++++++++++++++++
 lemon/preflow.h            |    42 +-
 test/CMakeLists.txt        |     1 +
 test/Makefile.am           |     2 +
 test/circulation_test.cc   |    14 +-
 test/min_cost_flow_test.cc |   339 ++++++++++
 tools/dimacs-solver.cc     |    26 +-
 10 files changed, 2191 insertions(+), 159 deletions(-)

diffs (truncated from 2825 to 300 lines):

diff --git a/doc/groups.dox b/doc/groups.dox
--- a/doc/groups.dox
+++ b/doc/groups.dox
@@ -317,15 +317,15 @@
 
 The \e maximum \e flow \e problem is to find a flow of maximum value between
 a single source and a single target. Formally, there is a \f$G=(V,A)\f$
-digraph, a \f$cap:A\rightarrow\mathbf{R}^+_0\f$ capacity function and
+digraph, a \f$cap: A\rightarrow\mathbf{R}^+_0\f$ capacity function and
 \f$s, t \in V\f$ source and target nodes.
-A maximum flow is an \f$f:A\rightarrow\mathbf{R}^+_0\f$ solution of the
+A maximum flow is an \f$f: A\rightarrow\mathbf{R}^+_0\f$ solution of the
 following optimization problem.
 
-\f[ \max\sum_{a\in\delta_{out}(s)}f(a) - \sum_{a\in\delta_{in}(s)}f(a) \f]
-\f[ \sum_{a\in\delta_{out}(v)} f(a) = \sum_{a\in\delta_{in}(v)} f(a)
-    \qquad \forall v\in V\setminus\{s,t\} \f]
-\f[ 0 \leq f(a) \leq cap(a) \qquad \forall a\in A \f]
+\f[ \max\sum_{sv\in A} f(sv) - \sum_{vs\in A} f(vs) \f]
+\f[ \sum_{uv\in A} f(uv) = \sum_{vu\in A} f(vu)
+    \quad \forall u\in V\setminus\{s,t\} \f]
+\f[ 0 \leq f(uv) \leq cap(uv) \quad \forall uv\in A \f]
 
 LEMON contains several algorithms for solving maximum flow problems:
 - \ref EdmondsKarp Edmonds-Karp algorithm.
@@ -350,30 +350,98 @@
 
 The \e minimum \e cost \e flow \e problem is to find a feasible flow of
 minimum total cost from a set of supply nodes to a set of demand nodes
-in a network with capacity constraints and arc costs.
+in a network with capacity constraints (lower and upper bounds)
+and arc costs.
 Formally, let \f$G=(V,A)\f$ be a digraph,
 \f$lower, upper: A\rightarrow\mathbf{Z}^+_0\f$ denote the lower and
-upper bounds for the flow values on the arcs,
+upper bounds for the flow values on the arcs, for which
+\f$0 \leq lower(uv) \leq upper(uv)\f$ holds for all \f$uv\in A\f$.
 \f$cost: A\rightarrow\mathbf{Z}^+_0\f$ denotes the cost per unit flow
-on the arcs, and
-\f$supply: V\rightarrow\mathbf{Z}\f$ denotes the supply/demand values
-of the nodes.
-A minimum cost flow is an \f$f:A\rightarrow\mathbf{R}^+_0\f$ solution of
-the following optimization problem.
+on the arcs, and \f$sup: V\rightarrow\mathbf{Z}\f$ denotes the
+signed supply values of the nodes.
+If \f$sup(u)>0\f$, then \f$u\f$ is a supply node with \f$sup(u)\f$
+supply, if \f$sup(u)<0\f$, then \f$u\f$ is a demand node with
+\f$-sup(u)\f$ demand.
+A minimum cost flow is an \f$f: A\rightarrow\mathbf{Z}^+_0\f$ solution
+of the following optimization problem.
 
-\f[ \min\sum_{a\in A} f(a) cost(a) \f]
-\f[ \sum_{a\in\delta_{out}(v)} f(a) - \sum_{a\in\delta_{in}(v)} f(a) =
-    supply(v) \qquad \forall v\in V \f]
-\f[ lower(a) \leq f(a) \leq upper(a) \qquad \forall a\in A \f]
+\f[ \min\sum_{uv\in A} f(uv) \cdot cost(uv) \f]
+\f[ \sum_{uv\in A} f(uv) - \sum_{vu\in A} f(vu) \geq
+    sup(u) \quad \forall u\in V \f]
+\f[ lower(uv) \leq f(uv) \leq upper(uv) \quad \forall uv\in A \f]
 
-LEMON contains several algorithms for solving minimum cost flow problems:
- - \ref CycleCanceling Cycle-canceling algorithms.
- - \ref CapacityScaling Successive shortest path algorithm with optional
+The sum of the supply values, i.e. \f$\sum_{u\in V} sup(u)\f$ must be
+zero or negative in order to have a feasible solution (since the sum
+of the expressions on the left-hand side of the inequalities is zero).
+It means that the total demand must be greater or equal to the total
+supply and all the supplies have to be carried out from the supply nodes,
+but there could be demands that are not satisfied.
+If \f$\sum_{u\in V} sup(u)\f$ is zero, then all the supply/demand
+constraints have to be satisfied with equality, i.e. all demands
+have to be satisfied and all supplies have to be used.
+
+If you need the opposite inequalities in the supply/demand constraints
+(i.e. the total demand is less than the total supply and all the demands
+have to be satisfied while there could be supplies that are not used),
+then you could easily transform the problem to the above form by reversing
+the direction of the arcs and taking the negative of the supply values
+(e.g. using \ref ReverseDigraph and \ref NegMap adaptors).
+However \ref NetworkSimplex algorithm also supports this form directly
+for the sake of convenience.
+
+A feasible solution for this problem can be found using \ref Circulation.
+
+Note that the above formulation is actually more general than the usual
+definition of the minimum cost flow problem, in which strict equalities
+are required in the supply/demand contraints, i.e.
+
+\f[ \sum_{uv\in A} f(uv) - \sum_{vu\in A} f(vu) =
+    sup(u) \quad \forall u\in V. \f]
+
+However if the sum of the supply values is zero, then these two problems
+are equivalent. So if you need the equality form, you have to ensure this
+additional contraint for the algorithms.
+
+The dual solution of the minimum cost flow problem is represented by node 
+potentials \f$\pi: V\rightarrow\mathbf{Z}\f$.
+An \f$f: A\rightarrow\mathbf{Z}^+_0\f$ feasible solution of the problem
+is optimal if and only if for some \f$\pi: V\rightarrow\mathbf{Z}\f$
+node potentials the following \e complementary \e slackness optimality
+conditions hold.
+
+ - For all \f$uv\in A\f$ arcs:
+   - if \f$cost^\pi(uv)>0\f$, then \f$f(uv)=lower(uv)\f$;
+   - if \f$lower(uv)<f(uv)<upper(uv)\f$, then \f$cost^\pi(uv)=0\f$;
+   - if \f$cost^\pi(uv)<0\f$, then \f$f(uv)=upper(uv)\f$.
+ - For all \f$u\in V\f$:
+   - if \f$\sum_{uv\in A} f(uv) - \sum_{vu\in A} f(vu) \neq sup(u)\f$,
+     then \f$\pi(u)=0\f$.
+ 
+Here \f$cost^\pi(uv)\f$ denotes the \e reduced \e cost of the arc
+\f$uv\in A\f$ with respect to the node potentials \f$\pi\f$, i.e.
+\f[ cost^\pi(uv) = cost(uv) + \pi(u) - \pi(v).\f]
+
+All algorithms provide dual solution (node potentials) as well
+if an optimal flow is found.
+
+LEMON contains several algorithms for solving minimum cost flow problems.
+ - \ref NetworkSimplex Primal Network Simplex algorithm with various
+   pivot strategies.
+ - \ref CostScaling Push-Relabel and Augment-Relabel algorithms based on
+   cost scaling.
+ - \ref CapacityScaling Successive Shortest %Path algorithm with optional
    capacity scaling.
- - \ref CostScaling Push-relabel and augment-relabel algorithms based on
-   cost scaling.
- - \ref NetworkSimplex Primal network simplex algorithm with various
-   pivot strategies.
+ - \ref CancelAndTighten The Cancel and Tighten algorithm.
+ - \ref CycleCanceling Cycle-Canceling algorithms.
+
+Most of these implementations support the general inequality form of the
+minimum cost flow problem, but CancelAndTighten and CycleCanceling
+only support the equality form due to the primal method they use.
+
+In general NetworkSimplex is the most efficient implementation,
+but in special cases other algorithms could be faster.
+For example, if the total supply and/or capacities are rather small,
+CapacityScaling is usually the fastest algorithm (without effective scaling).
 */
 
 /**
diff --git a/lemon/Makefile.am b/lemon/Makefile.am
--- a/lemon/Makefile.am
+++ b/lemon/Makefile.am
@@ -93,6 +93,7 @@
 	lemon/math.h \
 	lemon/min_cost_arborescence.h \
 	lemon/nauty_reader.h \
+	lemon/network_simplex.h \
 	lemon/path.h \
 	lemon/preflow.h \
 	lemon/radix_sort.h \
diff --git a/lemon/circulation.h b/lemon/circulation.h
--- a/lemon/circulation.h
+++ b/lemon/circulation.h
@@ -31,52 +31,52 @@
   /// \brief Default traits class of Circulation class.
   ///
   /// Default traits class of Circulation class.
-  /// \tparam GR Digraph type.
-  /// \tparam LM Lower bound capacity map type.
-  /// \tparam UM Upper bound capacity map type.
-  /// \tparam DM Delta map type.
+  ///
+  /// \tparam GR Type of the digraph the algorithm runs on.
+  /// \tparam LM The type of the lower bound map.
+  /// \tparam UM The type of the upper bound (capacity) map.
+  /// \tparam SM The type of the supply map.
   template <typename GR, typename LM,
-            typename UM, typename DM>
+            typename UM, typename SM>
   struct CirculationDefaultTraits {
 
     /// \brief The type of the digraph the algorithm runs on.
     typedef GR Digraph;
 
-    /// \brief The type of the map that stores the circulation lower
-    /// bound.
+    /// \brief The type of the lower bound map.
     ///
-    /// The type of the map that stores the circulation lower bound.
-    /// It must meet the \ref concepts::ReadMap "ReadMap" concept.
-    typedef LM LCapMap;
+    /// The type of the map that stores the lower bounds on the arcs.
+    /// It must conform to the \ref concepts::ReadMap "ReadMap" concept.
+    typedef LM LowerMap;
 
-    /// \brief The type of the map that stores the circulation upper
-    /// bound.
+    /// \brief The type of the upper bound (capacity) map.
     ///
-    /// The type of the map that stores the circulation upper bound.
-    /// It must meet the \ref concepts::ReadMap "ReadMap" concept.
-    typedef UM UCapMap;
+    /// The type of the map that stores the upper bounds (capacities)
+    /// on the arcs.
+    /// It must conform to the \ref concepts::ReadMap "ReadMap" concept.
+    typedef UM UpperMap;
 
-    /// \brief The type of the map that stores the lower bound for
-    /// the supply of the nodes.
+    /// \brief The type of supply map.
     ///
-    /// The type of the map that stores the lower bound for the supply
-    /// of the nodes. It must meet the \ref concepts::ReadMap "ReadMap"
-    /// concept.
-    typedef DM DeltaMap;
+    /// The type of the map that stores the signed supply values of the 
+    /// nodes. 
+    /// It must conform to the \ref concepts::ReadMap "ReadMap" concept.
+    typedef SM SupplyMap;
 
     /// \brief The type of the flow values.
-    typedef typename DeltaMap::Value Value;
+    typedef typename SupplyMap::Value Flow;
 
     /// \brief The type of the map that stores the flow values.
     ///
     /// The type of the map that stores the flow values.
-    /// It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
-    typedef typename Digraph::template ArcMap<Value> FlowMap;
+    /// It must conform to the \ref concepts::ReadWriteMap "ReadWriteMap"
+    /// concept.
+    typedef typename Digraph::template ArcMap<Flow> FlowMap;
 
     /// \brief Instantiates a FlowMap.
     ///
     /// This function instantiates a \ref FlowMap.
-    /// \param digraph The digraph, to which we would like to define
+    /// \param digraph The digraph for which we would like to define
     /// the flow map.
     static FlowMap* createFlowMap(const Digraph& digraph) {
       return new FlowMap(digraph);
@@ -93,7 +93,7 @@
     /// \brief Instantiates an Elevator.
     ///
     /// This function instantiates an \ref Elevator.
-    /// \param digraph The digraph, to which we would like to define
+    /// \param digraph The digraph for which we would like to define
     /// the elevator.
     /// \param max_level The maximum level of the elevator.
     static Elevator* createElevator(const Digraph& digraph, int max_level) {
@@ -103,7 +103,7 @@
     /// \brief The tolerance used by the algorithm
     ///
     /// The tolerance used by the algorithm to handle inexact computation.
-    typedef lemon::Tolerance<Value> Tolerance;
+    typedef lemon::Tolerance<Flow> Tolerance;
 
   };
 
@@ -111,53 +111,69 @@
      \brief Push-relabel algorithm for the network circulation problem.
 
      \ingroup max_flow
-     This class implements a push-relabel algorithm for the network
-     circulation problem.
+     This class implements a push-relabel algorithm for the \e network
+     \e circulation problem.
      It is to find a feasible circulation when lower and upper bounds
-     are given for the flow values on the arcs and lower bounds
-     are given for the supply values of the nodes.
+     are given for the flow values on the arcs and lower bounds are
+     given for the difference between the outgoing and incoming flow
+     at the nodes.
 
      The exact formulation of this problem is the following.
      Let \f$G=(V,A)\f$ be a digraph,
-     \f$lower, upper: A\rightarrow\mathbf{R}^+_0\f$,
-     \f$delta: V\rightarrow\mathbf{R}\f$. Find a feasible circulation
-     \f$f: A\rightarrow\mathbf{R}^+_0\f$ so that
-     \f[ \sum_{a\in\delta_{out}(v)} f(a) - \sum_{a\in\delta_{in}(v)} f(a)
-     \geq delta(v) \quad \forall v\in V, \f]
-     \f[ lower(a)\leq f(a) \leq upper(a) \quad \forall a\in A. \f]
-     \note \f$delta(v)\f$ specifies a lower bound for the supply of node
-     \f$v\f$. It can be either positive or negative, however note that
-     \f$\sum_{v\in V}delta(v)\f$ should be zero or negative in order to
-     have a feasible solution.
+     \f$lower, upper: A\rightarrow\mathbf{R}^+_0\f$ denote the lower and
+     upper bounds on the arcs, for which \f$0 \leq lower(uv) \leq upper(uv)\f$
+     holds for all \f$uv\in A\f$, and \f$sup: V\rightarrow\mathbf{R}\f$
+     denotes the signed supply values of the nodes.
+     If \f$sup(u)>0\f$, then \f$u\f$ is a supply node with \f$sup(u)\f$
+     supply, if \f$sup(u)<0\f$, then \f$u\f$ is a demand node with
+     \f$-sup(u)\f$ demand.
+     A feasible circulation is an \f$f: A\rightarrow\mathbf{R}^+_0\f$
+     solution of the following problem.
 
-     \note A special case of this problem is when
-     \f$\sum_{v\in V}delta(v) = 0\f$. Then the supply of each node \f$v\f$
-     will be \e equal \e to \f$delta(v)\f$, if a circulation can be found.
-     Thus a feasible solution for the
-     \ref min_cost_flow "minimum cost flow" problem can be calculated
-     in this way.
+     \f[ \sum_{uv\in A} f(uv) - \sum_{vu\in A} f(vu)
+     \geq sup(u) \quad \forall u\in V, \f]
+     \f[ lower(uv) \leq f(uv) \leq upper(uv) \quad \forall uv\in A. \f]
+     
+     The sum of the supply values, i.e. \f$\sum_{u\in V} sup(u)\f$ must be



More information about the Lemon-commits mailing list