Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_33_1/libs/graph/test/graph.cpp @ 12

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

added boost

File size: 12.6 KB
Line 
1//=======================================================================
2// Copyright 2002 Indiana University.
3// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
4//
5// Distributed under the Boost Software License, Version 1.0. (See
6// accompanying file LICENSE_1_0.txt or copy at
7// http://www.boost.org/LICENSE_1_0.txt)
8//=======================================================================
9
10#include <boost/config.hpp>
11
12#include <iostream>
13#include <vector>
14#include <set>
15#include <utility>
16#include <algorithm>
17
18#define VERBOSE 0
19
20#include <boost/utility.hpp>
21#include <boost/graph/graph_utility.hpp>
22#include <boost/graph/random.hpp>
23#include <boost/pending/indirect_cmp.hpp>
24
25#include <boost/random/mersenne_twister.hpp>
26
27
28enum vertex_id_t { vertex_id = 500 };
29enum edge_id_t { edge_id = 501 };
30namespace boost {
31  BOOST_INSTALL_PROPERTY(vertex, id);
32  BOOST_INSTALL_PROPERTY(edge, id);
33}
34
35
36#include "graph_type.hpp" // this provides a typedef for Graph
37
38using namespace boost;
39
40/*
41  This program tests models of the MutableGraph concept.
42 */
43
44using std::cout;
45using std::endl;
46using std::cerr;
47using std::find;
48
49
50template <class Graph, class Vertex, class ID>
51bool check_vertex_cleared(Graph& g, Vertex v, ID id)
52{
53  typename graph_traits<Graph>::vertex_iterator vi, viend;
54  for (boost::tie(vi,viend) = vertices(g); vi != viend; ++vi) {
55    typename graph_traits<Graph>::adjacency_iterator ai, aiend, found;
56    boost::tie(ai, aiend) = adjacent_vertices(*vi, g);
57    boost::indirect_cmp<ID, std::equal_to<std::size_t> > cmp(id);
58
59#if (defined(BOOST_MSVC) && BOOST_MSVC <= 1300) && defined(__SGI_STL_PORT)
60    // seeing internal compiler errors when using std::find_if()
61    found = aiend;
62    for ( ; ai != aiend; ++ai)
63      if (cmp(*ai, v)) {
64        found = ai;
65        break;
66      }
67#else
68    found = std::find_if(ai, aiend, std::bind1st(cmp,v));
69#endif
70
71    if ( found != aiend ) {
72#if VERBOSE
73      std::cerr << "should not have found vertex " << id[*found] << std::endl;
74#endif
75      return false;
76    }
77  }
78  return true;
79}
80
81template <class Graph, class Edge, class EdgeID>
82bool check_edge_added(Graph& g, Edge e, 
83                      typename graph_traits<Graph>::vertex_descriptor a, 
84                      typename graph_traits<Graph>::vertex_descriptor b, 
85                      EdgeID edge_id, std::size_t correct_id, 
86                      bool inserted)
87{
88  if (! (source(e, g) == a)) {
89#if VERBOSE
90    cerr << "    Failed, vertex a not source of e."<< endl;
91#endif
92    return false;
93  } else if (! (target(e, g) == b)) {
94#if VERBOSE
95    cerr << "    Failed, vertex b not source of e."<< endl;
96#endif
97    return false;
98  } else if (! is_adjacent(g, a, b)) {
99#if VERBOSE
100    cerr << "    Failed, not adj."<< endl;
101#endif
102    return false;
103  } else if (! in_edge_set(g,e)) {
104#if VERBOSE
105    cerr << "    Failed, not in edge set."<< endl;
106#endif
107    return false;
108  } else if (inserted && edge_id[e] != correct_id) {
109#if VERBOSE
110    cerr << "    Failed, invalid edge property."<< endl;
111#endif
112    return false;
113  } else if (!inserted && edge_id[e] != edge_id[edge(a, b, g).first]) {
114#if VERBOSE
115    cerr << "    Failed, invalid edge property."<< endl;
116#endif
117    return false;
118  } else if (num_edges(g) != count_edges(g)) {
119#if VERBOSE
120    cerr << "    Failed, invalid number of edges."<< endl;
121#endif
122    return false;
123  }
124  return true;
125}
126
127
128template <class Graph>
129std::size_t count_edges(Graph& g)
130{
131  std::size_t e = 0;
132  typename boost::graph_traits<Graph>::edge_iterator ei,ei_end;
133  for (boost::tie(ei,ei_end) = edges(g); ei != ei_end; ++ei)
134    ++e;
135  return e;
136}
137
138
139int main(int, char* [])
140{
141  int ret = 0;
142  std::size_t N = 5, E = 0;
143  std::size_t old_N;
144
145  Graph g;
146  typedef boost::graph_traits<Graph>::vertex_descriptor Vertex;
147  typedef boost::graph_traits<Graph>::edge_descriptor Edge;
148
149  int i, j;
150  std::size_t current_vertex_id = 0;
151  std::size_t current_edge_id = 0;
152
153  bool is_failed = false;
154
155  property_map<Graph, vertex_id_t>::type vertex_id_map = get(vertex_id, g);
156
157  property_map<Graph, edge_id_t>::type edge_id_map = get(edge_id, g);
158
159  for (std::size_t k = 0; k < N; ++k)
160    add_vertex(current_vertex_id++, g);
161
162  // also need to test EdgeIterator graph constructor -JGS
163  mt19937 gen;
164   
165  for (j=0; j < 10; ++j) {
166
167    // add_edge
168#if VERBOSE
169    cerr << "Testing add_edge ..." << endl;
170#endif
171    for (i=0; i < 6; ++i) {
172      Vertex a, b;
173      a = random_vertex(g, gen);
174      do {
175        b = random_vertex(g, gen);
176      } while ( a == b ); // don't do self edges
177#if VERBOSE
178      cerr << "add_edge(" << vertex_id_map[a] << "," << vertex_id_map[b] <<")" << endl; 
179#endif
180      Edge e;
181      bool inserted;
182      boost::tie(e, inserted) = add_edge(a, b, current_edge_id++, g);
183#if VERBOSE
184      std::cout << "inserted: " << inserted << std::endl;
185      std::cout << "source(e,g)" << source(e,g) << endl;
186      std::cout << "target(e,g)" << target(e,g) << endl;
187      std::cout << "edge_id[e] = " << edge_id_map[e] << std::endl;
188      print_edges2(g, vertex_id_map, edge_id_map);
189      print_graph(g, vertex_id_map);
190      std::cout << "finished printing" << std::endl;
191      //      print_in_edges(g, vertex_id_map);
192#endif
193      if (! check_edge_added(g, e, a, b, edge_id_map, 
194                             current_edge_id - 1, inserted)) {
195        ret = -1;
196        break;
197      }
198      ++E;
199    }
200
201    // remove_edge(u, v, g)
202#if VERBOSE
203    cerr << "Testing remove_edge(u, v, g) ..." << endl; is_failed = false;
204#endif
205    for (i = 0; i < 2; ++i) {
206#if VERBOSE
207      print_edges(g, vertex_id_map);
208#endif
209      Vertex a, b;
210     
211      Edge e = random_edge(g, gen);
212      boost::tie(a,b) = boost::incident(e, g);
213      --E;
214#if VERBOSE
215      cerr << "remove_edge(" << vertex_id_map[a] << "," << vertex_id_map[b] << ")" << endl;
216#endif
217      remove_edge(a, b, g);
218#if VERBOSE
219      print_graph(g, vertex_id_map);
220      //      print_in_edges(g, vertex_id_map);
221      print_edges(g, vertex_id_map);
222#endif
223      is_failed = is_failed || is_adjacent(g, a, b) || in_edge_set(g, a, b)
224        || num_edges(g) != count_edges(g);
225      if (is_failed)
226        break;
227    }
228    if ( is_failed ) {
229      ret = -1;
230#if VERBOSE
231      cerr << "    Failed."<< endl;
232#endif
233    } else {
234#if VERBOSE
235      cerr << "           Passed."<< endl;
236#endif
237    }
238
239    // remove_edge(e, g)
240#if VERBOSE
241    cerr << "Testing remove_edge(e, g) ..." << endl; is_failed = false;
242#endif
243    for (i = 0; i < 2; ++i) {
244#if VERBOSE
245      print_edges(g, vertex_id_map);
246#endif
247      Vertex a, b;
248      Edge e = random_edge(g, gen);
249      boost::tie(a,b) = boost::incident(e, g);
250      --E;
251#if VERBOSE
252      cerr << "remove_edge(" << vertex_id_map[a] << "," << vertex_id_map[b] << ")" << endl;
253#endif
254      graph_traits<Graph>::edges_size_type old_E = num_edges(g);
255      remove_edge(e, g);
256
257#if VERBOSE
258      print_graph(g, vertex_id_map);
259      //      print_in_edges(g, vertex_id_map);
260      print_edges(g, vertex_id_map);
261#endif
262
263      is_failed = is_failed || old_E != num_edges(g) + 1
264        || num_edges(g) != count_edges(g);
265      if (is_failed)
266        break;
267    }
268    if ( is_failed ) {
269      ret = -1;
270#if VERBOSE
271      cerr << "    Failed."<< endl;
272#endif
273    } else {
274#if VERBOSE
275      cerr << "           Passed."<< endl;
276#endif
277    }
278
279    // add_vertex
280#if VERBOSE
281    cerr << "Testing add_vertex ..." << endl; is_failed = false;
282#endif
283    old_N = num_vertices(g);
284    graph_traits<Graph>::vertex_descriptor vid = add_vertex(g),
285      vidp1 = add_vertex(g);
286    vertex_id_map[vid] = current_vertex_id++;
287    vertex_id_map[vidp1] = current_vertex_id++;
288
289#if VERBOSE
290    print_vertices(g,vertex_id_map);
291    print_graph(g,vertex_id_map);
292    //    print_in_edges(g,vertex_id_map);
293    print_edges(g,vertex_id_map);
294#endif
295    // make sure the two added vertices are in the graph's vertex set
296    {
297      if (!in_vertex_set(g, vid)) {
298#if VERBOSE
299        cerr << "   Failed, " << vertex_id_map[vid] << " not in vertices(g)" << endl;
300#endif
301        ret = -1;
302        break;
303      }
304      if (!in_vertex_set(g, vidp1)) {
305#if VERBOSE
306        cerr << "   Failed, " << vertex_id_map[vidp1] << " not in vertices(g)" << endl;
307#endif
308        ret = -1;
309        break;
310      }
311    }
312
313    // make sure the vertices do not have any out edges yet
314    {
315      graph_traits<Graph>::out_edge_iterator e, e_end;
316      boost::tie(e,e_end) = out_edges(vid,g);
317      if (e != e_end) {
318#if VERBOSE
319        cerr << "   Failed, " << vertex_id_map[vid] 
320             << " should not have any out-edges yet" << endl;
321#endif
322        ret = -1;
323        break;
324      }
325      boost::tie(e,e_end) = out_edges(vidp1,g);
326      if (e != e_end) {
327#if VERBOSE
328        cerr << "   Failed, " << vertex_id_map[vidp1] 
329             << " should not have any out-edges yet" << endl;
330#endif
331        ret = -1;
332        break;
333      }
334    }
335
336    // make sure the vertices do not yet appear in any of the edges
337    {
338      graph_traits<Graph>::edge_iterator e, e_end;
339      for (boost::tie(e, e_end) = edges(g); e != e_end; ++e) {
340        if (source(*e,g) == vid || target(*e,g) == vid) {
341#if VERBOSE
342          cerr << "   Failed, " << vertex_id_map[vid]
343               << " should not have any edges" << endl;
344#endif
345          ret = -1;
346          break;
347        }
348        if (source(*e,g) == vidp1 || target(*e,g) == vidp1) {
349#if VERBOSE
350          cerr << "   Failed, " << vertex_id_map[vidp1]
351               << " should not have any edges" << endl;
352#endif
353          ret = -1;
354          break;
355        }
356      }
357    }
358    // Make sure num_vertices(g) has been updated
359    N = num_vertices(g);
360    if ( (N - 2) != old_N ) {
361      ret = -1;
362#if VERBOSE
363      cerr << "    Failed. N = " << N
364           << " but should be " << old_N + 2 << endl;
365#endif
366      break;
367    } else {
368#if VERBOSE
369      cerr << "           Passed."<< endl;     
370#endif
371    }
372    // add_edge again
373#if VERBOSE
374    cerr << "Testing add_edge after add_vertex ..." << endl; is_failed = false;
375#endif
376
377    for (i=0; i<2; ++i) {
378      Vertex a = random_vertex(g, gen), b = random_vertex(g, gen);
379      while ( a == vid ) a = random_vertex(g, gen);
380      while ( b == vidp1 ) b = random_vertex(g, gen);
381      Edge e; 
382      bool inserted;
383#if VERBOSE
384      cerr << "add_edge(" << vertex_id_map[vid] << "," << vertex_id_map[a] <<")" << endl;
385#endif
386      boost::tie(e,inserted) = add_edge(vid, a, EdgeID(current_edge_id++), g);
387     
388      if (! check_edge_added(g, e, vid, a, edge_id_map, current_edge_id - 1,
389                             inserted)) {
390        ret = -1;
391        break;
392      }
393
394#if VERBOSE
395      cerr << "add_edge(" << vertex_id_map[b] << "," << vertex_id_map[vidp1] <<")" << endl;
396#endif
397      // add_edge without plugin
398      boost::tie(e,inserted) = add_edge(b, vidp1, g);
399      if (inserted)
400        edge_id_map[e] = current_edge_id;
401      ++current_edge_id;
402
403      if (! check_edge_added(g, e, b, vidp1, edge_id_map, 
404                             current_edge_id - 1, inserted)) {
405        ret = -1;
406        break;
407      }
408    }
409   
410    // clear_vertex
411    Vertex c = random_vertex(g, gen);
412#if VERBOSE
413    cerr << "Testing clear vertex ..." << endl; is_failed = false;
414    print_graph(g, vertex_id_map);
415    //    print_in_edges(g, vertex_id_map);
416    cerr << "clearing vertex " << vertex_id_map[c] << endl;
417#endif
418    clear_vertex(c, g);
419#if VERBOSE
420    print_graph(g, vertex_id_map);
421    //    print_in_edges(g, vertex_id_map);
422    print_edges(g, vertex_id_map);
423#endif 
424    if (check_vertex_cleared(g, c, vertex_id_map) && num_edges(g) == count_edges(g)) {
425#if VERBOSE
426      cerr << " Passed."<< endl;
427#endif
428    } else {
429#if VERBOSE
430      cerr << "**** Failed" << endl;
431#endif
432      ret = -1;
433      break;
434    }
435
436#if VERBOSE
437    cerr << "Testing remove vertex ..." << endl; is_failed = false;
438    cerr << "removing vertex " << vertex_id_map[c] << endl;
439#endif
440
441    old_N = num_vertices(g);
442    remove_vertex(c, g);
443#if VERBOSE
444    print_graph(g,vertex_id_map);
445    //    print_in_edges(g,vertex_id_map);
446    print_edges(g, vertex_id_map);
447#endif
448    // can't check in_vertex_set here because the vertex_descriptor c
449    // is no longer valid, we'll just make sure the vertex set has
450    // one fewer vertex
451    {
452      graph_traits<Graph>::vertex_iterator v, v_end;
453      boost::tie(v, v_end) = vertices(g);
454      for (N = 0; v != v_end; ++v) ++N; // N = std::distance(v, v_end);
455      if (N != old_N - 1) {
456        ret = -1;
457#if VERBOSE
458        cerr << "    Failed. N = " << N
459             << " but should be " << old_N - 1 << endl;
460#endif
461      }
462    }
463
464    N = num_vertices(g);
465    if (N != old_N - 1) {
466      ret = -1;
467#if VERBOSE
468      cerr << "    Failed. N = " << N
469           << " but should be " << old_N - 1 << endl;
470#endif
471    } else {
472#if VERBOSE
473      cerr << "           Passed."<< endl;     
474#endif
475    }
476  }
477  if (ret == 0)
478    std::cout << "tests passed" << std::endl;
479
480  return ret;
481}
Note: See TracBrowser for help on using the repository browser.