summaryrefslogtreecommitdiff
path: root/boost/graph/edge_coloring.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/graph/edge_coloring.hpp')
-rw-r--r--boost/graph/edge_coloring.hpp196
1 files changed, 196 insertions, 0 deletions
diff --git a/boost/graph/edge_coloring.hpp b/boost/graph/edge_coloring.hpp
new file mode 100644
index 0000000000..8eb79ad43b
--- /dev/null
+++ b/boost/graph/edge_coloring.hpp
@@ -0,0 +1,196 @@
+//=======================================================================
+// Copyright 2013 Maciej Piechotka
+// Authors: Maciej Piechotka
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//=======================================================================
+#ifndef BOOST_GRAPH_EDGE_COLORING_HPP
+#define BOOST_GRAPH_EDGE_COLORING_HPP
+
+#include <boost/graph/graph_traits.hpp>
+#include <boost/graph/iteration_macros.hpp>
+#include <boost/graph/properties.hpp>
+#include <algorithm>
+#include <limits>
+#include <vector>
+
+/* This algorithm is to find coloring of an edges
+
+ Reference:
+
+ Misra, J., & Gries, D. (1992). A constructive proof of Vizing's
+ theorem. In Information Processing Letters.
+*/
+
+namespace boost {
+ namespace detail {
+ template<typename Graph, typename ColorMap>
+ bool
+ is_free(const Graph &g,
+ ColorMap color,
+ typename boost::graph_traits<Graph>::vertex_descriptor u,
+ typename boost::property_traits<ColorMap>::value_type free_color)
+ {
+ typedef typename boost::property_traits<ColorMap>::value_type color_t;
+ if (free_color == (std::numeric_limits<color_t>::max)())
+ return false;
+ BGL_FORALL_OUTEDGES_T(u, e, g, Graph) {
+ if (get(color, e) == free_color) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ template<typename Graph, typename ColorMap>
+ std::vector<typename boost::graph_traits<Graph>::vertex_descriptor>
+ maximal_fan(const Graph &g,
+ ColorMap color,
+ typename boost::graph_traits<Graph>::vertex_descriptor x,
+ typename boost::graph_traits<Graph>::vertex_descriptor y)
+ {
+ typedef typename boost::graph_traits<Graph>::vertex_descriptor vertex_t;
+ std::vector<vertex_t> fan;
+ fan.push_back(y);
+ bool extended;
+ do {
+ extended = false;
+ BGL_FORALL_OUTEDGES_T(x, e, g, Graph) {
+ vertex_t v = target(e, g);
+ if (is_free(g, color, fan.back(), get(color, e)) &&
+ std::find(fan.begin(), fan.end(), v) == fan.end()) {
+ fan.push_back(v);
+ extended = true;
+ }
+ }
+ } while(extended);
+ return fan;
+ }
+ template<typename Graph, typename ColorMap>
+ typename boost::property_traits<ColorMap>::value_type
+ find_free_color(const Graph &g,
+ ColorMap color,
+ typename boost::graph_traits<Graph>::vertex_descriptor u)
+ {
+ typename boost::property_traits<ColorMap>::value_type c = 0;
+ while (!is_free(g, color, u, c)) c++;
+ return c;
+ }
+
+ template<typename Graph, typename ColorMap>
+ void
+ invert_cd_path(const Graph &g,
+ ColorMap color,
+ typename boost::graph_traits<Graph>::vertex_descriptor x,
+ typename boost::graph_traits<Graph>::edge_descriptor eold,
+ typename boost::property_traits<ColorMap>::value_type c,
+ typename boost::property_traits<ColorMap>::value_type d)
+ {
+ put(color, eold, d);
+ BGL_FORALL_OUTEDGES_T(x, e, g, Graph) {
+ if (get(color, e) == d && e != eold) {
+ invert_cd_path(g, color, target(e, g), e, d, c);
+ return;
+ }
+ }
+ }
+
+ template<typename Graph, typename ColorMap>
+ void
+ invert_cd_path(const Graph &g,
+ ColorMap color,
+ typename boost::graph_traits<Graph>::vertex_descriptor x,
+ typename boost::property_traits<ColorMap>::value_type c,
+ typename boost::property_traits<ColorMap>::value_type d)
+ {
+ BGL_FORALL_OUTEDGES_T(x, e, g, Graph) {
+ if (get(color, e) == d) {
+ invert_cd_path(g, color, target(e, g), e, d, c);
+ return;
+ }
+ }
+ }
+
+ template<typename Graph, typename ColorMap, typename ForwardIterator>
+ void
+ rotate_fan(const Graph &g,
+ ColorMap color,
+ typename boost::graph_traits<Graph>::vertex_descriptor x,
+ ForwardIterator begin,
+ ForwardIterator end)
+ {
+ typedef typename boost::graph_traits<Graph>::edge_descriptor edge_t;
+ if (begin == end) {
+ return;
+ }
+ edge_t previous = edge(x, *begin, g).first;
+ for (begin++; begin != end; begin++) {
+ edge_t current = edge(x, *begin, g).first;
+ put(color, previous, get(color, current));
+ previous = current;
+ }
+ }
+
+ template<typename Graph, typename ColorMap>
+ class find_free_in_fan
+ {
+ public:
+ find_free_in_fan(const Graph &graph,
+ const ColorMap color,
+ typename boost::property_traits<ColorMap>::value_type d)
+ : graph(graph),
+ color(color),
+ d(d) {}
+ bool operator()(const typename boost::graph_traits<Graph>::vertex_descriptor u) const {
+ return is_free(graph, color, u, d);
+ }
+ private:
+ const Graph &graph;
+ const ColorMap color;
+ const typename boost::property_traits<ColorMap>::value_type d;
+ };
+ }
+
+ template<typename Graph, typename ColorMap>
+ typename boost::property_traits<ColorMap>::value_type
+ color_edge(const Graph &g,
+ ColorMap color,
+ typename boost::graph_traits<Graph>::edge_descriptor e)
+ {
+ typedef typename boost::graph_traits<Graph>::vertex_descriptor vertex_t;
+ typedef typename boost::property_traits<ColorMap>::value_type color_t;
+ typedef typename std::vector<vertex_t>::iterator fan_iterator;
+ using namespace detail;
+ vertex_t x = source(e, g), y = target(e, g);
+ std::vector<vertex_t> fan = maximal_fan(g, color, x, y);
+ color_t c = find_free_color(g, color, x);
+ color_t d = find_free_color(g, color, fan.back());
+ invert_cd_path(g, color, x, c, d);
+ fan_iterator w = std::find_if(fan.begin(),
+ fan.end(),
+ find_free_in_fan<Graph, ColorMap>(g, color, d));
+ rotate_fan(g, color, x, fan.begin(), w + 1);
+ put(color, edge(x, *w, g).first, d);
+ return (std::max)(c, d);
+ }
+
+ template<typename Graph, typename ColorMap>
+ typename boost::property_traits<ColorMap>::value_type
+ edge_coloring(const Graph &g,
+ ColorMap color)
+ {
+ typedef typename boost::property_traits<ColorMap>::value_type color_t;
+ BGL_FORALL_EDGES_T(e, g, Graph) {
+ put(color, e, (std::numeric_limits<color_t>::max)());
+ }
+ color_t colors = 0;
+ BGL_FORALL_EDGES_T(e, g, Graph) {
+ colors = (std::max)(colors, color_edge(g, color, e) + 1);
+ }
+ return colors;
+ }
+}
+
+#endif