floyd_warshall_shortest.hpp 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  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. template<typename T, typename BinaryPredicate>
  33. T min_with_compare(const T& x, const T& y, const BinaryPredicate& compare)
  34. {
  35. if (compare(x, y)) return x;
  36. else return y;
  37. }
  38. template<typename VertexListGraph, typename DistanceMatrix,
  39. typename BinaryPredicate, typename BinaryFunction,
  40. typename Infinity, typename Zero>
  41. bool floyd_warshall_dispatch(const VertexListGraph& g,
  42. DistanceMatrix& d, const BinaryPredicate &compare,
  43. const BinaryFunction &combine, const Infinity& inf,
  44. const Zero& zero)
  45. {
  46. typename graph_traits<VertexListGraph>::vertex_iterator
  47. i, lasti, j, lastj, k, lastk;
  48. for (boost::tie(k, lastk) = vertices(g); k != lastk; k++)
  49. for (boost::tie(i, lasti) = vertices(g); i != lasti; i++)
  50. if(d[*i][*k] != inf)
  51. for (boost::tie(j, lastj) = vertices(g); j != lastj; j++)
  52. if(d[*k][*j] != inf)
  53. d[*i][*j] =
  54. detail::min_with_compare(d[*i][*j],
  55. combine(d[*i][*k], d[*k][*j]),
  56. 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,
  65. typename Infinity, typename Zero>
  66. bool floyd_warshall_initialized_all_pairs_shortest_paths(
  67. const VertexListGraph& g, DistanceMatrix& d,
  68. const BinaryPredicate& compare,
  69. const BinaryFunction& combine, const Infinity& inf,
  70. const Zero& zero)
  71. {
  72. BOOST_CONCEPT_ASSERT(( VertexListGraphConcept<VertexListGraph> ));
  73. return detail::floyd_warshall_dispatch(g, d, compare, combine,
  74. inf, zero);
  75. }
  76. template <typename VertexAndEdgeListGraph, typename DistanceMatrix,
  77. typename WeightMap, typename BinaryPredicate,
  78. typename BinaryFunction, typename Infinity, typename Zero>
  79. bool floyd_warshall_all_pairs_shortest_paths(
  80. const VertexAndEdgeListGraph& g,
  81. DistanceMatrix& d, const WeightMap& w,
  82. const BinaryPredicate& compare, const BinaryFunction& combine,
  83. const Infinity& inf, const Zero& zero)
  84. {
  85. BOOST_CONCEPT_ASSERT(( VertexListGraphConcept<VertexAndEdgeListGraph> ));
  86. BOOST_CONCEPT_ASSERT(( EdgeListGraphConcept<VertexAndEdgeListGraph> ));
  87. BOOST_CONCEPT_ASSERT(( IncidenceGraphConcept<VertexAndEdgeListGraph> ));
  88. typename graph_traits<VertexAndEdgeListGraph>::vertex_iterator
  89. firstv, lastv, firstv2, lastv2;
  90. typename graph_traits<VertexAndEdgeListGraph>::edge_iterator first, last;
  91. for(boost::tie(firstv, lastv) = vertices(g); firstv != lastv; firstv++)
  92. for(boost::tie(firstv2, lastv2) = vertices(g); firstv2 != lastv2; firstv2++)
  93. d[*firstv][*firstv2] = inf;
  94. for(boost::tie(firstv, lastv) = vertices(g); firstv != lastv; firstv++)
  95. d[*firstv][*firstv] = zero;
  96. for(boost::tie(first, last) = edges(g); first != last; first++)
  97. {
  98. if (d[source(*first, g)][target(*first, g)] != inf) {
  99. d[source(*first, g)][target(*first, g)] =
  100. detail::min_with_compare(
  101. get(w, *first),
  102. d[source(*first, g)][target(*first, g)],
  103. compare);
  104. } else
  105. d[source(*first, g)][target(*first, g)] = get(w, *first);
  106. }
  107. bool is_undirected = is_same<typename
  108. graph_traits<VertexAndEdgeListGraph>::directed_category,
  109. undirected_tag>::value;
  110. if (is_undirected)
  111. {
  112. for(boost::tie(first, last) = edges(g); first != last; first++)
  113. {
  114. if (d[target(*first, g)][source(*first, g)] != inf)
  115. d[target(*first, g)][source(*first, g)] =
  116. detail::min_with_compare(
  117. get(w, *first),
  118. d[target(*first, g)][source(*first, g)],
  119. compare);
  120. else
  121. d[target(*first, g)][source(*first, g)] = get(w, *first);
  122. }
  123. }
  124. return detail::floyd_warshall_dispatch(g, d, compare, combine,
  125. inf, zero);
  126. }
  127. namespace detail {
  128. template <class VertexListGraph, class DistanceMatrix,
  129. class WeightMap, class P, class T, class R>
  130. bool floyd_warshall_init_dispatch(const VertexListGraph& g,
  131. DistanceMatrix& d, WeightMap /*w*/,
  132. const bgl_named_params<P, T, R>& params)
  133. {
  134. typedef typename property_traits<WeightMap>::value_type WM;
  135. WM inf =
  136. choose_param(get_param(params, distance_inf_t()),
  137. std::numeric_limits<WM>::max BOOST_PREVENT_MACRO_SUBSTITUTION());
  138. return floyd_warshall_initialized_all_pairs_shortest_paths(g, d,
  139. choose_param(get_param(params, distance_compare_t()),
  140. std::less<WM>()),
  141. choose_param(get_param(params, distance_combine_t()),
  142. closed_plus<WM>(inf)),
  143. inf,
  144. choose_param(get_param(params, distance_zero_t()),
  145. WM()));
  146. }
  147. template <class VertexAndEdgeListGraph, class DistanceMatrix,
  148. class WeightMap, class P, class T, class R>
  149. bool floyd_warshall_noninit_dispatch(const VertexAndEdgeListGraph& g,
  150. DistanceMatrix& d, WeightMap w,
  151. const bgl_named_params<P, T, R>& params)
  152. {
  153. typedef typename property_traits<WeightMap>::value_type WM;
  154. WM inf =
  155. choose_param(get_param(params, distance_inf_t()),
  156. std::numeric_limits<WM>::max BOOST_PREVENT_MACRO_SUBSTITUTION());
  157. return floyd_warshall_all_pairs_shortest_paths(g, d, w,
  158. choose_param(get_param(params, distance_compare_t()),
  159. std::less<WM>()),
  160. choose_param(get_param(params, distance_combine_t()),
  161. closed_plus<WM>(inf)),
  162. inf,
  163. choose_param(get_param(params, distance_zero_t()),
  164. WM()));
  165. }
  166. } // namespace detail
  167. template <class VertexListGraph, class DistanceMatrix, class P,
  168. class T, class R>
  169. bool floyd_warshall_initialized_all_pairs_shortest_paths(
  170. const VertexListGraph& g, DistanceMatrix& d,
  171. const bgl_named_params<P, T, R>& params)
  172. {
  173. return detail::floyd_warshall_init_dispatch(g, d,
  174. choose_const_pmap(get_param(params, edge_weight), g, edge_weight),
  175. params);
  176. }
  177. template <class VertexListGraph, class DistanceMatrix>
  178. bool floyd_warshall_initialized_all_pairs_shortest_paths(
  179. const VertexListGraph& g, DistanceMatrix& d)
  180. {
  181. bgl_named_params<int,int> params(0);
  182. return detail::floyd_warshall_init_dispatch(g, d,
  183. get(edge_weight, g), params);
  184. }
  185. template <class VertexAndEdgeListGraph, class DistanceMatrix,
  186. class P, class T, class R>
  187. bool floyd_warshall_all_pairs_shortest_paths(
  188. const VertexAndEdgeListGraph& g, DistanceMatrix& d,
  189. const bgl_named_params<P, T, R>& params)
  190. {
  191. return detail::floyd_warshall_noninit_dispatch(g, d,
  192. choose_const_pmap(get_param(params, edge_weight), g, edge_weight),
  193. params);
  194. }
  195. template <class VertexAndEdgeListGraph, class DistanceMatrix>
  196. bool floyd_warshall_all_pairs_shortest_paths(
  197. const VertexAndEdgeListGraph& g, DistanceMatrix& d)
  198. {
  199. bgl_named_params<int,int> params(0);
  200. return detail::floyd_warshall_noninit_dispatch(g, d,
  201. get(edge_weight, g), params);
  202. }
  203. } // namespace boost
  204. #endif