[Lemon-commits] Peter Kovacs: Support >= and <= constraints in N...
Lemon HG
hg at lemon.cs.elte.hu
Tue Apr 21 16:33:31 CEST 2009
details: http://lemon.cs.elte.hu/hg/lemon/rev/e6927fe719e6
changeset: 641:e6927fe719e6
user: Peter Kovacs <kpeter [at] inf.elte.hu>
date: Fri Apr 17 18:04:36 2009 +0200
description:
Support >= and <= constraints in NetworkSimplex (#219, #234)
By default the same inequality constraints are supported as by
Circulation (the GEQ form), but the LEQ form can also be selected
using the problemType() function.
The documentation of the min. cost flow module is reworked and
extended with important notes and explanations about the different
variants of the problem and about the dual solution and optimality
conditions.
diffstat:
doc/groups.dox | 118 ++++++++++++++++++-----
lemon/network_simplex.h | 245 +++++++++++++++++++++++++++++++++++++++++-------
test/min_cost_flow_test.cc | 107 +++++++++++++++-----
3 files changed, 377 insertions(+), 93 deletions(-)
diffs (truncated from 768 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.
@@ -345,35 +345,103 @@
\brief Algorithms for finding minimum cost flows and circulations.
-This group describes the algorithms for finding minimum cost flows and
+This group contains the algorithms for finding minimum cost flows and
circulations.
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/network_simplex.h b/lemon/network_simplex.h
--- a/lemon/network_simplex.h
+++ b/lemon/network_simplex.h
@@ -30,6 +30,9 @@
#include <lemon/core.h>
#include <lemon/math.h>
+#include <lemon/maps.h>
+#include <lemon/circulation.h>
+#include <lemon/adaptors.h>
namespace lemon {
@@ -47,6 +50,8 @@
///
/// In general this class is the fastest implementation available
/// in LEMON for the minimum cost flow problem.
+ /// Moreover it supports both direction of the supply/demand inequality
+ /// constraints. For more information see \ref ProblemType.
///
/// \tparam GR The digraph type the algorithm runs on.
/// \tparam F The value type used for flow amounts, capacity bounds
@@ -58,7 +63,8 @@
/// be integer.
///
/// \note %NetworkSimplex provides five different pivot rule
- /// implementations. For more information see \ref PivotRule.
+ /// implementations, from which the most efficient one is used
+ /// by default. For more information see \ref PivotRule.
template <typename GR, typename F = int, typename C = F>
class NetworkSimplex
{
@@ -68,10 +74,17 @@
typedef F Flow;
/// The cost type of the algorithm
typedef C Cost;
+#ifdef DOXYGEN
+ /// The type of the flow map
+ typedef GR::ArcMap<Flow> FlowMap;
+ /// The type of the potential map
+ typedef GR::NodeMap<Cost> PotentialMap;
+#else
/// The type of the flow map
typedef typename GR::template ArcMap<Flow> FlowMap;
/// The type of the potential map
typedef typename GR::template NodeMap<Cost> PotentialMap;
+#endif
public:
@@ -117,6 +130,58 @@
/// candidate list and extends this list in every iteration.
ALTERING_LIST
};
+
+ /// \brief Enum type for selecting the problem type.
+ ///
+ /// Enum type for selecting the problem type, i.e. the direction of
+ /// the inequalities in the supply/demand constraints of the
+ /// \ref min_cost_flow "minimum cost flow problem".
+ ///
+ /// The default problem type is \c GEQ, since this form is supported
+ /// by other minimum cost flow algorithms and the \ref Circulation
+ /// algorithm as well.
+ /// The \c LEQ problem type can be selected using the \ref problemType()
+ /// function.
+ ///
+ /// Note that the equality form is a special case of both problem type.
+ enum ProblemType {
+
+ /// This option means that there are "<em>greater or equal</em>"
+ /// constraints in the defintion, i.e. the exact formulation of the
+ /// problem is the following.
+ /**
+ \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]
+ */
+ /// It means that the total demand must be greater or equal to the
+ /// total supply (i.e. \f$\sum_{u\in V} sup(u)\f$ must be zero or
+ /// negative) and all the supplies have to be carried out from
+ /// the supply nodes, but there could be demands that are not
+ /// satisfied.
+ GEQ,
+ /// It is just an alias for the \c GEQ option.
+ CARRY_SUPPLIES = GEQ,
+
+ /// This option means that there are "<em>less or equal</em>"
+ /// constraints in the defintion, i.e. the exact formulation of the
+ /// problem is the following.
+ /**
+ \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) \leq
+ sup(u) \quad \forall u\in V \f]
+ \f[ lower(uv) \leq f(uv) \leq upper(uv) \quad \forall uv\in A \f]
+ */
+ /// It means that the total demand must be less or equal to the
+ /// total supply (i.e. \f$\sum_{u\in V} sup(u)\f$ must be zero or
+ /// positive) and all the demands have to be satisfied, but there
+ /// could be supplies that are not carried out from the supply
+ /// nodes.
+ LEQ,
+ /// It is just an alias for the \c LEQ option.
+ SATISFY_DEMANDS = LEQ
+ };
private:
@@ -155,6 +220,7 @@
bool _pstsup;
Node _psource, _ptarget;
Flow _pstflow;
+ ProblemType _ptype;
// Result maps
FlowMap *_flow_map;
@@ -586,13 +652,13 @@
/// \brief Constructor.
///
- /// Constructor.
+ /// The constructor of the class.
///
/// \param graph The digraph the algorithm runs on.
NetworkSimplex(const GR& graph) :
_graph(graph),
_plower(NULL), _pupper(NULL), _pcost(NULL),
- _psupply(NULL), _pstsup(false),
+ _psupply(NULL), _pstsup(false), _ptype(GEQ),
_flow_map(NULL), _potential_map(NULL),
_local_flow(false), _local_potential(false),
_node_id(graph)
@@ -611,6 +677,12 @@
if (_local_potential) delete _potential_map;
}
+ /// \name Parameters
+ /// The parameters of the algorithm can be specified using these
+ /// functions.
+
+ /// @{
+
/// \brief Set the lower bounds on the arcs.
///
/// This function sets the lower bounds on the arcs.
@@ -760,6 +832,20 @@
_pstflow = k;
return *this;
}
+
+ /// \brief Set the problem type.
More information about the Lemon-commits
mailing list