edge_coloring.hpp 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  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. namespace detail {
  24. template<typename Graph, typename ColorMap>
  25. bool
  26. is_free(const Graph &g,
  27. 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. if (get(color, e) == free_color) {
  36. return false;
  37. }
  38. }
  39. return true;
  40. }
  41. template<typename Graph, typename ColorMap>
  42. std::vector<typename boost::graph_traits<Graph>::vertex_descriptor>
  43. maximal_fan(const Graph &g,
  44. ColorMap color,
  45. typename boost::graph_traits<Graph>::vertex_descriptor x,
  46. typename boost::graph_traits<Graph>::vertex_descriptor y)
  47. {
  48. typedef typename boost::graph_traits<Graph>::vertex_descriptor vertex_t;
  49. std::vector<vertex_t> fan;
  50. fan.push_back(y);
  51. bool extended;
  52. do {
  53. extended = false;
  54. BGL_FORALL_OUTEDGES_T(x, e, g, Graph) {
  55. vertex_t v = target(e, g);
  56. if (is_free(g, color, fan.back(), get(color, e)) &&
  57. std::find(fan.begin(), fan.end(), v) == fan.end()) {
  58. fan.push_back(v);
  59. extended = true;
  60. }
  61. }
  62. } while(extended);
  63. return fan;
  64. }
  65. template<typename Graph, typename ColorMap>
  66. typename boost::property_traits<ColorMap>::value_type
  67. find_free_color(const Graph &g,
  68. ColorMap color,
  69. typename boost::graph_traits<Graph>::vertex_descriptor u)
  70. {
  71. typename boost::property_traits<ColorMap>::value_type c = 0;
  72. while (!is_free(g, color, u, c)) c++;
  73. return c;
  74. }
  75. template<typename Graph, typename ColorMap>
  76. void
  77. invert_cd_path(const Graph &g,
  78. ColorMap color,
  79. typename boost::graph_traits<Graph>::vertex_descriptor x,
  80. typename boost::graph_traits<Graph>::edge_descriptor eold,
  81. typename boost::property_traits<ColorMap>::value_type c,
  82. typename boost::property_traits<ColorMap>::value_type d)
  83. {
  84. put(color, eold, d);
  85. BGL_FORALL_OUTEDGES_T(x, e, g, Graph) {
  86. if (get(color, e) == d && e != eold) {
  87. invert_cd_path(g, color, target(e, g), e, d, c);
  88. return;
  89. }
  90. }
  91. }
  92. template<typename Graph, typename ColorMap>
  93. void
  94. invert_cd_path(const Graph &g,
  95. ColorMap color,
  96. typename boost::graph_traits<Graph>::vertex_descriptor x,
  97. typename boost::property_traits<ColorMap>::value_type c,
  98. typename boost::property_traits<ColorMap>::value_type d)
  99. {
  100. BGL_FORALL_OUTEDGES_T(x, e, g, Graph) {
  101. if (get(color, e) == d) {
  102. invert_cd_path(g, color, target(e, g), e, d, c);
  103. return;
  104. }
  105. }
  106. }
  107. template<typename Graph, typename ColorMap, typename ForwardIterator>
  108. void
  109. rotate_fan(const Graph &g,
  110. ColorMap color,
  111. typename boost::graph_traits<Graph>::vertex_descriptor x,
  112. ForwardIterator begin,
  113. ForwardIterator end)
  114. {
  115. typedef typename boost::graph_traits<Graph>::edge_descriptor edge_t;
  116. if (begin == end) {
  117. return;
  118. }
  119. edge_t previous = edge(x, *begin, g).first;
  120. for (begin++; begin != end; begin++) {
  121. edge_t current = edge(x, *begin, g).first;
  122. put(color, previous, get(color, current));
  123. previous = current;
  124. }
  125. }
  126. template<typename Graph, typename ColorMap>
  127. class find_free_in_fan
  128. {
  129. public:
  130. find_free_in_fan(const Graph &graph,
  131. const ColorMap color,
  132. typename boost::property_traits<ColorMap>::value_type d)
  133. : graph(graph),
  134. color(color),
  135. d(d) {}
  136. bool operator()(const typename boost::graph_traits<Graph>::vertex_descriptor u) const {
  137. return is_free(graph, color, u, d);
  138. }
  139. private:
  140. const Graph &graph;
  141. const ColorMap color;
  142. const typename boost::property_traits<ColorMap>::value_type d;
  143. };
  144. }
  145. template<typename Graph, typename ColorMap>
  146. typename boost::property_traits<ColorMap>::value_type
  147. color_edge(const Graph &g,
  148. ColorMap color,
  149. typename boost::graph_traits<Graph>::edge_descriptor e)
  150. {
  151. typedef typename boost::graph_traits<Graph>::vertex_descriptor vertex_t;
  152. typedef typename boost::property_traits<ColorMap>::value_type color_t;
  153. typedef typename std::vector<vertex_t>::iterator fan_iterator;
  154. using namespace detail;
  155. vertex_t x = source(e, g), y = target(e, g);
  156. std::vector<vertex_t> fan = maximal_fan(g, color, x, y);
  157. color_t c = find_free_color(g, color, x);
  158. color_t d = find_free_color(g, color, fan.back());
  159. invert_cd_path(g, color, x, c, d);
  160. fan_iterator w = std::find_if(fan.begin(),
  161. fan.end(),
  162. find_free_in_fan<Graph, ColorMap>(g, color, d));
  163. rotate_fan(g, color, x, fan.begin(), w + 1);
  164. put(color, edge(x, *w, g).first, d);
  165. return (std::max)(c, d);
  166. }
  167. template<typename Graph, typename ColorMap>
  168. typename boost::property_traits<ColorMap>::value_type
  169. edge_coloring(const Graph &g,
  170. ColorMap color)
  171. {
  172. typedef typename boost::property_traits<ColorMap>::value_type color_t;
  173. BGL_FORALL_EDGES_T(e, g, Graph) {
  174. put(color, e, (std::numeric_limits<color_t>::max)());
  175. }
  176. color_t colors = 0;
  177. BGL_FORALL_EDGES_T(e, g, Graph) {
  178. colors = (std::max)(colors, color_edge(g, color, e) + 1);
  179. }
  180. return colors;
  181. }
  182. }
  183. #endif