[Lemon-commits] Peter Kovacs: Add HartmannOrlin algorithm class ...
Lemon HG
hg at lemon.cs.elte.hu
Thu Nov 5 08:59:58 CET 2009
details: http://lemon.cs.elte.hu/hg/lemon/rev/97744b6dabf8
changeset: 826:97744b6dabf8
user: Peter Kovacs <kpeter [at] inf.elte.hu>
date: Tue Aug 11 21:53:39 2009 +0200
description:
Add HartmannOrlin algorithm class (#179) This algorithm is an
improved version of Karp's original method, it applies an efficient
early termination scheme. The interface is the same as Karp's and
Howard's interface.
diffstat:
lemon/Makefile.am | 1 +
lemon/hartmann_orlin.h | 618 +++++++++++++++++++++++++++++++++++++++++++++++
test/min_mean_cycle_test.cc | 13 +
3 files changed, 632 insertions(+), 0 deletions(-)
diffs (truncated from 671 to 300 lines):
diff --git a/lemon/Makefile.am b/lemon/Makefile.am
--- a/lemon/Makefile.am
+++ b/lemon/Makefile.am
@@ -83,6 +83,7 @@
lemon/gomory_hu.h \
lemon/graph_to_eps.h \
lemon/grid_graph.h \
+ lemon/hartmann_orlin.h \
lemon/howard.h \
lemon/hypercube_graph.h \
lemon/karp.h \
diff --git a/lemon/hartmann_orlin.h b/lemon/hartmann_orlin.h
new file mode 100644
--- /dev/null
+++ b/lemon/hartmann_orlin.h
@@ -0,0 +1,618 @@
+/* -*- C++ -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library
+ *
+ * Copyright (C) 2003-2008
+ * 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_HARTMANN_ORLIN_H
+#define LEMON_HARTMANN_ORLIN_H
+
+/// \ingroup shortest_path
+///
+/// \file
+/// \brief Hartmann-Orlin's algorithm for finding a minimum mean cycle.
+
+#include <vector>
+#include <limits>
+#include <lemon/core.h>
+#include <lemon/path.h>
+#include <lemon/tolerance.h>
+#include <lemon/connectivity.h>
+
+namespace lemon {
+
+ /// \brief Default traits class of HartmannOrlin algorithm.
+ ///
+ /// Default traits class of HartmannOrlin algorithm.
+ /// \tparam GR The type of the digraph.
+ /// \tparam LEN The type of the length map.
+ /// It must conform to the \ref concepts::Rea_data "Rea_data" concept.
+#ifdef DOXYGEN
+ template <typename GR, typename LEN>
+#else
+ template <typename GR, typename LEN,
+ bool integer = std::numeric_limits<typename LEN::Value>::is_integer>
+#endif
+ struct HartmannOrlinDefaultTraits
+ {
+ /// The type of the digraph
+ typedef GR Digraph;
+ /// The type of the length map
+ typedef LEN LengthMap;
+ /// The type of the arc lengths
+ typedef typename LengthMap::Value Value;
+
+ /// \brief The large value type used for internal computations
+ ///
+ /// The large value type used for internal computations.
+ /// It is \c long \c long if the \c Value type is integer,
+ /// otherwise it is \c double.
+ /// \c Value must be convertible to \c LargeValue.
+ typedef double LargeValue;
+
+ /// The tolerance type used for internal computations
+ typedef lemon::Tolerance<LargeValue> Tolerance;
+
+ /// \brief The path type of the found cycles
+ ///
+ /// The path type of the found cycles.
+ /// It must conform to the \ref lemon::concepts::Path "Path" concept
+ /// and it must have an \c addBack() function.
+ typedef lemon::Path<Digraph> Path;
+ };
+
+ // Default traits class for integer value types
+ template <typename GR, typename LEN>
+ struct HartmannOrlinDefaultTraits<GR, LEN, true>
+ {
+ typedef GR Digraph;
+ typedef LEN LengthMap;
+ typedef typename LengthMap::Value Value;
+#ifdef LEMON_HAVE_LONG_LONG
+ typedef long long LargeValue;
+#else
+ typedef long LargeValue;
+#endif
+ typedef lemon::Tolerance<LargeValue> Tolerance;
+ typedef lemon::Path<Digraph> Path;
+ };
+
+
+ /// \addtogroup shortest_path
+ /// @{
+
+ /// \brief Implementation of the Hartmann-Orlin algorithm for finding
+ /// a minimum mean cycle.
+ ///
+ /// This class implements the Hartmann-Orlin algorithm for finding
+ /// a directed cycle of minimum mean length (cost) in a digraph.
+ /// It is an improved version of \ref Karp "Karp's original algorithm",
+ /// it applies an efficient early termination scheme.
+ ///
+ /// \tparam GR The type of the digraph the algorithm runs on.
+ /// \tparam LEN The type of the length map. The default
+ /// map type is \ref concepts::Digraph::ArcMap "GR::ArcMap<int>".
+#ifdef DOXYGEN
+ template <typename GR, typename LEN, typename TR>
+#else
+ template < typename GR,
+ typename LEN = typename GR::template ArcMap<int>,
+ typename TR = HartmannOrlinDefaultTraits<GR, LEN> >
+#endif
+ class HartmannOrlin
+ {
+ public:
+
+ /// The type of the digraph
+ typedef typename TR::Digraph Digraph;
+ /// The type of the length map
+ typedef typename TR::LengthMap LengthMap;
+ /// The type of the arc lengths
+ typedef typename TR::Value Value;
+
+ /// \brief The large value type
+ ///
+ /// The large value type used for internal computations.
+ /// Using the \ref HartmannOrlinDefaultTraits "default traits class",
+ /// it is \c long \c long if the \c Value type is integer,
+ /// otherwise it is \c double.
+ typedef typename TR::LargeValue LargeValue;
+
+ /// The tolerance type
+ typedef typename TR::Tolerance Tolerance;
+
+ /// \brief The path type of the found cycles
+ ///
+ /// The path type of the found cycles.
+ /// Using the \ref HartmannOrlinDefaultTraits "default traits class",
+ /// it is \ref lemon::Path "Path<Digraph>".
+ typedef typename TR::Path Path;
+
+ /// The \ref HartmannOrlinDefaultTraits "traits class" of the algorithm
+ typedef TR Traits;
+
+ private:
+
+ TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
+
+ // Data sturcture for path data
+ struct PathData
+ {
+ bool found;
+ LargeValue dist;
+ Arc pred;
+ PathData(bool f = false, LargeValue d = 0, Arc p = INVALID) :
+ found(f), dist(d), pred(p) {}
+ };
+
+ typedef typename Digraph::template NodeMap<std::vector<PathData> >
+ PathDataNodeMap;
+
+ private:
+
+ // The digraph the algorithm runs on
+ const Digraph &_gr;
+ // The length of the arcs
+ const LengthMap &_length;
+
+ // Data for storing the strongly connected components
+ int _comp_num;
+ typename Digraph::template NodeMap<int> _comp;
+ std::vector<std::vector<Node> > _comp_nodes;
+ std::vector<Node>* _nodes;
+ typename Digraph::template NodeMap<std::vector<Arc> > _out_arcs;
+
+ // Data for the found cycles
+ bool _curr_found, _best_found;
+ LargeValue _curr_length, _best_length;
+ int _curr_size, _best_size;
+ Node _curr_node, _best_node;
+ int _curr_level, _best_level;
+
+ Path *_cycle_path;
+ bool _local_path;
+
+ // Node map for storing path data
+ PathDataNodeMap _data;
+ // The processed nodes in the last round
+ std::vector<Node> _process;
+
+ Tolerance _tolerance;
+
+ public:
+
+ /// \name Named Template Parameters
+ /// @{
+
+ template <typename T>
+ struct SetLargeValueTraits : public Traits {
+ typedef T LargeValue;
+ typedef lemon::Tolerance<T> Tolerance;
+ };
+
+ /// \brief \ref named-templ-param "Named parameter" for setting
+ /// \c LargeValue type.
+ ///
+ /// \ref named-templ-param "Named parameter" for setting \c LargeValue
+ /// type. It is used for internal computations in the algorithm.
+ template <typename T>
+ struct SetLargeValue
+ : public HartmannOrlin<GR, LEN, SetLargeValueTraits<T> > {
+ typedef HartmannOrlin<GR, LEN, SetLargeValueTraits<T> > Create;
+ };
+
+ template <typename T>
+ struct SetPathTraits : public Traits {
+ typedef T Path;
+ };
+
+ /// \brief \ref named-templ-param "Named parameter" for setting
+ /// \c %Path type.
+ ///
+ /// \ref named-templ-param "Named parameter" for setting the \c %Path
+ /// type of the found cycles.
+ /// It must conform to the \ref lemon::concepts::Path "Path" concept
+ /// and it must have an \c addFront() function.
+ template <typename T>
+ struct SetPath
+ : public HartmannOrlin<GR, LEN, SetPathTraits<T> > {
+ typedef HartmannOrlin<GR, LEN, SetPathTraits<T> > Create;
+ };
+
+ /// @}
+
+ public:
+
+ /// \brief Constructor.
+ ///
+ /// The constructor of the class.
+ ///
+ /// \param digraph The digraph the algorithm runs on.
+ /// \param length The lengths (costs) of the arcs.
+ HartmannOrlin( const Digraph &digraph,
+ const LengthMap &length ) :
+ _gr(digraph), _length(length), _comp(digraph), _out_arcs(digraph),
+ _best_found(false), _best_length(0), _best_size(1),
+ _cycle_path(NULL), _local_path(false), _data(digraph)
+ {}
+
+ /// Destructor.
+ ~HartmannOrlin() {
+ if (_local_path) delete _cycle_path;
+ }
+
+ /// \brief Set the path structure for storing the found cycle.
+ ///
+ /// This function sets an external path structure for storing the
+ /// found cycle.
+ ///
+ /// If you don't call this function before calling \ref run() or
+ /// \ref findMinMean(), it will allocate a local \ref Path "path"
+ /// structure. The destuctor deallocates this automatically
+ /// allocated object, of course.
+ ///
+ /// \note The algorithm calls only the \ref lemon::Path::addFront()
+ /// "addFront()" function of the given path structure.
+ ///
+ /// \return <tt>(*this)</tt>
+ HartmannOrlin& cycle(Path &path) {
+ if (_local_path) {
+ delete _cycle_path;
+ _local_path = false;
+ }
+ _cycle_path = &path;
+ return *this;
+ }
+
+ /// \name Execution control
+ /// The simplest way to execute the algorithm is to call the \ref run()
+ /// function.\n
+ /// If you only need the minimum mean length, you may call
+ /// \ref findMinMean().
+
More information about the Lemon-commits
mailing list