[Lemon-commits] Antal Nemes: Port Edmonds-Karp algorithm from sv...
Lemon HG
hg at lemon.cs.elte.hu
Tue Mar 19 15:42:33 CET 2013
details: http://lemon.cs.elte.hu/hg/lemon/rev/92a884824429
changeset: 1224:92a884824429
user: Antal Nemes <thoneyvazul [at] gmail.com>
date: Tue Nov 30 20:21:52 2010 +0100
description:
Port Edmonds-Karp algorithm from svn -r3524 (#177)
diffstat:
lemon/edmonds_karp.h | 515 ++++++++++++++++++++++++++++++++++++++++++++++
test/CMakeLists.txt | 1 +
test/edmonds_karp_test.cc | 236 +++++++++++++++++++++
3 files changed, 752 insertions(+), 0 deletions(-)
diffs (truncated from 772 to 300 lines):
diff --git a/lemon/edmonds_karp.h b/lemon/edmonds_karp.h
new file mode 100644
--- /dev/null
+++ b/lemon/edmonds_karp.h
@@ -0,0 +1,515 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2010
+ * 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_EDMONDS_KARP_H
+#define LEMON_EDMONDS_KARP_H
+
+/// \file
+/// \ingroup max_flow
+/// \brief Implementation of the Edmonds-Karp algorithm.
+
+#include <lemon/tolerance.h>
+#include <vector>
+
+namespace lemon {
+
+ /// \brief Default traits class of EdmondsKarp class.
+ ///
+ /// Default traits class of EdmondsKarp class.
+ /// \param GR Digraph type.
+ /// \param CAP Type of capacity map.
+ template <typename GR, typename CAP>
+ struct EdmondsKarpDefaultTraits {
+
+ /// \brief The digraph type the algorithm runs on.
+ typedef GR Digraph;
+
+ /// \brief The type of the map that stores the arc capacities.
+ ///
+ /// The type of the map that stores the arc capacities.
+ /// It must meet the \ref concepts::ReadMap "ReadMap" concept.
+ typedef CAP CapacityMap;
+
+ /// \brief The type of the length of the arcs.
+ typedef typename CapacityMap::Value Value;
+
+ /// \brief The map type that stores the flow values.
+ ///
+ /// The map type that stores the flow values.
+ /// It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
+ typedef typename Digraph::template ArcMap<Value> FlowMap;
+
+ /// \brief Instantiates a FlowMap.
+ ///
+ /// This function instantiates a \ref FlowMap.
+ /// \param digraph The digraph, to which we would like to define the flow map.
+ static FlowMap* createFlowMap(const Digraph& digraph) {
+ return new FlowMap(digraph);
+ }
+
+ /// \brief The tolerance used by the algorithm
+ ///
+ /// The tolerance used by the algorithm to handle inexact computation.
+ typedef lemon::Tolerance<Value> Tolerance;
+
+ };
+
+ /// \ingroup max_flow
+ ///
+ /// \brief Edmonds-Karp algorithms class.
+ ///
+ /// This class provides an implementation of the \e Edmonds-Karp \e
+ /// algorithm producing a flow of maximum value in directed
+ /// digraphs. The Edmonds-Karp algorithm is slower than the Preflow
+ /// algorithm but it has an advantage of the step-by-step execution
+ /// control with feasible flow solutions. The \e source node, the \e
+ /// target node, the \e capacity of the arcs and the \e starting \e
+ /// flow value of the arcs should be passed to the algorithm
+ /// through the constructor.
+ ///
+ /// The time complexity of the algorithm is \f$ O(nm^2) \f$ in
+ /// worst case. Always try the preflow algorithm instead of this if
+ /// you just want to compute the optimal flow.
+ ///
+ /// \param GR The digraph type the algorithm runs on.
+ /// \param CAP The capacity map type.
+ /// \param TR Traits class to set various data types used by
+ /// the algorithm. The default traits class is \ref
+ /// EdmondsKarpDefaultTraits. See \ref EdmondsKarpDefaultTraits for the
+ /// documentation of a Edmonds-Karp traits class.
+
+#ifdef DOXYGEN
+ template <typename GR, typename CAP, typename TR>
+#else
+ template <typename GR,
+ typename CAP = typename GR::template ArcMap<int>,
+ typename TR = EdmondsKarpDefaultTraits<GR, CAP> >
+#endif
+ class EdmondsKarp {
+ public:
+
+ typedef TR Traits;
+ typedef typename Traits::Digraph Digraph;
+ typedef typename Traits::CapacityMap CapacityMap;
+ typedef typename Traits::Value Value;
+
+ typedef typename Traits::FlowMap FlowMap;
+ typedef typename Traits::Tolerance Tolerance;
+
+ private:
+
+ TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
+ typedef typename Digraph::template NodeMap<Arc> PredMap;
+
+ const Digraph& _graph;
+ const CapacityMap* _capacity;
+
+ Node _source, _target;
+
+ FlowMap* _flow;
+ bool _local_flow;
+
+ PredMap* _pred;
+ std::vector<Node> _queue;
+
+ Tolerance _tolerance;
+ Value _flow_value;
+
+ void createStructures() {
+ if (!_flow) {
+ _flow = Traits::createFlowMap(_graph);
+ _local_flow = true;
+ }
+ if (!_pred) {
+ _pred = new PredMap(_graph);
+ }
+ _queue.resize(countNodes(_graph));
+ }
+
+ void destroyStructures() {
+ if (_local_flow) {
+ delete _flow;
+ }
+ if (_pred) {
+ delete _pred;
+ }
+ }
+
+ public:
+
+ ///\name Named template parameters
+
+ ///@{
+
+ template <typename T>
+ struct DefFlowMapTraits : public Traits {
+ typedef T FlowMap;
+ static FlowMap *createFlowMap(const Digraph&) {
+ LEMON_ASSERT(false,"Uninitialized parameter.");
+ return 0;
+ }
+ };
+
+ /// \brief \ref named-templ-param "Named parameter" for setting
+ /// FlowMap type
+ ///
+ /// \ref named-templ-param "Named parameter" for setting FlowMap
+ /// type
+ template <typename T>
+ struct DefFlowMap
+ : public EdmondsKarp<Digraph, CapacityMap, DefFlowMapTraits<T> > {
+ typedef EdmondsKarp<Digraph, CapacityMap, DefFlowMapTraits<T> >
+ Create;
+ };
+
+
+ /// @}
+
+ protected:
+
+ EdmondsKarp() {}
+
+ public:
+
+ /// \brief The constructor of the class.
+ ///
+ /// The constructor of the class.
+ /// \param digraph The digraph the algorithm runs on.
+ /// \param capacity The capacity of the arcs.
+ /// \param source The source node.
+ /// \param target The target node.
+ EdmondsKarp(const Digraph& digraph, const CapacityMap& capacity,
+ Node source, Node target)
+ : _graph(digraph), _capacity(&capacity), _source(source), _target(target),
+ _flow(0), _local_flow(false), _pred(0), _tolerance(), _flow_value()
+ {
+ LEMON_ASSERT(_source != _target,"Flow source and target are the same nodes.");
+ }
+
+ /// \brief Destructor.
+ ///
+ /// Destructor.
+ ~EdmondsKarp() {
+ destroyStructures();
+ }
+
+ /// \brief Sets the capacity map.
+ ///
+ /// Sets the capacity map.
+ /// \return \c (*this)
+ EdmondsKarp& capacityMap(const CapacityMap& map) {
+ _capacity = ↦
+ return *this;
+ }
+
+ /// \brief Sets the flow map.
+ ///
+ /// Sets the flow map.
+ /// \return \c (*this)
+ EdmondsKarp& flowMap(FlowMap& map) {
+ if (_local_flow) {
+ delete _flow;
+ _local_flow = false;
+ }
+ _flow = ↦
+ return *this;
+ }
+
+ /// \brief Returns the flow map.
+ ///
+ /// \return The flow map.
+ const FlowMap& flowMap() const {
+ return *_flow;
+ }
+
+ /// \brief Sets the source node.
+ ///
+ /// Sets the source node.
+ /// \return \c (*this)
+ EdmondsKarp& source(const Node& node) {
+ _source = node;
+ return *this;
+ }
+
+ /// \brief Sets the target node.
+ ///
+ /// Sets the target node.
+ /// \return \c (*this)
+ EdmondsKarp& target(const Node& node) {
+ _target = node;
+ return *this;
+ }
+
+ /// \brief Sets the tolerance used by algorithm.
+ ///
+ /// Sets the tolerance used by algorithm.
+ EdmondsKarp& tolerance(const Tolerance& tolerance) {
+ _tolerance = tolerance;
+ return *this;
+ }
+
+ /// \brief Returns the tolerance used by algorithm.
+ ///
+ /// Returns the tolerance used by algorithm.
+ const Tolerance& tolerance() const {
+ return _tolerance;
+ }
+
+ /// \name Execution control
+ /// The simplest way to execute the
+ /// algorithm is to use the \c run() member functions.
+ /// \n
+ /// If you need more control on initial solution or
+ /// execution then you have to call one \ref init() function and then
+ /// the start() or multiple times the \c augment() member function.
+
+ ///@{
+
+ /// \brief Initializes the algorithm
+ ///
+ /// Sets the flow to empty flow.
+ void init() {
+ createStructures();
+ for (ArcIt it(_graph); it != INVALID; ++it) {
+ _flow->set(it, 0);
+ }
+ _flow_value = 0;
+ }
+
+ /// \brief Initializes the algorithm
+ ///
More information about the Lemon-commits
mailing list