edge_coloring.hpp 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. //=======================================================================
  2. // Copyright 2013 Maciej Piechotka
  3. // Authors: Maciej Piechotka
  4. //
  5. // Distributed under the Boost Software License, Version 1.0. (See
  6. // accompanying file LICENSE_1_0.txt or copy at
  7. // http://www.boost.org/LICENSE_1_0.txt)
  8. //=======================================================================
  9. #ifndef BOOST_GRAPH_EDGE_COLORING_HPP
  10. #define BOOST_GRAPH_EDGE_COLORING_HPP
  11. #include <boost/graph/graph_traits.hpp>
  12. #include <boost/graph/iteration_macros.hpp>
  13. #include <boost/graph/properties.hpp>
  14. #include <algorithm>
  15. #include <limits>
  16. #include <vector>
  17. /* This algorithm is to find coloring of an edges
  18. Reference:
  19. Misra, J., & Gries, D. (1992). A constructive proof of Vizing's
  20. theorem. In Information Processing Letters.
  21. */
  22. namespace boost
  23. {
  24. namespace detail
  25. {
  26. template < typename Graph, typename ColorMap >
  27. bool is_free(const Graph& g, ColorMap color,
  28. typename boost::graph_traits< Graph >::vertex_descriptor u,
  29. typename boost::property_traits< ColorMap >::value_type free_color)
  30. {
  31. typedef typename boost::property_traits< ColorMap >::value_type color_t;
  32. if (free_color == (std::numeric_limits< color_t >::max)())
  33. return false;
  34. BGL_FORALL_OUTEDGES_T(u, e, g, Graph)
  35. {
  36. if (get(color, e) == free_color)
  37. {
  38. return false;
  39. }
  40. }
  41. return true;
  42. }
  43. template < typename Graph, typename ColorMap >
  44. std::vector< typename boost::graph_traits< Graph >::vertex_descriptor >
  45. maximal_fan(const Graph& g, ColorMap color,
  46. typename boost::graph_traits< Graph >::vertex_descriptor x,
  47. typename boost::graph_traits< Graph >::vertex_descriptor y)
  48. {
  49. typedef
  50. typename boost::graph_traits< Graph >::vertex_descriptor vertex_t;
  51. std::vector< vertex_t > fan;
  52. fan.push_back(y);
  53. bool extended;
  54. do
  55. {
  56. extended = false;
  57. BGL_FORALL_OUTEDGES_T(x, e, g, Graph)
  58. {
  59. vertex_t v = target(e, g);
  60. if (is_free(g, color, fan.back(), get(color, e))
  61. && std::find(fan.begin(), fan.end(), v) == fan.end())
  62. {
  63. fan.push_back(v);
  64. extended = true;
  65. }
  66. }
  67. } while (extended);
  68. return fan;
  69. }
  70. template < typename Graph, typename ColorMap >
  71. typename boost::property_traits< ColorMap >::value_type find_free_color(
  72. const Graph& g, ColorMap color,
  73. typename boost::graph_traits< Graph >::vertex_descriptor u)
  74. {
  75. typename boost::property_traits< ColorMap >::value_type c = 0;
  76. while (!is_free(g, color, u, c))
  77. c++;
  78. return c;
  79. }
  80. template < typename Graph, typename ColorMap >
  81. void invert_cd_path(const Graph& g, ColorMap color,
  82. typename boost::graph_traits< Graph >::vertex_descriptor x,
  83. typename boost::graph_traits< Graph >::edge_descriptor eold,
  84. typename boost::property_traits< ColorMap >::value_type c,
  85. typename boost::property_traits< ColorMap >::value_type d)
  86. {
  87. put(color, eold, d);
  88. BGL_FORALL_OUTEDGES_T(x, e, g, Graph)
  89. {
  90. if (get(color, e) == d && e != eold)
  91. {
  92. invert_cd_path(g, color, target(e, g), e, d, c);
  93. return;
  94. }
  95. }
  96. }
  97. template < typename Graph, typename ColorMap >
  98. void invert_cd_path(const Graph& g, ColorMap color,
  99. typename boost::graph_traits< Graph >::vertex_descriptor x,
  100. typename boost::property_traits< ColorMap >::value_type c,
  101. typename boost::property_traits< ColorMap >::value_type d)
  102. {
  103. BGL_FORALL_OUTEDGES_T(x, e, g, Graph)
  104. {
  105. if (get(color, e) == d)
  106. {
  107. invert_cd_path(g, color, target(e, g), e, d, c);
  108. return;
  109. }
  110. }
  111. }
  112. template < typename Graph, typename ColorMap, typename ForwardIterator >
  113. void rotate_fan(const Graph& g, ColorMap color,
  114. typename boost::graph_traits< Graph >::vertex_descriptor x,
  115. ForwardIterator begin, ForwardIterator end)
  116. {
  117. typedef typename boost::graph_traits< Graph >::edge_descriptor edge_t;
  118. if (begin == end)
  119. {
  120. return;
  121. }
  122. edge_t previous = edge(x, *begin, g).first;
  123. for (begin++; begin != end; begin++)
  124. {
  125. edge_t current = edge(x, *begin, g).first;
  126. put(color, previous, get(color, current));
  127. previous = current;
  128. }
  129. }
  130. template < typename Graph, typename ColorMap > class find_free_in_fan
  131. {
  132. public:
  133. find_free_in_fan(const Graph& graph, const ColorMap color,
  134. typename boost::property_traits< ColorMap >::value_type d)
  135. : graph(graph), color(color), d(d)
  136. {
  137. }
  138. bool operator()(
  139. const typename boost::graph_traits< Graph >::vertex_descriptor u)
  140. const
  141. {
  142. return is_free(graph, color, u, d);
  143. }
  144. private:
  145. const Graph& graph;
  146. const ColorMap color;
  147. const typename boost::property_traits< ColorMap >::value_type d;
  148. };
  149. }
  150. template < typename Graph, typename ColorMap >
  151. typename boost::property_traits< ColorMap >::value_type color_edge(
  152. const Graph& g, ColorMap color,
  153. typename boost::graph_traits< Graph >::edge_descriptor e)
  154. {
  155. typedef typename boost::graph_traits< Graph >::vertex_descriptor vertex_t;
  156. typedef typename boost::property_traits< ColorMap >::value_type color_t;
  157. typedef typename std::vector< vertex_t >::iterator fan_iterator;
  158. using namespace detail;
  159. vertex_t x = source(e, g), y = target(e, g);
  160. std::vector< vertex_t > fan = maximal_fan(g, color, x, y);
  161. color_t c = find_free_color(g, color, x);
  162. color_t d = find_free_color(g, color, fan.back());
  163. invert_cd_path(g, color, x, c, d);
  164. fan_iterator w = std::find_if(fan.begin(), fan.end(),
  165. find_free_in_fan< Graph, ColorMap >(g, color, d));
  166. rotate_fan(g, color, x, fan.begin(), w + 1);
  167. put(color, edge(x, *w, g).first, d);
  168. return (std::max)(c, d);
  169. }
  170. template < typename Graph, typename ColorMap >
  171. typename boost::property_traits< ColorMap >::value_type edge_coloring(
  172. const Graph& g, ColorMap color)
  173. {
  174. typedef typename boost::property_traits< ColorMap >::value_type color_t;
  175. BGL_FORALL_EDGES_T(e, g, Graph)
  176. {
  177. put(color, e, (std::numeric_limits< color_t >::max)());
  178. }
  179. color_t colors = 0;
  180. BGL_FORALL_EDGES_T(e, g, Graph)
  181. {
  182. colors = (std::max)(colors, color_edge(g, color, e) + 1);
  183. }
  184. return colors;
  185. }
  186. }
  187. #endif