Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_34_1/libs/graph/test/floyd_warshall_test.cpp @ 47

Last change on this file since 47 was 29, checked in by landauf, 17 years ago

updated boost from 1_33_1 to 1_34_1

File size: 15.1 KB
Line 
1// Copyright 2002 Rensselaer Polytechnic Institute
2
3// Use, modification and distribution is subject to the Boost Software
4// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
5// http://www.boost.org/LICENSE_1_0.txt)
6
7//  Authors: Lauren Foutz
8//           Scott Hill
9#include <boost/graph/floyd_warshall_shortest.hpp>
10#include <map>
11#include <algorithm>
12#include <iostream>
13#include <boost/random/linear_congruential.hpp>
14#include <boost/graph/graph_utility.hpp>
15#include <boost/graph/properties.hpp>
16#include <boost/graph/bellman_ford_shortest_paths.hpp>
17#include <boost/graph/random.hpp>
18#include <boost/graph/adjacency_list.hpp>
19#include <boost/graph/adjacency_matrix.hpp>
20#include <boost/test/minimal.hpp>
21#include <algorithm>
22using namespace boost;
23
24template <typename T>
25struct inf_plus{
26  T operator()(const T& a, const T& b) const {
27    T inf = std::numeric_limits<T>::max BOOST_PREVENT_MACRO_SUBSTITUTION();
28    if (a == inf || b == inf){
29      return inf;
30    }
31    return a + b;
32  }
33};
34
35template<typename T>
36inline const T& my_min(const T& x, const T& y) 
37{ return x < y? x : y; }
38
39template<typename Graph>
40bool acceptance_test(Graph& g, int vec, int e)
41{
42  boost::minstd_rand ran(vec);
43
44  {
45    typename boost::property_map<Graph, boost::vertex_name_t>::type index =
46      boost::get(boost::vertex_name, g);
47    typename boost::graph_traits<Graph>::vertex_iterator firstv, lastv,
48      firstv2, lastv2;
49    int x = 0;
50    for(boost::tie(firstv, lastv) = boost::vertices(g); firstv != lastv;
51        firstv++){
52      boost::put(index, *firstv, x);
53      x++;
54    }
55
56
57    for(int i = 0; i < e; i++){
58      boost::add_edge(index[ran() % vec], index[ran() % vec], g);
59    }
60
61
62    typename boost::graph_traits<Graph>::edge_iterator first, last;
63    typename boost::property_map<Graph, boost::edge_weight_t>::type
64      local_edge_map = boost::get(boost::edge_weight, g);
65    for(boost::tie(first, last) = boost::edges(g); first != last; first++){
66      if (ran() % vec != 0){
67        boost::put(local_edge_map, *first, ran() % 100);
68      } else {
69        boost::put(local_edge_map, *first, 0 - (ran() % 100));
70      }
71    }
72
73    int int_inf =
74      std::numeric_limits<int>::max BOOST_PREVENT_MACRO_SUBSTITUTION();
75    typedef typename boost::graph_traits<Graph>::vertex_descriptor vertex_des;
76    std::map<vertex_des,int> matrixRow;
77    std::map<vertex_des, std::map<vertex_des ,int> > matrix;
78    typedef typename boost::property_map<Graph, boost::vertex_distance_t>::type
79      distance_type;
80    distance_type distance_row = boost::get(boost::vertex_distance, g);
81    for(boost::tie(firstv, lastv) = boost::vertices(g); firstv != lastv;
82        firstv++){
83      boost::put(distance_row, *firstv, int_inf);
84      matrixRow[*firstv] = int_inf;
85    }
86    for(boost::tie(firstv, lastv) = boost::vertices(g); firstv != lastv;
87        firstv++){
88      matrix[*firstv] = matrixRow;
89    }
90    for(boost::tie(firstv, lastv) = boost::vertices(g); firstv != lastv;
91        firstv++){
92      matrix[*firstv][*firstv] = 0;
93    }
94    std::map<vertex_des, std::map<vertex_des, int> > matrix3(matrix);
95    std::map<vertex_des, std::map<vertex_des, int> > matrix4(matrix);
96    for(boost::tie(first, last) = boost::edges(g); first != last; first++){
97      if (matrix[boost::source(*first, g)][boost::target(*first, g)] != int_inf)
98      {
99        matrix[boost::source(*first, g)][boost::target(*first, g)] =
100          my_min
101            (boost::get(local_edge_map, *first),
102             matrix[boost::source(*first, g)][boost::target(*first, g)]);
103      } else {
104        matrix[boost::source(*first, g)][boost::target(*first, g)] =
105          boost::get(local_edge_map, *first);
106      }
107    }
108    bool is_undirected =
109      boost::is_same<typename boost::graph_traits<Graph>::directed_category,
110      boost::undirected_tag>::value;
111    if (is_undirected){
112      for(boost::tie(first, last) = boost::edges(g); first != last; first++){
113        if (matrix[boost::target(*first, g)][boost::source(*first, g)] != int_inf)
114        {
115          matrix[boost::target(*first, g)][boost::source(*first, g)] =
116            my_min
117              (boost::get(local_edge_map, *first),
118               matrix[boost::target(*first, g)][boost::source(*first, g)]);
119        } else {
120          matrix[boost::target(*first, g)][boost::source(*first, g)] =
121            boost::get(local_edge_map, *first);
122        }
123      }
124    }
125
126
127    bool bellman, floyd1, floyd2, floyd3;
128    std::less<int> compare;
129    inf_plus<int> combine;
130    floyd1 =
131      boost::floyd_warshall_initialized_all_pairs_shortest_paths
132        (g,
133         matrix, weight_map(boost::get(boost::edge_weight, g)).
134         distance_compare(compare). distance_combine(combine).
135         distance_inf(int_inf). distance_zero(0));
136
137    floyd2 =
138      boost::floyd_warshall_all_pairs_shortest_paths
139        (g, matrix3,
140         weight_map(local_edge_map).  distance_compare(compare).
141         distance_combine(combine).
142         distance_inf(int_inf). distance_zero(0));
143
144    floyd3 = boost::floyd_warshall_all_pairs_shortest_paths(g, matrix4);
145
146
147    boost::dummy_property_map dummy_map;
148    std::map<vertex_des, std::map<vertex_des, int> > matrix2;
149    for(boost::tie(firstv, lastv) = vertices(g); firstv != lastv; firstv++){
150      boost::put(distance_row, *firstv, 0);
151      bellman =
152        boost::bellman_ford_shortest_paths
153          (g, vec,
154           weight_map(boost::get(boost::edge_weight, g)).
155           distance_map(boost::get(boost::vertex_distance, g)).
156           predecessor_map(dummy_map).distance_compare(compare).
157           distance_combine(combine));
158      distance_row = boost::get(boost::vertex_distance, g);
159      for(boost::tie(firstv2, lastv2) = vertices(g); firstv2 != lastv2;
160          firstv2++){
161        matrix2[*firstv][*firstv2] = boost::get(distance_row, *firstv2);
162        boost::put(distance_row, *firstv2, int_inf);
163      }
164      if(bellman == false){
165        break;
166      }
167    }
168
169
170    if (bellman != floyd1 || bellman != floyd2 || bellman != floyd3){
171      std::cout <<
172        "A negative cycle was detected in one algorithm but not the others. "
173                << std::endl;
174      return false;
175    }
176    else if (bellman == false && floyd1 == false && floyd2 == false &&
177             floyd3 == false){
178      return true;
179    }
180    else {
181      typename boost::graph_traits<Graph>::vertex_iterator first1, first2,
182        last1, last2;
183      for (boost::tie(first1, last1) = boost::vertices(g); first1 != last1;
184           first1++){
185        for (boost::tie(first2, last2) = boost::vertices(g); first2 != last2;
186             first2++){
187          if (matrix2[*first1][*first2] != matrix[*first1][*first2]){
188            std::cout << "Algorithms do not match at matrix point "
189                      << index[*first1] << " " << index[*first2]
190                      << " Bellman results: " << matrix2[*first1][*first2]
191                      << " floyd 1 results " << matrix[*first1][*first2]
192                      << std::endl;
193            return false;
194          }
195          if (matrix2[*first1][*first2] != matrix3[*first1][*first2]){
196            std::cout << "Algorithms do not match at matrix point "
197                      << index[*first1] << " " << index[*first2]
198                      << " Bellman results: " << matrix2[*first1][*first2]
199                      << " floyd 2 results " << matrix3[*first1][*first2]
200                      << std::endl;
201            return false;
202          }
203          if (matrix2[*first1][*first2] != matrix4[*first1][*first2]){
204            std::cout << "Algorithms do not match at matrix point "
205                      << index[*first1] << " " << index[*first2]
206                      << " Bellman results: " << matrix2[*first1][*first2]
207                      << " floyd 3 results " << matrix4[*first1][*first2]
208                      << std::endl;
209            return false;
210          }
211        }
212      }
213    }
214
215  }
216  return true;
217}
218
219template<typename Graph>
220bool acceptance_test2(Graph& g, int vec, int e)
221{
222  boost::minstd_rand ran(vec);
223
224  {
225
226    typename boost::property_map<Graph, boost::vertex_name_t>::type index =
227      boost::get(boost::vertex_name, g);
228    typename boost::graph_traits<Graph>::vertex_iterator firstv, lastv,
229      firstv2, lastv2;
230    int x = 0;
231    for(boost::tie(firstv, lastv) = boost::vertices(g); firstv != lastv;
232        firstv++){
233      boost::put(index, *firstv, x);
234      x++;
235    }
236
237    boost::generate_random_graph(g, vec, e, ran, true);
238
239    typename boost::graph_traits<Graph>::edge_iterator first, last;
240    typename boost::property_map<Graph, boost::edge_weight_t>::type
241      local_edge_map = boost::get(boost::edge_weight, g);
242    for(boost::tie(first, last) = boost::edges(g); first != last; first++){
243      if (ran() % vec != 0){
244        boost::put(local_edge_map, *first, ran() % 100);
245      } else {
246        boost::put(local_edge_map, *first, 0 - (ran() % 100));
247      }
248    }
249
250    int int_inf =
251      std::numeric_limits<int>::max BOOST_PREVENT_MACRO_SUBSTITUTION();
252    typedef typename boost::graph_traits<Graph>::vertex_descriptor vertex_des;
253    std::map<vertex_des,int> matrixRow;
254    std::map<vertex_des, std::map<vertex_des ,int> > matrix;
255    typedef typename boost::property_map<Graph, boost::vertex_distance_t>::type
256      distance_type;
257    distance_type distance_row = boost::get(boost::vertex_distance, g);
258    for(boost::tie(firstv, lastv) = boost::vertices(g); firstv != lastv;
259        firstv++){
260      boost::put(distance_row, *firstv, int_inf);
261      matrixRow[*firstv] = int_inf;
262    }
263    for(boost::tie(firstv, lastv) = boost::vertices(g); firstv != lastv;
264        firstv++){
265      matrix[*firstv] = matrixRow;
266    }
267    for(boost::tie(firstv, lastv) = boost::vertices(g); firstv != lastv;
268        firstv++){
269      matrix[*firstv][*firstv] = 0;
270    }
271    std::map<vertex_des, std::map<vertex_des, int> > matrix3(matrix);
272    std::map<vertex_des, std::map<vertex_des, int> > matrix4(matrix);
273    for(boost::tie(first, last) = boost::edges(g); first != last; first++){
274      if (matrix[boost::source(*first, g)][boost::target(*first, g)] != int_inf)
275      {
276        matrix[boost::source(*first, g)][boost::target(*first, g)] =
277          my_min
278            (boost::get(local_edge_map, *first),
279             matrix[boost::source(*first, g)][boost::target(*first, g)]);
280      } else {
281        matrix[boost::source(*first, g)][boost::target(*first, g)] =
282          boost::get(local_edge_map, *first);
283      }
284    }
285    bool is_undirected =
286      boost::is_same<typename boost::graph_traits<Graph>::directed_category,
287      boost::undirected_tag>::value;
288    if (is_undirected){
289      for(boost::tie(first, last) = boost::edges(g); first != last; first++){
290        if (matrix[boost::target(*first, g)][boost::source(*first, g)]
291            != int_inf){
292          matrix[boost::target(*first, g)][boost::source(*first, g)] =
293            my_min
294              (boost::get(local_edge_map, *first),
295               matrix[boost::target(*first, g)][boost::source(*first, g)]);
296        } else {
297          matrix[boost::target(*first, g)][boost::source(*first, g)] =
298            boost::get(local_edge_map, *first);
299        }
300      }
301    }
302
303
304    bool bellman, floyd1, floyd2, floyd3;
305    std::less<int> compare;
306    inf_plus<int> combine;
307    floyd1 =
308      boost::floyd_warshall_initialized_all_pairs_shortest_paths
309        (g,
310         matrix, weight_map(boost::get(boost::edge_weight, g)).
311         distance_compare(compare). distance_combine(combine).
312         distance_inf(int_inf). distance_zero(0));
313
314    floyd2 =
315      boost::floyd_warshall_all_pairs_shortest_paths
316        (g, matrix3,
317         weight_map(local_edge_map).  distance_compare(compare).
318         distance_combine(combine).
319         distance_inf(int_inf). distance_zero(0));
320
321    floyd3 = boost::floyd_warshall_all_pairs_shortest_paths(g, matrix4);
322
323
324    boost::dummy_property_map dummy_map;
325    std::map<vertex_des, std::map<vertex_des, int> > matrix2;
326    for(boost::tie(firstv, lastv) = vertices(g); firstv != lastv; firstv++){
327      boost::put(distance_row, *firstv, 0);
328      bellman =
329        boost::bellman_ford_shortest_paths
330          (g, vec,
331           weight_map(boost::get(boost::edge_weight, g)).
332           distance_map(boost::get(boost::vertex_distance, g)).
333           predecessor_map(dummy_map).distance_compare(compare).
334           distance_combine(combine));
335      distance_row = boost::get(boost::vertex_distance, g);
336      for(boost::tie(firstv2, lastv2) = vertices(g); firstv2 != lastv2;
337          firstv2++){
338        matrix2[*firstv][*firstv2] = boost::get(distance_row, *firstv2);
339        boost::put(distance_row, *firstv2, int_inf);
340      }
341      if(bellman == false){
342        break;
343      }
344    }
345
346
347    if (bellman != floyd1 || bellman != floyd2 || bellman != floyd3){
348      std::cout <<
349        "A negative cycle was detected in one algorithm but not the others. "
350                << std::endl;
351      return false;
352    }
353    else if (bellman == false && floyd1 == false && floyd2 == false &&
354             floyd3 == false){
355      return true;
356    }
357    else {
358      typename boost::graph_traits<Graph>::vertex_iterator first1, first2,
359        last1, last2;
360      for (boost::tie(first1, last1) = boost::vertices(g); first1 != last1;
361           first1++){
362        for (boost::tie(first2, last2) = boost::vertices(g); first2 != last2;
363             first2++){
364          if (matrix2[*first1][*first2] != matrix[*first1][*first2]){
365            std::cout << "Algorithms do not match at matrix point "
366                      << index[*first1] << " " << index[*first2]
367                      << " Bellman results: " << matrix2[*first1][*first2]
368                      << " floyd 1 results " << matrix[*first1][*first2]
369                      << std::endl;
370            return false;
371          }
372          if (matrix2[*first1][*first2] != matrix3[*first1][*first2]){
373            std::cout << "Algorithms do not match at matrix point "
374                      << index[*first1] << " " << index[*first2]
375                      << " Bellman results: " << matrix2[*first1][*first2]
376                      << " floyd 2 results " << matrix3[*first1][*first2]
377                      << std::endl;
378            return false;
379          }
380          if (matrix2[*first1][*first2] != matrix4[*first1][*first2]){
381            std::cout << "Algorithms do not match at matrix point "
382                      << index[*first1] << " " << index[*first2]
383                      << " Bellman results: " << matrix2[*first1][*first2]
384                      << " floyd 3 results " << matrix4[*first1][*first2]
385                      << std::endl;
386            return false;
387          }
388        }
389      }
390    }
391
392  }
393  return true;
394}
395
396int test_main(int, char*[])
397{
398  typedef boost::adjacency_list<boost::listS, boost::listS, boost::directedS,
399            boost::property<boost::vertex_distance_t, int,
400            boost::property<boost::vertex_name_t, int> > ,
401            boost::property<boost::edge_weight_t, int> > Digraph;
402  Digraph adjlist_digraph;
403  BOOST_CHECK(acceptance_test2(adjlist_digraph, 100, 2000));
404
405  typedef boost::adjacency_matrix<boost::undirectedS,
406            boost::property<boost::vertex_distance_t, int,
407            boost::property<boost::vertex_name_t, int> > ,
408            boost::property<boost::edge_weight_t, int> > Graph;
409  Graph matrix_graph(100);
410  BOOST_CHECK(acceptance_test(matrix_graph, 100, 2000));
411
412  return 0;
413}
Note: See TracBrowser for help on using the repository browser.