graph.cpp 13 KB

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