Difference between revisions of "Boost/BGL/CreateGraph"

From ProgrammingExamples
< Boost‎ | BGL
Jump to: navigation, search
(Created page with '==Timer.cpp== <source lang="cpp"> #include <iostream> // for std::cout #include <utility> // for std::pair #include <algorithm> …')
 
 
(4 intermediate revisions by 2 users not shown)
Line 1: Line 1:
==Timer.cpp==
+
This example demonstrates 3 ways to construct a graph.
 +
 
 +
==CreateGraph.cpp==
 
<source lang="cpp">
 
<source lang="cpp">
 +
 +
// STL
 
#include <iostream>                  // for std::cout
 
#include <iostream>                  // for std::cout
#include <utility>                  // for std::pair
 
#include <algorithm>                // for std::for_each
 
#include <boost/graph/graph_traits.hpp>
 
#include <boost/graph/adjacency_list.hpp>
 
  
using namespace boost;
+
// Boost
 +
#include <boost/graph/adjacency_list.hpp> // for customizable graphs
 +
#include <boost/graph/directed_graph.hpp> // A subclass to provide reasonable arguments to adjacency_list for a typical directed graph
 +
#include <boost/graph/undirected_graph.hpp>// A subclass to provide reasonable arguments to adjacency_list for a typical undirected graph
 +
 
 +
void AdjacencyList();
 +
void UndirectedGraph();
 +
void DirectedGraph();
  
typedef adjacency_list<vecS, vecS, bidirectionalS> Graph;
 
/*
 
void OutputVertices(const Graph &g);
 
void OutputEdges(const Graph &g);
 
*/
 
 
int main(int,char*[])
 
int main(int,char*[])
 
