[Lemon-commits] Balazs Dezso: Add fractional matching algorithms...
Lemon HG
hg at lemon.cs.elte.hu
Wed Mar 17 10:42:52 CET 2010
details: http://lemon.cs.elte.hu/hg/lemon/rev/636dadefe1e6
changeset: 948:636dadefe1e6
user: Balazs Dezso <deba [at] inf.elte.hu>
date: Fri Sep 25 21:51:36 2009 +0200
description:
Add fractional matching algorithms (#314)
diffstat:
doc/groups.dox | 9 +-
lemon/Makefile.am | 1 +
lemon/fractional_matching.h | 2135 +++++++++++++++++++++++++++++++++++++++++
test/CMakeLists.txt | 1 +
test/Makefile.am | 2 +
test/fractional_matching_test.cc | 502 +++++++++
6 files changed, 2649 insertions(+), 1 deletions(-)
diffs (truncated from 2714 to 300 lines):
diff --git a/doc/groups.dox b/doc/groups.dox
--- a/doc/groups.dox
+++ b/doc/groups.dox
@@ -349,7 +349,7 @@
also provide functions to query the minimum cut, which is the dual
problem of maximum flow.
-\ref Circulation is a preflow push-relabel algorithm implemented directly
+\ref Circulation is a preflow push-relabel algorithm implemented directly
for finding feasible circulations, which is a somewhat different problem,
but it is strongly related to maximum flow.
For more information, see \ref Circulation.
@@ -470,6 +470,13 @@
- \ref MaxWeightedPerfectMatching
Edmond's blossom shrinking algorithm for calculating maximum weighted
perfect matching in general graphs.
+- \ref MaxFractionalMatching Push-relabel algorithm for calculating
+ maximum cardinality fractional matching in general graphs.
+- \ref MaxWeightedFractionalMatching Augmenting path algorithm for calculating
+ maximum weighted fractional matching in general graphs.
+- \ref MaxWeightedPerfectFractionalMatching
+ Augmenting path algorithm for calculating maximum weighted
+ perfect fractional matching in general graphs.
\image html bipartite_matching.png
\image latex bipartite_matching.eps "Bipartite Matching" width=\textwidth
diff --git a/lemon/Makefile.am b/lemon/Makefile.am
--- a/lemon/Makefile.am
+++ b/lemon/Makefile.am
@@ -81,6 +81,7 @@
lemon/euler.h \
lemon/fib_heap.h \
lemon/fourary_heap.h \
+ lemon/fractional_matching.h \
lemon/full_graph.h \
lemon/glpk.h \
lemon/gomory_hu.h \
diff --git a/lemon/fractional_matching.h b/lemon/fractional_matching.h
new file mode 100644
--- /dev/null
+++ b/lemon/fractional_matching.h
@@ -0,0 +1,2135 @@
+/* -*- 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_FRACTIONAL_MATCHING_H
+#define LEMON_FRACTIONAL_MATCHING_H
+
+#include <vector>
+#include <queue>
+#include <set>
+#include <limits>
+
+#include <lemon/core.h>
+#include <lemon/unionfind.h>
+#include <lemon/bin_heap.h>
+#include <lemon/maps.h>
+#include <lemon/assert.h>
+#include <lemon/elevator.h>
+
+///\ingroup matching
+///\file
+///\brief Fractional matching algorithms in general graphs.
+
+namespace lemon {
+
+ /// \brief Default traits class of MaxFractionalMatching class.
+ ///
+ /// Default traits class of MaxFractionalMatching class.
+ /// \tparam GR Graph type.
+ template <typename GR>
+ struct MaxFractionalMatchingDefaultTraits {
+
+ /// \brief The type of the graph the algorithm runs on.
+ typedef GR Graph;
+
+ /// \brief The type of the map that stores the matching.
+ ///
+ /// The type of the map that stores the matching arcs.
+ /// It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
+ typedef typename Graph::template NodeMap<typename GR::Arc> MatchingMap;
+
+ /// \brief Instantiates a MatchingMap.
+ ///
+ /// This function instantiates a \ref MatchingMap.
+ /// \param graph The graph for which we would like to define
+ /// the matching map.
+ static MatchingMap* createMatchingMap(const Graph& graph) {
+ return new MatchingMap(graph);
+ }
+
+ /// \brief The elevator type used by MaxFractionalMatching algorithm.
+ ///
+ /// The elevator type used by MaxFractionalMatching algorithm.
+ ///
+ /// \sa Elevator
+ /// \sa LinkedElevator
+ typedef LinkedElevator<Graph, typename Graph::Node> Elevator;
+
+ /// \brief Instantiates an Elevator.
+ ///
+ /// This function instantiates an \ref Elevator.
+ /// \param graph The graph for which we would like to define
+ /// the elevator.
+ /// \param max_level The maximum level of the elevator.
+ static Elevator* createElevator(const Graph& graph, int max_level) {
+ return new Elevator(graph, max_level);
+ }
+ };
+
+ /// \ingroup matching
+ ///
+ /// \brief Max cardinality fractional matching
+ ///
+ /// This class provides an implementation of fractional matching
+ /// algorithm based on push-relabel principle.
+ ///
+ /// The maximum cardinality fractional matching is a relaxation of the
+ /// maximum cardinality matching problem where the odd set constraints
+ /// are omitted.
+ /// It can be formulated with the following linear program.
+ /// \f[ \sum_{e \in \delta(u)}x_e \le 1 \quad \forall u\in V\f]
+ /// \f[x_e \ge 0\quad \forall e\in E\f]
+ /// \f[\max \sum_{e\in E}x_e\f]
+ /// where \f$\delta(X)\f$ is the set of edges incident to a node in
+ /// \f$X\f$. The result can be represented as the union of a
+ /// matching with one value edges and a set of odd length cycles
+ /// with half value edges.
+ ///
+ /// The algorithm calculates an optimal fractional matching and a
+ /// barrier. The number of adjacents of any node set minus the size
+ /// of node set is a lower bound on the uncovered nodes in the
+ /// graph. For maximum matching a barrier is computed which
+ /// maximizes this difference.
+ ///
+ /// The algorithm can be executed with the run() function. After it
+ /// the matching (the primal solution) and the barrier (the dual
+ /// solution) can be obtained using the query functions.
+ ///
+ /// The primal solution is multiplied by
+ /// \ref MaxWeightedMatching::primalScale "2".
+ ///
+ /// \tparam GR The undirected graph type the algorithm runs on.
+#ifdef DOXYGEN
+ template <typename GR, typename TR>
+#else
+ template <typename GR,
+ typename TR = MaxFractionalMatchingDefaultTraits<GR> >
+#endif
+ class MaxFractionalMatching {
+ public:
+
+ /// \brief The \ref MaxFractionalMatchingDefaultTraits "traits
+ /// class" of the algorithm.
+ typedef TR Traits;
+ /// The type of the graph the algorithm runs on.
+ typedef typename TR::Graph Graph;
+ /// The type of the matching map.
+ typedef typename TR::MatchingMap MatchingMap;
+ /// The type of the elevator.
+ typedef typename TR::Elevator Elevator;
+
+ /// \brief Scaling factor for primal solution
+ ///
+ /// Scaling factor for primal solution.
+ static const int primalScale = 2;
+
+ private:
+
+ const Graph &_graph;
+ int _node_num;
+ bool _allow_loops;
+ int _empty_level;
+
+ TEMPLATE_GRAPH_TYPEDEFS(Graph);
+
+ bool _local_matching;
+ MatchingMap *_matching;
+
+ bool _local_level;
+ Elevator *_level;
+
+ typedef typename Graph::template NodeMap<int> InDegMap;
+ InDegMap *_indeg;
+
+ void createStructures() {
+ _node_num = countNodes(_graph);
+
+ if (!_matching) {
+ _local_matching = true;
+ _matching = Traits::createMatchingMap(_graph);
+ }
+ if (!_level) {
+ _local_level = true;
+ _level = Traits::createElevator(_graph, _node_num);
+ }
+ if (!_indeg) {
+ _indeg = new InDegMap(_graph);
+ }
+ }
+
+ void destroyStructures() {
+ if (_local_matching) {
+ delete _matching;
+ }
+ if (_local_level) {
+ delete _level;
+ }
+ if (_indeg) {
+ delete _indeg;
+ }
+ }
+
+ void postprocessing() {
+ for (NodeIt n(_graph); n != INVALID; ++n) {
+ if ((*_indeg)[n] != 0) continue;
+ _indeg->set(n, -1);
+ Node u = n;
+ while ((*_matching)[u] != INVALID) {
+ Node v = _graph.target((*_matching)[u]);
+ _indeg->set(v, -1);
+ Arc a = _graph.oppositeArc((*_matching)[u]);
+ u = _graph.target((*_matching)[v]);
+ _indeg->set(u, -1);
+ _matching->set(v, a);
+ }
+ }
+
+ for (NodeIt n(_graph); n != INVALID; ++n) {
+ if ((*_indeg)[n] != 1) continue;
+ _indeg->set(n, -1);
+
+ int num = 1;
+ Node u = _graph.target((*_matching)[n]);
+ while (u != n) {
+ _indeg->set(u, -1);
+ u = _graph.target((*_matching)[u]);
+ ++num;
+ }
+ if (num % 2 == 0 && num > 2) {
+ Arc prev = _graph.oppositeArc((*_matching)[n]);
+ Node v = _graph.target((*_matching)[n]);
+ u = _graph.target((*_matching)[v]);
+ _matching->set(v, prev);
+ while (u != n) {
+ prev = _graph.oppositeArc((*_matching)[u]);
+ v = _graph.target((*_matching)[u]);
+ u = _graph.target((*_matching)[v]);
+ _matching->set(v, prev);
+ }
+ }
+ }
+ }
+
+ public:
+
+ typedef MaxFractionalMatching Create;
+
+ ///\name Named Template Parameters
+
+ ///@{
+
+ template <typename T>
+ struct SetMatchingMapTraits : public Traits {
+ typedef T MatchingMap;
+ static MatchingMap *createMatchingMap(const Graph&) {
+ LEMON_ASSERT(false, "MatchingMap is not initialized");
+ return 0; // ignore warnings
+ }
+ };
+
+ /// \brief \ref named-templ-param "Named parameter" for setting
+ /// MatchingMap type
+ ///
+ /// \ref named-templ-param "Named parameter" for setting MatchingMap
+ /// type.
+ template <typename T>
+ struct SetMatchingMap
+ : public MaxFractionalMatching<Graph, SetMatchingMapTraits<T> > {
+ typedef MaxFractionalMatching<Graph, SetMatchingMapTraits<T> > Create;
+ };
+
+ template <typename T>
+ struct SetElevatorTraits : public Traits {
+ typedef T Elevator;
More information about the Lemon-commits
mailing list