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