[Lemon-commits] Peter Kovacs: Port NetworkSimplex from SVN -r352...
Lemon HG
hg at lemon.cs.elte.hu
Tue Apr 21 16:33:30 CEST 2009
details: http://lemon.cs.elte.hu/hg/lemon/rev/e8349c6f12ca
changeset: 633:e8349c6f12ca
user: Peter Kovacs <kpeter [at] inf.elte.hu>
date: Tue Feb 24 09:46:02 2009 +0100
description:
Port NetworkSimplex from SVN -r3520 (#234)
diffstat:
lemon/Makefile.am | 1 +
lemon/network_simplex.h | 1191 +++++++++++++++++++++++++++++++++++++++++++++++
test/CMakeLists.txt | 1 +
test/Makefile.am | 2 +
test/min_cost_flow_test.cc | 455 ++++++++++++++++++
5 files changed, 1650 insertions(+), 0 deletions(-)
diffs (truncated from 1697 to 300 lines):
diff --git a/lemon/Makefile.am b/lemon/Makefile.am
--- a/lemon/Makefile.am
+++ b/lemon/Makefile.am
@@ -85,6 +85,7 @@
lemon/max_matching.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/network_simplex.h b/lemon/network_simplex.h
new file mode 100644
--- /dev/null
+++ b/lemon/network_simplex.h
@@ -0,0 +1,1191 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2009
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_NETWORK_SIMPLEX_H
+#define LEMON_NETWORK_SIMPLEX_H
+
+/// \ingroup min_cost_flow
+///
+/// \file
+/// \brief Network simplex algorithm for finding a minimum cost flow.
+
+#include <vector>
+#include <limits>
+#include <algorithm>
+
+#include <lemon/math.h>
+
+namespace lemon {
+
+ /// \addtogroup min_cost_flow
+ /// @{
+
+ /// \brief Implementation of the primal network simplex algorithm
+ /// for finding a \ref min_cost_flow "minimum cost flow".
+ ///
+ /// \ref NetworkSimplex implements the primal network simplex algorithm
+ /// for finding a \ref min_cost_flow "minimum cost flow".
+ ///
+ /// \tparam Digraph The digraph type the algorithm runs on.
+ /// \tparam LowerMap The type of the lower bound map.
+ /// \tparam CapacityMap The type of the capacity (upper bound) map.
+ /// \tparam CostMap The type of the cost (length) map.
+ /// \tparam SupplyMap The type of the supply map.
+ ///
+ /// \warning
+ /// - Arc capacities and costs should be \e non-negative \e integers.
+ /// - Supply values should be \e signed \e integers.
+ /// - The value types of the maps should be convertible to each other.
+ /// - \c CostMap::Value must be signed type.
+ ///
+ /// \note \ref NetworkSimplex provides five different pivot rule
+ /// implementations that significantly affect the efficiency of the
+ /// algorithm.
+ /// By default "Block Search" pivot rule is used, which proved to be
+ /// by far the most efficient according to our benchmark tests.
+ /// However another pivot rule can be selected using \ref run()
+ /// function with the proper parameter.
+#ifdef DOXYGEN
+ template < typename Digraph,
+ typename LowerMap,
+ typename CapacityMap,
+ typename CostMap,
+ typename SupplyMap >
+
+#else
+ template < typename Digraph,
+ typename LowerMap = typename Digraph::template ArcMap<int>,
+ typename CapacityMap = typename Digraph::template ArcMap<int>,
+ typename CostMap = typename Digraph::template ArcMap<int>,
+ typename SupplyMap = typename Digraph::template NodeMap<int> >
+#endif
+ class NetworkSimplex
+ {
+ TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
+
+ typedef typename CapacityMap::Value Capacity;
+ typedef typename CostMap::Value Cost;
+ typedef typename SupplyMap::Value Supply;
+
+ typedef std::vector<Arc> ArcVector;
+ typedef std::vector<Node> NodeVector;
+ typedef std::vector<int> IntVector;
+ typedef std::vector<bool> BoolVector;
+ typedef std::vector<Capacity> CapacityVector;
+ typedef std::vector<Cost> CostVector;
+ typedef std::vector<Supply> SupplyVector;
+
+ public:
+
+ /// The type of the flow map
+ typedef typename Digraph::template ArcMap<Capacity> FlowMap;
+ /// The type of the potential map
+ typedef typename Digraph::template NodeMap<Cost> PotentialMap;
+
+ public:
+
+ /// Enum type for selecting the pivot rule used by \ref run()
+ enum PivotRuleEnum {
+ FIRST_ELIGIBLE_PIVOT,
+ BEST_ELIGIBLE_PIVOT,
+ BLOCK_SEARCH_PIVOT,
+ CANDIDATE_LIST_PIVOT,
+ ALTERING_LIST_PIVOT
+ };
+
+ private:
+
+ // State constants for arcs
+ enum ArcStateEnum {
+ STATE_UPPER = -1,
+ STATE_TREE = 0,
+ STATE_LOWER = 1
+ };
+
+ private:
+
+ // References for the original data
+ const Digraph &_orig_graph;
+ const LowerMap *_orig_lower;
+ const CapacityMap &_orig_cap;
+ const CostMap &_orig_cost;
+ const SupplyMap *_orig_supply;
+ Node _orig_source;
+ Node _orig_target;
+ Capacity _orig_flow_value;
+
+ // Result maps
+ FlowMap *_flow_result;
+ PotentialMap *_potential_result;
+ bool _local_flow;
+ bool _local_potential;
+
+ // Data structures for storing the graph
+ ArcVector _arc;
+ NodeVector _node;
+ IntNodeMap _node_id;
+ IntVector _source;
+ IntVector _target;
+
+ // The number of nodes and arcs in the original graph
+ int _node_num;
+ int _arc_num;
+
+ // Node and arc maps
+ CapacityVector _cap;
+ CostVector _cost;
+ CostVector _supply;
+ CapacityVector _flow;
+ CostVector _pi;
+
+ // Node and arc maps for the spanning tree structure
+ IntVector _depth;
+ IntVector _parent;
+ IntVector _pred;
+ IntVector _thread;
+ BoolVector _forward;
+ IntVector _state;
+
+ // The root node
+ int _root;
+
+ // The entering arc in the current pivot iteration
+ int _in_arc;
+
+ // Temporary data used in the current pivot iteration
+ int join, u_in, v_in, u_out, v_out;
+ int right, first, second, last;
+ int stem, par_stem, new_stem;
+ Capacity delta;
+
+ private:
+
+ /// \brief Implementation of the "First Eligible" pivot rule for the
+ /// \ref NetworkSimplex "network simplex" algorithm.
+ ///
+ /// This class implements the "First Eligible" pivot rule
+ /// for the \ref NetworkSimplex "network simplex" algorithm.
+ ///
+ /// For more information see \ref NetworkSimplex::run().
+ class FirstEligiblePivotRule
+ {
+ private:
+
+ // References to the NetworkSimplex class
+ const ArcVector &_arc;
+ const IntVector &_source;
+ const IntVector &_target;
+ const CostVector &_cost;
+ const IntVector &_state;
+ const CostVector &_pi;
+ int &_in_arc;
+ int _arc_num;
+
+ // Pivot rule data
+ int _next_arc;
+
+ public:
+
+ /// Constructor
+ FirstEligiblePivotRule(NetworkSimplex &ns) :
+ _arc(ns._arc), _source(ns._source), _target(ns._target),
+ _cost(ns._cost), _state(ns._state), _pi(ns._pi),
+ _in_arc(ns._in_arc), _arc_num(ns._arc_num), _next_arc(0)
+ {}
+
+ /// Find next entering arc
+ bool findEnteringArc() {
+ Cost c;
+ for (int e = _next_arc; e < _arc_num; ++e) {
+ c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
+ if (c < 0) {
+ _in_arc = e;
+ _next_arc = e + 1;
+ return true;
+ }
+ }
+ for (int e = 0; e < _next_arc; ++e) {
+ c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
+ if (c < 0) {
+ _in_arc = e;
+ _next_arc = e + 1;
+ return true;
+ }
+ }
+ return false;
+ }
+
+ }; //class FirstEligiblePivotRule
+
+
+ /// \brief Implementation of the "Best Eligible" pivot rule for the
+ /// \ref NetworkSimplex "network simplex" algorithm.
+ ///
+ /// This class implements the "Best Eligible" pivot rule
+ /// for the \ref NetworkSimplex "network simplex" algorithm.
+ ///
+ /// For more information see \ref NetworkSimplex::run().
+ class BestEligiblePivotRule
+ {
+ private:
+
+ // References to the NetworkSimplex class
+ const ArcVector &_arc;
+ const IntVector &_source;
+ const IntVector &_target;
+ const CostVector &_cost;
+ const IntVector &_state;
+ const CostVector &_pi;
+ int &_in_arc;
+ int _arc_num;
+
+ public:
+
+ /// Constructor
+ BestEligiblePivotRule(NetworkSimplex &ns) :
+ _arc(ns._arc), _source(ns._source), _target(ns._target),
+ _cost(ns._cost), _state(ns._state), _pi(ns._pi),
+ _in_arc(ns._in_arc), _arc_num(ns._arc_num)
+ {}
+
+ /// Find next entering arc
+ bool findEnteringArc() {
+ Cost c, min = 0;
+ for (int e = 0; e < _arc_num; ++e) {
+ c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
+ if (c < min) {
+ min = c;
+ _in_arc = e;
+ }
+ }
+ return min < 0;
+ }
+
+ }; //class BestEligiblePivotRule
+
+
+ /// \brief Implementation of the "Block Search" pivot rule for the
+ /// \ref NetworkSimplex "network simplex" algorithm.
+ ///
More information about the Lemon-commits
mailing list