graph.cpp

来自「Boost provides free peer-reviewed portab」· C++ 代码 · 共 483 行

CPP
483
字号
//=======================================================================// Copyright 2002 Indiana University.// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek//// Distributed under the Boost Software License, Version 1.0. (See// accompanying file LICENSE_1_0.txt or copy at// http://www.boost.org/LICENSE_1_0.txt)//=======================================================================#include <boost/config.hpp>#include <iostream>#include <vector>#include <set>#include <utility>#include <algorithm>#define VERBOSE 0#include <boost/utility.hpp>#include <boost/graph/graph_utility.hpp>#include <boost/graph/random.hpp>#include <boost/pending/indirect_cmp.hpp>#include <boost/random/mersenne_twister.hpp>enum vertex_id_t { vertex_id = 500 };enum edge_id_t { edge_id = 501 };namespace boost {  BOOST_INSTALL_PROPERTY(vertex, id);  BOOST_INSTALL_PROPERTY(edge, id);}#include "graph_type.hpp" // this provides a typedef for Graphusing namespace boost;/*  This program tests models of the MutableGraph concept. */using std::cout;using std::endl;using std::cerr;using std::find;template <class Graph, class Vertex, class ID>bool check_vertex_cleared(Graph& g, Vertex v, ID id){  typename graph_traits<Graph>::vertex_iterator vi, viend;  for (boost::tie(vi,viend) = vertices(g); vi != viend; ++vi) {    typename graph_traits<Graph>::adjacency_iterator ai, aiend, found;    boost::tie(ai, aiend) = adjacent_vertices(*vi, g);    boost::indirect_cmp<ID, std::equal_to<std::size_t> > cmp(id);#if (defined(BOOST_MSVC) && BOOST_MSVC <= 1300) && defined(__SGI_STL_PORT)    // seeing internal compiler errors when using std::find_if()    found = aiend;    for ( ; ai != aiend; ++ai)      if (cmp(*ai, v)) {        found = ai;        break;      }#else    found = std::find_if(ai, aiend, std::bind1st(cmp,v));#endif    if ( found != aiend ) {#if VERBOSE      std::cerr << "should not have found vertex " << id[*found] << std::endl;#endif      return false;    }  }  return true;}template <class Graph, class Edge, class EdgeID>bool check_edge_added(Graph& g, Edge e,                       typename graph_traits<Graph>::vertex_descriptor a,                       typename graph_traits<Graph>::vertex_descriptor b,                       EdgeID edge_id, std::size_t correct_id,                       bool inserted){  if (! (source(e, g) == a)) {#if VERBOSE    cerr << "    Failed, vertex a not source of e."<< endl;#endif    return false;  } else if (! (target(e, g) == b)) {#if VERBOSE    cerr << "    Failed, vertex b not source of e."<< endl;#endif    return false;  } else if (! is_adjacent(g, a, b)) {#if VERBOSE    cerr << "    Failed, not adj."<< endl;#endif    return false;  } else if (! in_edge_set(g,e)) {#if VERBOSE    cerr << "    Failed, not in edge set."<< endl;#endif    return false;  } else if (inserted && edge_id[e] != correct_id) {#if VERBOSE    cerr << "    Failed, invalid edge property."<< endl;#endif    return false;  } else if (!inserted && edge_id[e] != edge_id[edge(a, b, g).first]) {#if VERBOSE    cerr << "    Failed, invalid edge property."<< endl;#endif    return false;  } else if (num_edges(g) != count_edges(g)) {#if VERBOSE    cerr << "    Failed, invalid number of edges."<< endl;#endif    return false;  }  return true;}template <class Graph>std::size_t count_edges(Graph& g){  std::size_t e = 0;  typename boost::graph_traits<Graph>::edge_iterator ei,ei_end;  for (boost::tie(ei,ei_end) = edges(g); ei != ei_end; ++ei)    ++e;  return e;}int main(int, char* []){  int ret = 0;  std::size_t N = 5, E = 0;  std::size_t old_N;  typedef ::Graph Graph;  Graph g;  typedef boost::graph_traits<Graph>::vertex_descriptor Vertex;  typedef boost::graph_traits<Graph>::edge_descriptor Edge;  int i, j;  std::size_t current_vertex_id = 0;  std::size_t current_edge_id = 0;  bool is_failed = false;  property_map<Graph, vertex_id_t>::type vertex_id_map = get(vertex_id, g);  property_map<Graph, edge_id_t>::type edge_id_map = get(edge_id, g);  for (std::size_t k = 0; k < N; ++k)    add_vertex(current_vertex_id++, g);  // also need to test EdgeIterator graph constructor -JGS  mt19937 gen;      for (j=0; j < 10; ++j) {    // add_edge#if VERBOSE    cerr << "Testing add_edge ..." << endl;#endif    for (i=0; i < 6; ++i) {      Vertex a, b;      a = random_vertex(g, gen);      do {        b = random_vertex(g, gen);      } while ( a == b ); // don't do self edges#if VERBOSE      cerr << "add_edge(" << vertex_id_map[a] << "," << vertex_id_map[b] <<")" << endl; #endif      Edge e;      bool inserted;      boost::tie(e, inserted) = add_edge(a, b, current_edge_id++, g);#if VERBOSE      std::cout << "inserted: " << inserted << std::endl;      std::cout << "source(e,g)" << source(e,g) << endl;      std::cout << "target(e,g)" << target(e,g) << endl;      std::cout << "edge_id[e] = " << edge_id_map[e] << std::endl;      print_edges2(g, vertex_id_map, edge_id_map);      print_graph(g, vertex_id_map);      std::cout << "finished printing" << std::endl;      //      print_in_edges(g, vertex_id_map);#endif      if (! check_edge_added(g, e, a, b, edge_id_map,                              current_edge_id - 1, inserted)) {        ret = -1;        break;      }      ++E;    }    // remove_edge(u, v, g)#if VERBOSE    cerr << "Testing remove_edge(u, v, g) ..." << endl; is_failed = false;#endif    for (i = 0; i < 2; ++i) {#if VERBOSE      print_edges(g, vertex_id_map);#endif      Vertex a, b;            Edge e = random_edge(g, gen);      boost::tie(a,b) = boost::incident(e, g);      --E;#if VERBOSE      cerr << "remove_edge(" << vertex_id_map[a] << "," << vertex_id_map[b] << ")" << endl;#endif      remove_edge(a, b, g);#if VERBOSE      print_graph(g, vertex_id_map);      //      print_in_edges(g, vertex_id_map);      print_edges(g, vertex_id_map);#endif      is_failed = is_failed || is_adjacent(g, a, b) || in_edge_set(g, a, b)        || num_edges(g) != count_edges(g);      if (is_failed)        break;    }    if ( is_failed ) {      ret = -1;#if VERBOSE      cerr << "    Failed."<< endl;#endif    } else {#if VERBOSE      cerr << "           Passed."<< endl;#endif    }    // remove_edge(e, g)#if VERBOSE    cerr << "Testing remove_edge(e, g) ..." << endl; is_failed = false;#endif    for (i = 0; i < 2; ++i) {#if VERBOSE      print_edges(g, vertex_id_map);#endif      Vertex a, b;      Edge e = random_edge(g, gen);      boost::tie(a,b) = boost::incident(e, g);      --E;#if VERBOSE      cerr << "remove_edge(" << vertex_id_map[a] << "," << vertex_id_map[b] << ")" << endl;#endif      graph_traits<Graph>::edges_size_type old_E = num_edges(g);      remove_edge(e, g);#if VERBOSE      print_graph(g, vertex_id_map);      //      print_in_edges(g, vertex_id_map);      print_edges(g, vertex_id_map);#endif      is_failed = is_failed || old_E != num_edges(g) + 1        || num_edges(g) != count_edges(g);      if (is_failed)        break;    }    if ( is_failed ) {      ret = -1;#if VERBOSE      cerr << "    Failed."<< endl;#endif    } else {#if VERBOSE      cerr << "           Passed."<< endl;#endif    }    // add_vertex#if VERBOSE    cerr << "Testing add_vertex ..." << endl; is_failed = false;#endif    old_N = num_vertices(g);    graph_traits<Graph>::vertex_descriptor vid = add_vertex(g),      vidp1 = add_vertex(g);    vertex_id_map[vid] = current_vertex_id++;    vertex_id_map[vidp1] = current_vertex_id++;#if VERBOSE    print_vertices(g,vertex_id_map);    print_graph(g,vertex_id_map);    //    print_in_edges(g,vertex_id_map);    print_edges(g,vertex_id_map);#endif    // make sure the two added vertices are in the graph's vertex set    {      if (!in_vertex_set(g, vid)) {#if VERBOSE        cerr << "   Failed, " << vertex_id_map[vid] << " not in vertices(g)" << endl;#endif        ret = -1;        break;      }      if (!in_vertex_set(g, vidp1)) {#if VERBOSE        cerr << "   Failed, " << vertex_id_map[vidp1] << " not in vertices(g)" << endl;#endif        ret = -1;        break;      }    }    // make sure the vertices do not have any out edges yet    {      graph_traits<Graph>::out_edge_iterator e, e_end;      boost::tie(e,e_end) = out_edges(vid,g);      if (e != e_end) {#if VERBOSE        cerr << "   Failed, " << vertex_id_map[vid]              << " should not have any out-edges yet" << endl;#endif        ret = -1;        break;      }      boost::tie(e,e_end) = out_edges(vidp1,g);      if (e != e_end) {#if VERBOSE        cerr << "   Failed, " << vertex_id_map[vidp1]              << " should not have any out-edges yet" << endl;#endif        ret = -1;        break;      }    }    // make sure the vertices do not yet appear in any of the edges    {      graph_traits<Graph>::edge_iterator e, e_end;      for (boost::tie(e, e_end) = edges(g); e != e_end; ++e) {        if (source(*e,g) == vid || target(*e,g) == vid) {#if VERBOSE          cerr << "   Failed, " << vertex_id_map[vid]               << " should not have any edges" << endl;#endif          ret = -1;          break;        }        if (source(*e,g) == vidp1 || target(*e,g) == vidp1) {#if VERBOSE          cerr << "   Failed, " << vertex_id_map[vidp1]               << " should not have any edges" << endl;#endif          ret = -1;          break;        }      }    }    // Make sure num_vertices(g) has been updated    N = num_vertices(g);    if ( (N - 2) != old_N ) {      ret = -1;#if VERBOSE      cerr << "    Failed. N = " << N           << " but should be " << old_N + 2 << endl;#endif      break;    } else {#if VERBOSE      cerr << "           Passed."<< endl;      #endif    }    // add_edge again#if VERBOSE    cerr << "Testing add_edge after add_vertex ..." << endl; is_failed = false;#endif    for (i=0; i<2; ++i) {      Vertex a = random_vertex(g, gen), b = random_vertex(g, gen);      while ( a == vid ) a = random_vertex(g, gen);      while ( b == vidp1 ) b = random_vertex(g, gen);      Edge e;       bool inserted;#if VERBOSE      cerr << "add_edge(" << vertex_id_map[vid] << "," << vertex_id_map[a] <<")" << endl;#endif      boost::tie(e,inserted) = add_edge(vid, a, EdgeID(current_edge_id++), g);            if (! check_edge_added(g, e, vid, a, edge_id_map, current_edge_id - 1,                             inserted)) {        ret = -1;        break;      }#if VERBOSE      cerr << "add_edge(" << vertex_id_map[b] << "," << vertex_id_map[vidp1] <<")" << endl;#endif      // add_edge without plugin      boost::tie(e,inserted) = add_edge(b, vidp1, g);      if (inserted)        edge_id_map[e] = current_edge_id;      ++current_edge_id;      if (! check_edge_added(g, e, b, vidp1, edge_id_map,                              current_edge_id - 1, inserted)) {        ret = -1;        break;      }    }        // clear_vertex    Vertex c = random_vertex(g, gen);#if VERBOSE    cerr << "Testing clear vertex ..." << endl; is_failed = false;    print_graph(g, vertex_id_map);    //    print_in_edges(g, vertex_id_map);    cerr << "clearing vertex " << vertex_id_map[c] << endl;#endif    clear_vertex(c, g);#if VERBOSE    print_graph(g, vertex_id_map);    //    print_in_edges(g, vertex_id_map);    print_edges(g, vertex_id_map);#endif      if (check_vertex_cleared(g, c, vertex_id_map) && num_edges(g) == count_edges(g)) {#if VERBOSE      cerr << " Passed."<< endl;#endif    } else {#if VERBOSE      cerr << "**** Failed" << endl;#endif      ret = -1;      break;    }#if VERBOSE    cerr << "Testing remove vertex ..." << endl; is_failed = false;    cerr << "removing vertex " << vertex_id_map[c] << endl;#endif    old_N = num_vertices(g);    remove_vertex(c, g);#if VERBOSE    print_graph(g,vertex_id_map);    //    print_in_edges(g,vertex_id_map);    print_edges(g, vertex_id_map);#endif    // can't check in_vertex_set here because the vertex_descriptor c    // is no longer valid, we'll just make sure the vertex set has    // one fewer vertex    {      graph_traits<Graph>::vertex_iterator v, v_end;      boost::tie(v, v_end) = vertices(g);      for (N = 0; v != v_end; ++v) ++N; // N = std::distance(v, v_end);      if (N != old_N - 1) {        ret = -1;#if VERBOSE        cerr << "    Failed. N = " << N             << " but should be " << old_N - 1 << endl;#endif      }    }    N = num_vertices(g);    if (N != old_N - 1) {      ret = -1;#if VERBOSE      cerr << "    Failed. N = " << N           << " but should be " << old_N - 1 << endl;#endif    } else {#if VERBOSE      cerr << "           Passed."<< endl;      #endif    }  }  if (ret == 0)    std::cout << "tests passed" << std::endl;  return ret;}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?