floyd_warshall_shortest.hpp 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. // Copyright 2002 Rensselaer Polytechnic Institute
  2. // Distributed under the Boost Software License, Version 1.0.
  3. // (See accompanying file LICENSE_1_0.txt or copy at
  4. // http://www.boost.org/LICENSE_1_0.txt)
  5. // Authors: Lauren Foutz
  6. // Scott Hill
  7. /*
  8. This file implements the functions
  9. template <class VertexListGraph, class DistanceMatrix,
  10. class P, class T, class R>
  11. bool floyd_warshall_initialized_all_pairs_shortest_paths(
  12. const VertexListGraph& g, DistanceMatrix& d,
  13. const bgl_named_params<P, T, R>& params)
  14. AND
  15. template <class VertexAndEdgeListGraph, class DistanceMatrix,
  16. class P, class T, class R>
  17. bool floyd_warshall_all_pairs_shortest_paths(
  18. const VertexAndEdgeListGraph& g, DistanceMatrix& d,
  19. const bgl_named_params<P, T, R>& params)
  20. */
  21. #ifndef BOOST_GRAPH_FLOYD_WARSHALL_HPP
  22. #define BOOST_GRAPH_FLOYD_WARSHALL_HPP
  23. #include <boost/property_map/property_map.hpp>
  24. #include <boost/graph/graph_traits.hpp>
  25. #include <boost/graph/named_function_params.hpp>
  26. #include <boost/graph/graph_concepts.hpp>
  27. #include <boost/graph/relax.hpp>
  28. #include <boost/concept/assert.hpp>
  29. namespace boost
  30. {
  31. namespace detail
  32. {
  33. template < typename T, typename BinaryPredicate >
  34. T min_with_compare(const T& x, const T& y, const BinaryPredicate& compare)
  35. {
  36. if (compare(x, y))
  37. return x;
  38. else
  39. return y;
  40. }
  41. template < typename VertexListGraph, typename DistanceMatrix,
  42. typename BinaryPredicate, typename BinaryFunction, typename Infinity,
  43. typename Zero >
  44. bool floyd_warshall_dispatch(const VertexListGraph& g, DistanceMatrix& d,
  45. const BinaryPredicate& compare, const BinaryFunction& combine,
  46. const Infinity& inf, const Zero& zero)
  47. {
  48. typename graph_traits< VertexListGraph >::vertex_iterator i, lasti, j,
  49. lastj, k, lastk;
  50. for (boost::tie(k, lastk) = vertices(g); k != lastk; k++)
  51. for (boost::tie(i, lasti) = vertices(g); i != lasti; i++)
  52. if (d[*i][*k] != inf)
  53. for (boost::tie(j, lastj) = vertices(g); j != lastj; j++)
  54. if (d[*k][*j] != inf)
  55. d[*i][*j] = detail::min_with_compare(d[*i][*j],
  56. combine(d[*i][*k], d[*k][*j]), compare);
  57. for (boost::tie(i, lasti) = vertices(g); i != lasti; i++)
  58. if (compare(d[*i][*i], zero))
  59. return false;
  60. return true;
  61. }
  62. }
  63. template < typename VertexListGraph, typename DistanceMatrix,
  64. typename BinaryPredicate, typename BinaryFunction, typename Infinity,
  65. typename Zero >
  66. bool floyd_warshall_initialized_all_pairs_shortest_paths(
  67. const VertexListGraph& g, DistanceMatrix& d, const BinaryPredicate& compare,
  68. const BinaryFunction& combine, const Infinity& inf, const Zero& zero)
  69. {
  70. BOOST_CONCEPT_ASSERT((VertexListGraphConcept< VertexListGraph >));
  71. return detail::floyd_warshall_dispatch(g, d, compare, combine, inf, zero);
  72. }
  73. template < typename VertexAndEdgeListGraph, typename DistanceMatrix,
  74. typename WeightMap, typename BinaryPredicate, typename BinaryFunction,
  75. typename Infinity, typename Zero >
  76. bool floyd_warshall_all_pairs_shortest_paths(const VertexAndEdgeListGraph& g,
  77. DistanceMatrix& d, const WeightMap& w, const BinaryPredicate& compare,
  78. const BinaryFunction& combine, const Infinity& inf, const Zero& zero)
  79. {
  80. BOOST_CONCEPT_ASSERT((VertexListGraphConcept< VertexAndEdgeListGraph >));
  81. BOOST_CONCEPT_ASSERT((EdgeListGraphConcept< VertexAndEdgeListGraph >));
  82. BOOST_CONCEPT_ASSERT((IncidenceGraphConcept< VertexAndEdgeListGraph >));
  83. typename graph_traits< VertexAndEdgeListGraph >::vertex_iterator firstv,
  84. lastv, firstv2, lastv2;
  85. typename graph_traits< VertexAndEdgeListGraph >::edge_iterator first, last;
  86. for (boost::tie(firstv, lastv) = vertices(g); firstv != lastv; firstv++)
  87. for (boost::tie(firstv2, lastv2) = vertices(g); firstv2 != lastv2;
  88. firstv2++)
  89. d[*firstv][*firstv2] = inf;
  90. for (boost::tie(firstv, lastv) = vertices(g); firstv != lastv; firstv++)
  91. d[*firstv][*firstv] = zero;
  92. for (boost::tie(first, last) = edges(g); first != last; first++)
  93. {
  94. if (d[source(*first, g)][target(*first, g)] != inf)
  95. {
  96. d[source(*first, g)][target(*first, g)]
  97. = detail::min_with_compare(get(w, *first),
  98. d[source(*first, g)][target(*first, g)], compare);
  99. }
  100. else
  101. d[source(*first, g)][target(*first, g)] = get(w, *first);
  102. }
  103. bool is_undirected = is_same<
  104. typename graph_traits< VertexAndEdgeListGraph >::directed_category,
  105. undirected_tag >::value;
  106. if (is_undirected)
  107. {
  108. for (boost::tie(first, last) = edges(g); first != last; first++)
  109. {
  110. if (d[target(*first, g)][source(*first, g)] != inf)
  111. d[target(*first, g)][source(*first, g)]
  112. = detail::min_with_compare(get(w, *first),
  113. d[target(*first, g)][source(*first, g)], compare);
  114. else
  115. d[target(*first, g)][source(*first, g)] = get(w, *first);
  116. }
  117. }
  118. return detail::floyd_warshall_dispatch(g, d, compare, combine, inf, zero);
  119. }
  120. namespace detail
  121. {
  122. template < class VertexListGraph, class DistanceMatrix, class WeightMap,
  123. class P, class T, class R >
  124. bool floyd_warshall_init_dispatch(const VertexListGraph& g,
  125. DistanceMatrix& d, WeightMap /*w*/,
  126. const bgl_named_params< P, T, R >& params)
  127. {
  128. typedef typename property_traits< WeightMap >::value_type WM;
  129. WM inf = choose_param(get_param(params, distance_inf_t()),
  130. std::numeric_limits< WM >::max BOOST_PREVENT_MACRO_SUBSTITUTION());
  131. return floyd_warshall_initialized_all_pairs_shortest_paths(g, d,
  132. choose_param(
  133. get_param(params, distance_compare_t()), std::less< WM >()),
  134. choose_param(get_param(params, distance_combine_t()),
  135. closed_plus< WM >(inf)),
  136. inf, choose_param(get_param(params, distance_zero_t()), WM()));
  137. }
  138. template < class VertexAndEdgeListGraph, class DistanceMatrix,
  139. class WeightMap, class P, class T, class R >
  140. bool floyd_warshall_noninit_dispatch(const VertexAndEdgeListGraph& g,
  141. DistanceMatrix& d, WeightMap w,
  142. const bgl_named_params< P, T, R >& params)
  143. {
  144. typedef typename property_traits< WeightMap >::value_type WM;
  145. WM inf = choose_param(get_param(params, distance_inf_t()),
  146. std::numeric_limits< WM >::max BOOST_PREVENT_MACRO_SUBSTITUTION());
  147. return floyd_warshall_all_pairs_shortest_paths(g, d, w,
  148. choose_param(
  149. get_param(params, distance_compare_t()), std::less< WM >()),
  150. choose_param(get_param(params, distance_combine_t()),
  151. closed_plus< WM >(inf)),
  152. inf, choose_param(get_param(params, distance_zero_t()), WM()));
  153. }
  154. } // namespace detail
  155. template < class VertexListGraph, class DistanceMatrix, class P, class T,
  156. class R >
  157. bool floyd_warshall_initialized_all_pairs_shortest_paths(
  158. const VertexListGraph& g, DistanceMatrix& d,
  159. const bgl_named_params< P, T, R >& params)
  160. {
  161. return detail::floyd_warshall_init_dispatch(g, d,
  162. choose_const_pmap(get_param(params, edge_weight), g, edge_weight),
  163. params);
  164. }
  165. template < class VertexListGraph, class DistanceMatrix >
  166. bool floyd_warshall_initialized_all_pairs_shortest_paths(
  167. const VertexListGraph& g, DistanceMatrix& d)
  168. {
  169. bgl_named_params< int, int > params(0);
  170. return detail::floyd_warshall_init_dispatch(
  171. g, d, get(edge_weight, g), params);
  172. }
  173. template < class VertexAndEdgeListGraph, class DistanceMatrix, class P, class T,
  174. class R >
  175. bool floyd_warshall_all_pairs_shortest_paths(const VertexAndEdgeListGraph& g,
  176. DistanceMatrix& d, const bgl_named_params< P, T, R >& params)
  177. {
  178. return detail::floyd_warshall_noninit_dispatch(g, d,
  179. choose_const_pmap(get_param(params, edge_weight), g, edge_weight),
  180. params);
  181. }
  182. template < class VertexAndEdgeListGraph, class DistanceMatrix >
  183. bool floyd_warshall_all_pairs_shortest_paths(
  184. const VertexAndEdgeListGraph& g, DistanceMatrix& d)
  185. {
  186. bgl_named_params< int, int > params(0);
  187. return detail::floyd_warshall_noninit_dispatch(
  188. g, d, get(edge_weight, g), params);
  189. }
  190. } // namespace boost
  191. #endif