{
 
{
   // Construct a graph
+
   AdjacencyList();
   Graph g(3); // 3 vertices
+
  UndirectedGraph();
 +
   DirectedGraph();
  
   add_edge(0, 1, g);
+
   return 0;
  add_edge(1, 2, g);
+
}
  
   // Get the vertices
+
void AdjacencyList()
   typedef property_map<Graph, vertex_index_t>::type IndexMap;
+
{
   IndexMap index = get(vertex_index, g);
+
   /* Method 1: The most generic
 +
   * The generic class for a graph in Boost is adjacency_list.
 +
  * Up to 7 template parameters can be given, for example:
 +
  * typedef boost::adjacency_list<     boost::listS,             // out-edges stored in a std::list
 +
  *                      boost::vecS,            // vertex set stored here
 +
  *                      boost::undirectedS,    // bidirectional graph.
 +
  *                      boost::no_property,              // vertex properties
 +
  *                      EdgeWeightProperty,      // edge properties
 +
  *                      boost::no_property,      // graph properties
 +
  *                      boost::listS              // edge storage
 +
  *                      > graph_t;
 +
   *
 +
  * The 'S' at the end of the choices (vecS, etc.) stands for 'S'elector.
 +
  */
  
  std::cout << "vertices = ";
 
  typedef graph_traits<Graph>::vertex_iterator vertex_iter;
 
  std::pair<vertex_iter, vertex_iter> vp;
 
  for (vp = vertices(g); vp.first != vp.second; ++vp.first)
 
 
   {
 
   {
  std::cout << index[*vp.first] <<  " ";
+
  // Construct a graph with the vertices container as a vector
 +
  typedef boost::adjacency_list<boost::vecS, boost::vecS, boost::bidirectionalS> Graph;
 +
  Graph g(3); // Create a graph with 3 vertices.
 +
 
 +
  // The graph behaves as a new user would expect if the vertex container type is vector. That is, vertices can be indexed with an unsigned int.
 +
  boost::add_edge(0, 1, g);
 +
  boost::add_edge(1, 2, g);
 
   }
 
   }
  std::cout << std::endl;
 
  
 
  // Get the edges
 
  std::cout << "edges = ";
 
  graph_traits<Graph>::edge_iterator ei, ei_end;
 
  for (tie(ei, ei_end) = edges(g); ei != ei_end; ++ei)
 
 
   {
 
   {
  std::cout << "(" << index[source(*ei, g)]
+
  // Construct a graph with the vertices container as a set
  << "," << index[target(*ei, g)] << ") ";
+
  typedef boost::adjacency_list<boost::vecS, boost::setS, boost::bidirectionalS> Graph;
  }
+
  std::cout << std::endl;
+
  
   return 0;
+
   // Since the vertex container type is not a vector, the vertices can NOT be indexed with an unsigned int. I.e. the following will not work:
}
+
  //Graph g(3); // 3 vertices
 +
  //boost::add_edge(0, 1, g);
 +
  //boost::add_edge(1, 2, g);
  
 +
  // Instead, you must add vertices individually so that you get a handle to them (a way to reference them, Boost calls this a "vertex_descriptor"),
 +
  // and then add the edges by referencing these descriptors. Note this is a very generic method, so it would work just as well with a vecS vertex container.
  
/*
+
  Graph g; // Create a graph.
void OutputVertices(const Graph &g)
+
  Graph::vertex_descriptor v0 = boost::add_vertex(g);
{
+
  Graph::vertex_descriptor v1 = boost::add_vertex(g);
   // get the vertices
+
  Graph::vertex_descriptor v2 = boost::add_vertex(g);
   typedef property_map<Graph, vertex_index_t>::type IndexMap;
+
    
   IndexMap index = get(vertex_index, g);
+
   boost::add_edge(v0, v1, g);
 +
   boost::add_edge(v1, v2, g);
  
  std::cout << "vertices(g) = ";
 
  typedef graph_traits<Graph>::vertex_iterator vertex_iter;
 
  std::pair<vertex_iter, vertex_iter> vp;
 
  for (vp = vertices(g); vp.first != vp.second; ++vp.first)
 
  {
 
  std::cout << index[*vp.first] <<  " ";
 
 
   }
 
   }
  std::cout << std::endl;
 
 
}
 
}
  
void OutputEdges(const Graph &g)
+
void UndirectedGraph()
 
{
 
{
   typedef property_map<Graph, vertex_index_t>::type IndexMap;
+
   // undirected_graph is a subclass of adjacency_list which gives you object oriented access to functions like add_vertex and add_edge, which makes the code easier to understand. However, it hard codes many of the template parameters, so it is much less flexible.
  IndexMap index = get(vertex_index, g);
+
  
   //get the edges
+
   typedef boost::undirected_graph<> Graph;
  std::cout << "edges(g) = ";
+
  Graph g;
   graph_traits<Graph>::edge_iterator ei, ei_end;
+
   Graph::vertex_descriptor v0 = g.add_vertex();
  for (tie(ei, ei_end) = edges(g); ei != ei_end; ++ei)
+
   Graph::vertex_descriptor v1 = g.add_vertex();
   {
+
  std::cout << "(" << index[source(*ei, g)]
+
  << "," << index[target(*ei, g)] << ") ";
+
  
  //property_map<Graph, edge_weight_t>::type edge_weight = get(edge_weight_t(), g);
+
  g.add_edge(v0, v1);
  }
+
  std::cout << std::endl;
+
 
}
 
}
*/
+
 
 +
void DirectedGraph()
 +
{
 +
  // directed_graph is a subclass of adjacency_list which gives you object oriented access to functions like add_vertex and add_edge, which makes the code easier to understand. However, it hard codes many of the template parameters, so it is much less flexible.
 +
 
 +
  typedef boost::directed_graph<> Graph;
 +
  Graph g;
 +
  Graph::vertex_descriptor v0 = g.add_vertex();
 +
  Graph::vertex_descriptor v1 = g.add_vertex();
 +
 
 +
  g.add_edge(v0, v1);
 +
}
 +
 
 
</source>
 
</source>
  

Latest revision as of 08:37, 16 November 2011

This example demonstrates 3 ways to construct a graph.

CreateGraph.cpp

// STL
#include <iostream>                  // for std::cout
 
// Boost
#include <boost/graph/adjacency_list.hpp> // for customizable graphs
#include <boost/graph/directed_graph.hpp> // A subclass to provide reasonable arguments to adjacency_list for a typical directed graph
#include <boost/graph/undirected_graph.hpp>// A subclass to provide reasonable arguments to adjacency_list for a typical undirected graph
 
void AdjacencyList();
void UndirectedGraph();
void DirectedGraph();
 
int main(int,char*[])
{
  AdjacencyList();
  UndirectedGraph();
  DirectedGraph();
 
  return 0;
}
 
void AdjacencyList()
{
  /* Method 1: The most generic
  * The generic class for a graph in Boost is adjacency_list.
  * Up to 7 template parameters can be given, for example:
  * typedef boost::adjacency_list<     boost::listS,             // out-edges stored in a std::list
  *                       boost::vecS,             // vertex set stored here
  *                       boost::undirectedS,    // bidirectional graph.
  *                       boost::no_property,              // vertex properties
  *                       EdgeWeightProperty,       // edge properties
  *                       boost::no_property,       // graph properties
  *                       boost::listS              // edge storage
  *                       > graph_t;
  *
  * The 'S' at the end of the choices (vecS, etc.) stands for 'S'elector.
  */
 
  {
  // Construct a graph with the vertices container as a vector
  typedef boost::adjacency_list<boost::vecS, boost::vecS, boost::bidirectionalS> Graph;
  Graph g(3); // Create a graph with 3 vertices.
 
  // The graph behaves as a new user would expect if the vertex container type is vector. That is, vertices can be indexed with an unsigned int.
  boost::add_edge(0, 1, g);
  boost::add_edge(1, 2, g);
  }
 
  {
  // Construct a graph with the vertices container as a set
  typedef boost::adjacency_list<boost::vecS, boost::setS, boost::bidirectionalS> Graph;
 
  // Since the vertex container type is not a vector, the vertices can NOT be indexed with an unsigned int. I.e. the following will not work:
  //Graph g(3); // 3 vertices
  //boost::add_edge(0, 1, g);
  //boost::add_edge(1, 2, g);
 
  // Instead, you must add vertices individually so that you get a handle to them (a way to reference them, Boost calls this a "vertex_descriptor"),
  // and then add the edges by referencing these descriptors. Note this is a very generic method, so it would work just as well with a vecS vertex container.
 
  Graph g; // Create a graph.
  Graph::vertex_descriptor v0 = boost::add_vertex(g);
  Graph::vertex_descriptor v1 = boost::add_vertex(g);
  Graph::vertex_descriptor v2 = boost::add_vertex(g);
 
  boost::add_edge(v0, v1, g);
  boost::add_edge(v1, v2, g);
 
  }
}
 
void UndirectedGraph()
{
  // undirected_graph is a subclass of adjacency_list which gives you object oriented access to functions like add_vertex and add_edge, which makes the code easier to understand. However, it hard codes many of the template parameters, so it is much less flexible.
 
  typedef boost::undirected_graph<> Graph;
  Graph g;
  Graph::vertex_descriptor v0 = g.add_vertex();
  Graph::vertex_descriptor v1 = g.add_vertex();
 
  g.add_edge(v0, v1);
}
 
void DirectedGraph()
{
  // directed_graph is a subclass of adjacency_list which gives you object oriented access to functions like add_vertex and add_edge, which makes the code easier to understand. However, it hard codes many of the template parameters, so it is much less flexible.
 
  typedef boost::directed_graph<> Graph;
  Graph g;
  Graph::vertex_descriptor v0 = g.add_vertex();
  Graph::vertex_descriptor v1 = g.add_vertex();
 
  g.add_edge(v0, v1);
}

CMakeLists.txt

cmake_minimum_required(VERSION 2.6)
 
Project(ConstructGraph)
 
set(Boost_USE_MULTITHREADED ON)
FIND_PACKAGE(Boost 1.38 COMPONENTS required)
 
INCLUDE_DIRECTORIES(${INCLUDE_DIRECTORIES} ${Boost_INCLUDE_DIRS})
LINK_DIRECTORIES(${LINK_DIRECTORIES} ${Boost_LIBRARY_DIRS})
 
ADD_EXECUTABLE(ConstructGraph ConstructGraph.cpp)
target_link_libraries(ConstructGraph)