[Lemon-commits] Peter Kovacs: Port MinMeanCycle from SVN -r3524 ...
Lemon HG
hg at lemon.cs.elte.hu
Thu Nov 5 08:59:55 CET 2009
details: http://lemon.cs.elte.hu/hg/lemon/rev/b31e130db13d
changeset: 818:b31e130db13d
user: Peter Kovacs <kpeter [at] inf.elte.hu>
date: Mon Aug 03 14:12:55 2009 +0200
description:
Port MinMeanCycle from SVN -r3524 (#179) with some doc improvements
diffstat:
lemon/Makefile.am | 1 +
lemon/min_mean_cycle.h | 462 +++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 463 insertions(+), 0 deletions(-)
diffs (truncated from 478 to 300 lines):
diff --git a/lemon/Makefile.am b/lemon/Makefile.am
--- a/lemon/Makefile.am
+++ b/lemon/Makefile.am
@@ -97,6 +97,7 @@
lemon/matching.h \
lemon/math.h \
lemon/min_cost_arborescence.h \
+ lemon/min_mean_cycle.h \
lemon/nauty_reader.h \
lemon/network_simplex.h \
lemon/path.h \
diff --git a/lemon/min_mean_cycle.h b/lemon/min_mean_cycle.h
new file mode 100644
--- /dev/null
+++ b/lemon/min_mean_cycle.h
@@ -0,0 +1,462 @@
+/* -*- 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_MIN_MEAN_CYCLE_H
+#define LEMON_MIN_MEAN_CYCLE_H
+
+/// \ingroup shortest_path
+///
+/// \file
+/// \brief Howard's algorithm for finding a minimum mean cycle.
+
+#include <vector>
+#include <lemon/core.h>
+#include <lemon/path.h>
+#include <lemon/tolerance.h>
+#include <lemon/connectivity.h>
+
+namespace lemon {
+
+ /// \addtogroup shortest_path
+ /// @{
+
+ /// \brief Implementation of Howard's algorithm for finding a minimum
+ /// mean cycle.
+ ///
+ /// \ref MinMeanCycle implements Howard's algorithm for finding a
+ /// directed cycle of minimum mean length (cost) in a digraph.
+ ///
+ /// \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>".
+ ///
+ /// \warning \c LEN::Value must be convertible to \c double.
+#ifdef DOXYGEN
+ template <typename GR, typename LEN>
+#else
+ template < typename GR,
+ typename LEN = typename GR::template ArcMap<int> >
+#endif
+ class MinMeanCycle
+ {
+ public:
+
+ /// The type of the digraph the algorithm runs on
+ typedef GR Digraph;
+ /// The type of the length map
+ typedef LEN LengthMap;
+ /// The type of the arc lengths
+ typedef typename LengthMap::Value Value;
+ /// The type of the paths
+ typedef lemon::Path<Digraph> Path;
+
+ private:
+
+ TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
+
+ // The digraph the algorithm runs on
+ const Digraph &_gr;
+ // The length of the arcs
+ const LengthMap &_length;
+
+ // The total length of the found cycle
+ Value _cycle_length;
+ // The number of arcs on the found cycle
+ int _cycle_size;
+ // The found cycle
+ Path *_cycle_path;
+
+ bool _local_path;
+ bool _cycle_found;
+ Node _cycle_node;
+
+ typename Digraph::template NodeMap<bool> _reached;
+ typename Digraph::template NodeMap<double> _dist;
+ typename Digraph::template NodeMap<Arc> _policy;
+
+ typename Digraph::template NodeMap<int> _comp;
+ int _comp_num;
+
+ std::vector<Node> _nodes;
+ std::vector<Arc> _arcs;
+ Tolerance<double> _tol;
+
+ public:
+
+ /// \brief Constructor.
+ ///
+ /// The constructor of the class.
+ ///
+ /// \param digraph The digraph the algorithm runs on.
+ /// \param length The lengths (costs) of the arcs.
+ MinMeanCycle( const Digraph &digraph,
+ const LengthMap &length ) :
+ _gr(digraph), _length(length), _cycle_length(0), _cycle_size(-1),
+ _cycle_path(NULL), _local_path(false), _reached(digraph),
+ _dist(digraph), _policy(digraph), _comp(digraph)
+ {}
+
+ /// Destructor.
+ ~MinMeanCycle() {
+ 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 init(), 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::addBack()
+ /// "addBack()" function of the given path structure.
+ ///
+ /// \return <tt>(*this)</tt>
+ ///
+ /// \sa cycle()
+ MinMeanCycle& cyclePath(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 init()
+ /// and \ref findMinMean().
+ /// If you would like to run the algorithm again (e.g. the underlying
+ /// digraph and/or the arc lengths has been modified), you may not
+ /// create a new instance of the class, rather call \ref reset(),
+ /// \ref findMinMean() and \ref findCycle() instead.
+
+ /// @{
+
+ /// \brief Run the algorithm.
+ ///
+ /// This function runs the algorithm.
+ ///
+ /// \return \c true if a directed cycle exists in the digraph.
+ ///
+ /// \note Apart from the return value, <tt>mmc.run()</tt> is just a
+ /// shortcut of the following code.
+ /// \code
+ /// mmc.init();
+ /// mmc.findMinMean();
+ /// mmc.findCycle();
+ /// \endcode
+ bool run() {
+ init();
+ return findMinMean() && findCycle();
+ }
+
+ /// \brief Initialize the internal data structures.
+ ///
+ /// This function initializes the internal data structures.
+ ///
+ /// \sa reset()
+ void init() {
+ _tol.epsilon(1e-6);
+ if (!_cycle_path) {
+ _local_path = true;
+ _cycle_path = new Path;
+ }
+ _cycle_found = false;
+ _comp_num = stronglyConnectedComponents(_gr, _comp);
+ }
+
+ /// \brief Reset the internal data structures.
+ ///
+ /// This function resets the internal data structures so that
+ /// findMinMean() and findCycle() can be called again (e.g. when the
+ /// underlying digraph and/or the arc lengths has been modified).
+ ///
+ /// \sa init()
+ void reset() {
+ if (_cycle_path) _cycle_path->clear();
+ _cycle_found = false;
+ _comp_num = stronglyConnectedComponents(_gr, _comp);
+ }
+
+ /// \brief Find the minimum cycle mean.
+ ///
+ /// This function computes all the required data and finds the
+ /// minimum mean length of the directed cycles in the digraph.
+ ///
+ /// \return \c true if a directed cycle exists in the digraph.
+ ///
+ /// \pre \ref init() must be called before using this function.
+ bool findMinMean() {
+ // Find the minimum cycle mean in the components
+ for (int comp = 0; comp < _comp_num; ++comp) {
+ if (!initCurrentComponent(comp)) continue;
+ while (true) {
+ if (!findPolicyCycles()) break;
+ contractPolicyGraph(comp);
+ if (!computeNodeDistances()) break;
+ }
+ }
+ return _cycle_found;
+ }
+
+ /// \brief Find a minimum mean directed cycle.
+ ///
+ /// This function finds a directed cycle of minimum mean length
+ /// in the digraph using the data computed by findMinMean().
+ ///
+ /// \return \c true if a directed cycle exists in the digraph.
+ ///
+ /// \pre \ref init() and \ref findMinMean() must be called before
+ /// using this function.
+ bool findCycle() {
+ if (!_cycle_found) return false;
+ _cycle_path->addBack(_policy[_cycle_node]);
+ for ( Node v = _cycle_node;
+ (v = _gr.target(_policy[v])) != _cycle_node; ) {
+ _cycle_path->addBack(_policy[v]);
+ }
+ return true;
+ }
+
+ /// @}
+
+ /// \name Query Functions
+ /// The result of the algorithm can be obtained using these
+ /// functions.\n
+ /// The algorithm should be executed before using them.
+
+ /// @{
+
+ /// \brief Return the total length of the found cycle.
+ ///
+ /// This function returns the total length of the found cycle.
+ ///
+ /// \pre \ref run() or \ref findCycle() must be called before
+ /// using this function.
+ Value cycleLength() const {
+ return _cycle_length;
+ }
+
+ /// \brief Return the number of arcs on the found cycle.
+ ///
+ /// This function returns the number of arcs on the found cycle.
+ ///
+ /// \pre \ref run() or \ref findCycle() must be called before
+ /// using this function.
+ int cycleArcNum() const {
+ return _cycle_size;
+ }
+
+ /// \brief Return the mean length of the found cycle.
+ ///
+ /// This function returns the mean length of the found cycle.
+ ///
+ /// \note <tt>mmc.cycleMean()</tt> is just a shortcut of the
+ /// following code.
+ /// \code
+ /// return double(mmc.cycleLength()) / mmc.cycleArcNum();
+ /// \endcode
+ ///
+ /// \pre \ref run() or \ref findMinMean() must be called before
+ /// using this function.
+ double cycleMean() const {
+ return double(_cycle_length) / _cycle_size;
More information about the Lemon-commits
mailing list