[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