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