2
0
mirror of https://github.com/boostorg/graph.git synced 2026-01-19 04:12:11 +00:00

Merge branch 'whitespace_and_formatting' of https://github.com/anadon/graph into pr171_2

Resolved Conflicts:
 include/boost/graph/one_bit_color_map.hpp
 include/boost/graph/two_bit_color_map.hpp
This commit is contained in:
jzmaddock
2019-08-26 18:09:24 +01:00
743 changed files with 76329 additions and 71081 deletions

View File

@@ -1,5 +1,5 @@
//=======================================================================
// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee,
// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee,
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
@@ -16,80 +16,85 @@
namespace std
{
template < typename T >
std::istream& operator >> (std::istream& in, std::pair < T, T > &p)
{
template < typename T >
std::istream& operator>>(std::istream& in, std::pair< T, T >& p)
{
in >> p.first >> p.second;
return in;
}
}
}
namespace boost
{
enum vertex_compile_cost_t { vertex_compile_cost };
BOOST_INSTALL_PROPERTY(vertex, compile_cost);
enum vertex_compile_cost_t
{
vertex_compile_cost
};
BOOST_INSTALL_PROPERTY(vertex, compile_cost);
}
using namespace boost;
typedef adjacency_list< listS, // Store out-edges of each vertex in a std::list
listS, // Store vertex set in a std::list
directedS, // The file dependency graph is directed
// vertex properties
property < vertex_name_t, std::string,
property < vertex_compile_cost_t, float,
property < vertex_distance_t, float,
property < vertex_color_t, default_color_type > > > >,
// an edge property
property < edge_weight_t, float > >
file_dep_graph2;
listS, // Store vertex set in a std::list
directedS, // The file dependency graph is directed
// vertex properties
property< vertex_name_t, std::string,
property< vertex_compile_cost_t, float,
property< vertex_distance_t, float,
property< vertex_color_t, default_color_type > > > >,
// an edge property
property< edge_weight_t, float > >
file_dep_graph2;
typedef graph_traits<file_dep_graph2>::vertex_descriptor vertex_t;
typedef graph_traits<file_dep_graph2>::edge_descriptor edge_t;
typedef graph_traits< file_dep_graph2 >::vertex_descriptor vertex_t;
typedef graph_traits< file_dep_graph2 >::edge_descriptor edge_t;
int
main(int argc, const char** argv)
int main(int argc, const char** argv)
{
std::ifstream file_in(argc >= 2 ? argv[1] : "makefile-dependencies.dat");
typedef graph_traits<file_dep_graph2>::vertices_size_type size_type;
size_type n_vertices;
file_in >> n_vertices; // read in number of vertices
std::ifstream file_in(argc >= 2 ? argv[1] : "makefile-dependencies.dat");
typedef graph_traits< file_dep_graph2 >::vertices_size_type size_type;
size_type n_vertices;
file_in >> n_vertices; // read in number of vertices
#if defined(BOOST_MSVC) && BOOST_MSVC <= 1300
// std::istream_iterator causes trouble with VC++
std::vector<vertex_t> id2vertex;
file_dep_graph2 g;
for (std::size_t i = 0; i < n_vertices; ++i)
id2vertex.push_back(add_vertex(g));
std::pair<size_type, size_type> p;
while (file_in >> p)
add_edge(id2vertex[p.first], id2vertex[p.second], g);
// std::istream_iterator causes trouble with VC++
std::vector< vertex_t > id2vertex;
file_dep_graph2 g;
for (std::size_t i = 0; i < n_vertices; ++i)
id2vertex.push_back(add_vertex(g));
std::pair< size_type, size_type > p;
while (file_in >> p)
add_edge(id2vertex[p.first], id2vertex[p.second], g);
#else
std::istream_iterator<std::pair<size_type, size_type> >
input_begin(file_in), input_end;
file_dep_graph2 g(input_begin, input_end, n_vertices);
std::istream_iterator< std::pair< size_type, size_type > > input_begin(
file_in),
input_end;
file_dep_graph2 g(input_begin, input_end, n_vertices);
#endif
typedef property_map < file_dep_graph2, vertex_name_t >::type name_map_t;
typedef property_map < file_dep_graph2, vertex_compile_cost_t >::type
compile_cost_map_t;
typedef property_map< file_dep_graph2, vertex_name_t >::type name_map_t;
typedef property_map< file_dep_graph2, vertex_compile_cost_t >::type
compile_cost_map_t;
name_map_t name_map = get(vertex_name, g);
compile_cost_map_t compile_cost_map = get(vertex_compile_cost, g);
name_map_t name_map = get(vertex_name, g);
compile_cost_map_t compile_cost_map = get(vertex_compile_cost, g);
std::ifstream name_in(argc >= 3 ? argv[2] : "makefile-target-names.dat");
std::ifstream compile_cost_in(argc >= 4 ? argv[3] : "target-compile-costs.dat");
graph_traits < file_dep_graph2 >::vertex_iterator vi, vi_end;
for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) {
name_in >> name_map[*vi];
compile_cost_in >> compile_cost_map[*vi];
}
std::ifstream name_in(argc >= 3 ? argv[2] : "makefile-target-names.dat");
std::ifstream compile_cost_in(
argc >= 4 ? argv[3] : "target-compile-costs.dat");
graph_traits< file_dep_graph2 >::vertex_iterator vi, vi_end;
for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
{
name_in >> name_map[*vi];
compile_cost_in >> compile_cost_map[*vi];
}
graph_property_iter_range < file_dep_graph2,
vertex_compile_cost_t >::iterator ci, ci_end;
boost::tie(ci, ci_end) = get_property_iter_range(g, vertex_compile_cost);
std::cout << "total (sequential) compile time: "
<< std::accumulate(ci, ci_end, 0.0) << std::endl;
graph_property_iter_range< file_dep_graph2,
vertex_compile_cost_t >::iterator ci,
ci_end;
boost::tie(ci, ci_end) = get_property_iter_range(g, vertex_compile_cost);
std::cout << "total (sequential) compile time: "
<< std::accumulate(ci, ci_end, 0.0) << std::endl;
return 0;
return 0;
}

View File

@@ -29,159 +29,191 @@ using namespace boost;
struct Actor
{
Actor(int id = -1) : id(id) {}
Actor(int id = -1) : id(id) {}
int id;
int id;
};
typedef adjacency_list<vecS, vecS, undirectedS, Actor,
property<edge_centrality_t, double> > ActorGraph;
typedef graph_traits<ActorGraph>::vertex_descriptor Vertex;
typedef graph_traits<ActorGraph>::edge_descriptor Edge;
typedef adjacency_list< vecS, vecS, undirectedS, Actor,
property< edge_centrality_t, double > >
ActorGraph;
typedef graph_traits< ActorGraph >::vertex_descriptor Vertex;
typedef graph_traits< ActorGraph >::edge_descriptor Edge;
void load_actor_graph(std::istream& in, ActorGraph& g)
{
std::map<int, Vertex> actors;
std::map< int, Vertex > actors;
std::string line;
while (getline(in, line)) {
std::vector<Vertex> actors_in_movie;
std::string line;
while (getline(in, line))
{
std::vector< Vertex > actors_in_movie;
// Map from the actor numbers on this line to the actor vertices
typedef tokenizer<char_separator<char> > Tok;
Tok tok(line, char_separator<char>(" "));
for (Tok::iterator id = tok.begin(); id != tok.end(); ++id) {
int actor_id = lexical_cast<int>(*id);
std::map<int, Vertex>::iterator v = actors.find(actor_id);
if (v == actors.end()) {
Vertex new_vertex = add_vertex(Actor(actor_id), g);
actors[actor_id] = new_vertex;
actors_in_movie.push_back(new_vertex);
} else {
actors_in_movie.push_back(v->second);
}
// Map from the actor numbers on this line to the actor vertices
typedef tokenizer< char_separator< char > > Tok;
Tok tok(line, char_separator< char >(" "));
for (Tok::iterator id = tok.begin(); id != tok.end(); ++id)
{
int actor_id = lexical_cast< int >(*id);
std::map< int, Vertex >::iterator v = actors.find(actor_id);
if (v == actors.end())
{
Vertex new_vertex = add_vertex(Actor(actor_id), g);
actors[actor_id] = new_vertex;
actors_in_movie.push_back(new_vertex);
}
else
{
actors_in_movie.push_back(v->second);
}
}
for (std::vector< Vertex >::iterator i = actors_in_movie.begin();
i != actors_in_movie.end(); ++i)
{
for (std::vector< Vertex >::iterator j = i + 1;
j != actors_in_movie.end(); ++j)
{
if (!edge(*i, *j, g).second)
add_edge(*i, *j, g);
}
}
}
for (std::vector<Vertex>::iterator i = actors_in_movie.begin();
i != actors_in_movie.end(); ++i) {
for (std::vector<Vertex>::iterator j = i + 1;
j != actors_in_movie.end(); ++j) {
if (!edge(*i, *j, g).second) add_edge(*i, *j, g);
}
}
}
}
template<typename Graph, typename VertexIndexMap, typename VertexNameMap>
std::ostream&
write_pajek_graph(std::ostream& out, const Graph& g,
VertexIndexMap vertex_index, VertexNameMap vertex_name)
template < typename Graph, typename VertexIndexMap, typename VertexNameMap >
std::ostream& write_pajek_graph(std::ostream& out, const Graph& g,
VertexIndexMap vertex_index, VertexNameMap vertex_name)
{
out << "*Vertices " << num_vertices(g) << '\n';
typedef typename graph_traits<Graph>::vertex_iterator vertex_iterator;
for (vertex_iterator v = vertices(g).first; v != vertices(g).second; ++v) {
out << get(vertex_index, *v)+1 << " \"" << get(vertex_name, *v) << "\"\n";
}
out << "*Vertices " << num_vertices(g) << '\n';
typedef typename graph_traits< Graph >::vertex_iterator vertex_iterator;
for (vertex_iterator v = vertices(g).first; v != vertices(g).second; ++v)
{
out << get(vertex_index, *v) + 1 << " \"" << get(vertex_name, *v)
<< "\"\n";
}
out << "*Edges\n";
typedef typename graph_traits<Graph>::edge_iterator edge_iterator;
for (edge_iterator e = edges(g).first; e != edges(g).second; ++e) {
out << get(vertex_index, source(*e, g))+1 << ' '
<< get(vertex_index, target(*e, g))+1 << " 1.0\n"; // HACK!
}
return out;
out << "*Edges\n";
typedef typename graph_traits< Graph >::edge_iterator edge_iterator;
for (edge_iterator e = edges(g).first; e != edges(g).second; ++e)
{
out << get(vertex_index, source(*e, g)) + 1 << ' '
<< get(vertex_index, target(*e, g)) + 1 << " 1.0\n"; // HACK!
}
return out;
}
class actor_clustering_threshold : public bc_clustering_threshold<double>
class actor_clustering_threshold : public bc_clustering_threshold< double >
{
typedef bc_clustering_threshold<double> inherited;
typedef bc_clustering_threshold< double > inherited;
public:
actor_clustering_threshold(double threshold, const ActorGraph& g,
bool normalize)
: inherited(threshold, g, normalize), iter(1) { }
public:
actor_clustering_threshold(
double threshold, const ActorGraph& g, bool normalize)
: inherited(threshold, g, normalize), iter(1)
{
}
bool operator()(double max_centrality, Edge e, const ActorGraph& g)
{
std::cout << "Iter: " << iter << " Max Centrality: "
<< (max_centrality / dividend) << std::endl;
++iter;
return inherited::operator()(max_centrality, e, g);
}
bool operator()(double max_centrality, Edge e, const ActorGraph& g)
{
std::cout << "Iter: " << iter
<< " Max Centrality: " << (max_centrality / dividend)
<< std::endl;
++iter;
return inherited::operator()(max_centrality, e, g);
}
private:
unsigned int iter;
private:
unsigned int iter;
};
int main(int argc, char* argv[])
{
std::string in_file;
std::string out_file;
double threshold = -1.0;
bool normalize = false;
std::string in_file;
std::string out_file;
double threshold = -1.0;
bool normalize = false;
// Parse command-line options
{
int on_arg = 1;
while (on_arg < argc) {
std::string arg(argv[on_arg]);
if (arg == "-in") {
++on_arg; assert(on_arg < argc);
in_file = argv[on_arg];
} else if (arg == "-out") {
++on_arg; assert(on_arg < argc);
out_file = argv[on_arg];
} else if (arg == "-threshold") {
++on_arg; assert(on_arg < argc);
threshold = lexical_cast<double>(argv[on_arg]);
} else if (arg == "-normalize") {
normalize = true;
} else {
std::cerr << "Unrecognized parameter \"" << arg << "\".\n";
return -1;
}
++on_arg;
// Parse command-line options
{
int on_arg = 1;
while (on_arg < argc)
{
std::string arg(argv[on_arg]);
if (arg == "-in")
{
++on_arg;
assert(on_arg < argc);
in_file = argv[on_arg];
}
else if (arg == "-out")
{
++on_arg;
assert(on_arg < argc);
out_file = argv[on_arg];
}
else if (arg == "-threshold")
{
++on_arg;
assert(on_arg < argc);
threshold = lexical_cast< double >(argv[on_arg]);
}
else if (arg == "-normalize")
{
normalize = true;
}
else
{
std::cerr << "Unrecognized parameter \"" << arg << "\".\n";
return -1;
}
++on_arg;
}
if (in_file.empty() || out_file.empty() || threshold < 0)
{
std::cerr << "error: syntax is actor_clustering [options]\n\n"
<< "options are:\n"
<< "\t-in <infile>\tInput file\n"
<< "\t-out <outfile>\tOutput file\n"
<< "\t-threshold <value>\tA threshold value\n"
<< "\t-normalize\tNormalize edge centrality scores\n";
return -1;
}
}
if (in_file.empty() || out_file.empty() || threshold < 0) {
std::cerr << "error: syntax is actor_clustering [options]\n\n"
<< "options are:\n"
<< "\t-in <infile>\tInput file\n"
<< "\t-out <outfile>\tOutput file\n"
<< "\t-threshold <value>\tA threshold value\n"
<< "\t-normalize\tNormalize edge centrality scores\n";
return -1;
ActorGraph g;
// Load the actor graph
{
std::cout << "Building graph." << std::endl;
std::ifstream in(in_file.c_str());
if (!in)
{
std::cerr << "Unable to open file \"" << in_file
<< "\" for input.\n";
return -2;
}
load_actor_graph(in, g);
}
}
ActorGraph g;
// Run the algorithm
std::cout << "Clusting..." << std::endl;
betweenness_centrality_clustering(g,
actor_clustering_threshold(threshold, g, normalize),
get(edge_centrality, g));
// Load the actor graph
{
std::cout << "Building graph." << std::endl;
std::ifstream in(in_file.c_str());
if (!in) {
std::cerr << "Unable to open file \"" << in_file << "\" for input.\n";
return -2;
// Output the graph
{
std::cout << "Writing graph to file: " << out_file << std::endl;
std::ofstream out(out_file.c_str());
if (!out)
{
std::cerr << "Unable to open file \"" << out_file
<< "\" for output.\n";
return -3;
}
write_pajek_graph(out, g, get(vertex_index, g), get(&Actor::id, g));
}
load_actor_graph(in, g);
}
// Run the algorithm
std::cout << "Clusting..." << std::endl;
betweenness_centrality_clustering(g,
actor_clustering_threshold(threshold, g, normalize),
get(edge_centrality, g));
// Output the graph
{
std::cout << "Writing graph to file: " << out_file << std::endl;
std::ofstream out(out_file.c_str());
if (!out) {
std::cerr << "Unable to open file \"" << out_file << "\" for output.\n";
return -3;
}
write_pajek_graph(out, g, get(vertex_index, g), get(&Actor::id, g));
}
return 0;
return 0;
}

View File

@@ -11,25 +11,26 @@
#include <boost/graph/adjacency_list.hpp>
#include <iostream>
int
main()
int main()
{
using namespace boost;
typedef adjacency_list<vecS, vecS, bidirectionalS, no_property,
property<int, edge_weight_t>, no_property, vecS> Graph;
using namespace boost;
typedef adjacency_list< vecS, vecS, bidirectionalS, no_property,
property< int, edge_weight_t >, no_property, vecS >
Graph;
const std::size_t n = 3;
typedef std::pair<std::size_t, std::size_t> E;
E edge_array[] = { E(0,1), E(0,2), E(0,1) };
const std::size_t m = sizeof(edge_array) / sizeof(E);
Graph g(edge_array, edge_array + m, n);
const std::size_t n = 3;
typedef std::pair< std::size_t, std::size_t > E;
E edge_array[] = { E(0, 1), E(0, 2), E(0, 1) };
const std::size_t m = sizeof(edge_array) / sizeof(E);
Graph g(edge_array, edge_array + m, n);
graph_traits<Graph>::edge_iterator edge_iterator;
for (std::size_t i = 0; i < m; ++i) {
const graph_traits<Graph>::edge_iterator e = edges(g).first + i;
std::cout << *e << " ";
}
std::cout << std::endl;
return 0;
graph_traits< Graph >::edge_iterator edge_iterator;
for (std::size_t i = 0; i < m; ++i)
{
const graph_traits< Graph >::edge_iterator e = edges(g).first + i;
std::cout << *e << " ";
}
std::cout << std::endl;
return 0;
}

View File

@@ -20,88 +20,92 @@
Sample Output
graph name: foo
0 --joe--> 1
1 --joe--> 0 --curly--> 2 --dick--> 3
2 --curly--> 1 --tom--> 4
3 --dick--> 1 --harry--> 4
4 --tom--> 2 --harry--> 3
(0,1) (1,2) (1,3) (2,4) (3,4)
0 --joe--> 1
1 --joe--> 0 --curly--> 2 --dick--> 3
2 --curly--> 1 --tom--> 4
3 --dick--> 1 --harry--> 4
4 --tom--> 2 --harry--> 3
(0,1) (1,2) (1,3) (2,4) (3,4)
removing edge (1,3):
0 --joe--> 1
1 --joe--> 0 --curly--> 2
2 --curly--> 1 --tom--> 4
3 --harry--> 4
4 --tom--> 2 --harry--> 3
(0,1) (1,2) (2,4) (3,4)
removing edge (1,3):
0 --joe--> 1
1 --joe--> 0 --curly--> 2
2 --curly--> 1 --tom--> 4
3 --harry--> 4
4 --tom--> 2 --harry--> 3
(0,1) (1,2) (2,4) (3,4)
*/
struct EdgeProperties {
EdgeProperties(const std::string& n) : name(n) { }
std::string name;
};
struct VertexProperties {
std::size_t index;
boost::default_color_type color;
};
int main(int , char* [])
struct EdgeProperties
{
using namespace boost;
using namespace std;
EdgeProperties(const std::string& n) : name(n) {}
std::string name;
};
typedef adjacency_list<vecS, listS, undirectedS,
VertexProperties, EdgeProperties> Graph;
struct VertexProperties
{
std::size_t index;
boost::default_color_type color;
};
const int V = 5;
Graph g(V);
int main(int, char*[])
{
using namespace boost;
using namespace std;
property_map<Graph, std::size_t VertexProperties::*>::type
id = get(&VertexProperties::index, g);
property_map<Graph, std::string EdgeProperties::*>::type
name = get(&EdgeProperties::name, g);
typedef adjacency_list< vecS, listS, undirectedS, VertexProperties,
EdgeProperties >
Graph;
boost::graph_traits<Graph>::vertex_iterator vi, viend;
int vnum = 0;
const int V = 5;
Graph g(V);
for (boost::tie(vi,viend) = vertices(g); vi != viend; ++vi)
id[*vi] = vnum++;
property_map< Graph, std::size_t VertexProperties::* >::type id
= get(&VertexProperties::index, g);
property_map< Graph, std::string EdgeProperties::* >::type name
= get(&EdgeProperties::name, g);
add_edge(vertex(0, g), vertex(1, g), EdgeProperties("joe"), g);
add_edge(vertex(1, g), vertex(2, g), EdgeProperties("curly"), g);
add_edge(vertex(1, g), vertex(3, g), EdgeProperties("dick"), g);
add_edge(vertex(2, g), vertex(4, g), EdgeProperties("tom"), g);
add_edge(vertex(3, g), vertex(4, g), EdgeProperties("harry"), g);
boost::graph_traits< Graph >::vertex_iterator vi, viend;
int vnum = 0;
graph_traits<Graph>::vertex_iterator i, end;
graph_traits<Graph>::out_edge_iterator ei, edge_end;
for (boost::tie(i,end) = vertices(g); i != end; ++i) {
cout << id[*i] << " ";
for (boost::tie(ei,edge_end) = out_edges(*i, g); ei != edge_end; ++ei)
cout << " --" << name[*ei] << "--> " << id[target(*ei, g)] << " ";
cout << endl;
}
print_edges(g, id);
for (boost::tie(vi, viend) = vertices(g); vi != viend; ++vi)
id[*vi] = vnum++;
cout << endl << "removing edge (1,3): " << endl;
remove_edge(vertex(1, g), vertex(3, g), g);
add_edge(vertex(0, g), vertex(1, g), EdgeProperties("joe"), g);
add_edge(vertex(1, g), vertex(2, g), EdgeProperties("curly"), g);
add_edge(vertex(1, g), vertex(3, g), EdgeProperties("dick"), g);
add_edge(vertex(2, g), vertex(4, g), EdgeProperties("tom"), g);
add_edge(vertex(3, g), vertex(4, g), EdgeProperties("harry"), g);
ei = out_edges(vertex(1, g), g).first;
cout << "removing edge (" << id[source(*ei, g)]
<< "," << id[target(*ei, g)] << ")" << endl;
remove_edge(ei, g);
graph_traits< Graph >::vertex_iterator i, end;
graph_traits< Graph >::out_edge_iterator ei, edge_end;
for (boost::tie(i, end) = vertices(g); i != end; ++i)
{
cout << id[*i] << " ";
for (boost::tie(ei, edge_end) = out_edges(*i, g); ei != edge_end; ++ei)
cout << " --" << name[*ei] << "--> " << id[target(*ei, g)] << " ";
cout << endl;
}
print_edges(g, id);
for(boost::tie(i,end) = vertices(g); i != end; ++i) {
cout << id[*i] << " ";
for (boost::tie(ei,edge_end) = out_edges(*i, g); ei != edge_end; ++ei)
cout << " --" << name[*ei] << "--> " << id[target(*ei, g)] << " ";
cout << endl;
}
cout << endl << "removing edge (1,3): " << endl;
remove_edge(vertex(1, g), vertex(3, g), g);
print_edges(g, id);
ei = out_edges(vertex(1, g), g).first;
cout << "removing edge (" << id[source(*ei, g)] << "," << id[target(*ei, g)]
<< ")" << endl;
remove_edge(ei, g);
return 0;
for (boost::tie(i, end) = vertices(g); i != end; ++i)
{
cout << id[*i] << " ";
for (boost::tie(ei, edge_end) = out_edges(*i, g); ei != edge_end; ++ei)
cout << " --" << name[*ei] << "--> " << id[target(*ei, g)] << " ";
cout << endl;
}
print_edges(g, id);
return 0;
}

View File

@@ -1,15 +1,15 @@
0 --joe--> 1
1 --joe--> 0 --curly--> 2 --dick--> 3
2 --curly--> 1 --tom--> 4
3 --dick--> 1 --harry--> 4
4 --tom--> 2 --harry--> 3
(0,1) (1,2) (1,3) (2,4) (3,4)
0 --joe--> 1
1 --joe--> 0 --curly--> 2 --dick--> 3
2 --curly--> 1 --tom--> 4
3 --dick--> 1 --harry--> 4
4 --tom--> 2 --harry--> 3
(0,1) (1,2) (1,3) (2,4) (3,4)
removing edge (1,3):
removing edge (1,3):
removing edge (1,0)
0
1 --curly--> 2
2 --curly--> 1 --tom--> 4
3 --harry--> 4
4 --tom--> 2 --harry--> 3
(1,2) (2,4) (3,4)
0
1 --curly--> 2
2 --curly--> 1 --tom--> 4
3 --harry--> 4
4 --tom--> 2 --harry--> 3
(1,2) (2,4) (3,4)

View File

@@ -15,83 +15,99 @@
using namespace boost;
//======== my data structure
struct MyStruct { double value; };
std::ostream& operator << ( std::ostream& out, const MyStruct& s )
struct MyStruct
{
out << s.value << " ";
return out;
double value;
};
std::ostream& operator<<(std::ostream& out, const MyStruct& s)
{
out << s.value << " ";
return out;
}
std::istream& operator >> ( std::istream& in, MyStruct& s )
std::istream& operator>>(std::istream& in, MyStruct& s)
{
in >> s.value;
return in;
in >> s.value;
return in;
}
//======== vertex properties
struct n1_t { enum { num = 23063}; typedef vertex_property_tag kind; };
struct n2_t { enum { num = 23062}; typedef vertex_property_tag kind; };
struct n3_t { enum { num = 23061}; typedef vertex_property_tag kind; };
struct n1_t
{
enum
{
num = 23063
};
typedef vertex_property_tag kind;
};
struct n2_t
{
enum
{
num = 23062
};
typedef vertex_property_tag kind;
};
struct n3_t
{
enum
{
num = 23061
};
typedef vertex_property_tag kind;
};
typedef property< n1_t, int,
property< n2_t, double,
property< n3_t, MyStruct > > > VertexProperty;
property< n2_t, double, property< n3_t, MyStruct > > >
VertexProperty;
//====== edge properties
struct e1_t { enum { num = 23064}; typedef edge_property_tag kind; };
typedef property<e1_t, double> EdgeProperty;
struct e1_t
{
enum
{
num = 23064
};
typedef edge_property_tag kind;
};
typedef property< e1_t, double > EdgeProperty;
//===== graph types
typedef
adjacency_list<vecS, listS, directedS, no_property, no_property>
Graph1;
typedef adjacency_list< vecS, listS, directedS, no_property, no_property >
Graph1;
typedef
adjacency_list<setS, setS, bidirectionalS, VertexProperty, EdgeProperty>
Graph2;
typedef adjacency_list< setS, setS, bidirectionalS, VertexProperty,
EdgeProperty >
Graph2;
int
main()
int main()
{
// read Graph1
Graph1 g1;
std::ifstream readFile1("data1.txt");
readFile1 >> read( g1 );
std::cout << "graph g1 from file data1.txt:\n"
<< write( g1 )
<< std::endl;
// read Graph1
Graph1 g1;
std::ifstream readFile1("data1.txt");
readFile1 >> read(g1);
std::cout << "graph g1 from file data1.txt:\n" << write(g1) << std::endl;
// read Graph2 and all internal properties
Graph2 g2;
std::ifstream readFile2("data2.txt");
readFile2 >> read( g2 );
std::cout << "graph g2 from file data2.txt:\n"
<< write( g2 )
<< std::endl;
// read Graph2, no property given. Write no property.
Graph2 g21;
std::ifstream readFile21("data1.txt");
readFile21 >> read( g21, no_property(), no_property() );
std::cout << "graph g21 from file data1.txt:\n"
<< write(g21, no_property(), no_property())
<< std::endl;
// read Graph2, incomplete data in a different order. Write it diffently.
Graph2 g31;
std::ifstream readFile31("data3.txt");
typedef property< n3_t, MyStruct, property< n1_t, int > > readNodeProp;
readFile31 >> read( g31, readNodeProp() , EdgeProperty() );
std::cout << "graph g31 from file data3.txt:\n"
<< write( g31, property<n3_t, MyStruct>(), EdgeProperty() )
<< std::endl;
// read Graph2 and all internal properties
Graph2 g2;
std::ifstream readFile2("data2.txt");
readFile2 >> read(g2);
std::cout << "graph g2 from file data2.txt:\n" << write(g2) << std::endl;
return 0;
// read Graph2, no property given. Write no property.
Graph2 g21;
std::ifstream readFile21("data1.txt");
readFile21 >> read(g21, no_property(), no_property());
std::cout << "graph g21 from file data1.txt:\n"
<< write(g21, no_property(), no_property()) << std::endl;
// read Graph2, incomplete data in a different order. Write it diffently.
Graph2 g31;
std::ifstream readFile31("data3.txt");
typedef property< n3_t, MyStruct, property< n1_t, int > > readNodeProp;
readFile31 >> read(g31, readNodeProp(), EdgeProperty());
std::cout << "graph g31 from file data3.txt:\n"
<< write(g31, property< n3_t, MyStruct >(), EdgeProperty())
<< std::endl;
return 0;
}

View File

@@ -11,57 +11,65 @@
#include <boost/graph/adjacency_matrix.hpp>
#include <boost/graph/graph_utility.hpp>
int main()
{
using namespace boost;
enum { A, B, C, D, E, F, N };
const char* name = "ABCDEF";
using namespace boost;
enum
{
A,
B,
C,
D,
E,
F,
N
};
const char* name = "ABCDEF";
// A directed graph
typedef adjacency_matrix<directedS> Graph;
Graph g(N);
add_edge(B, C, g);
add_edge(B, F, g);
add_edge(C, A, g);
add_edge(C, C, g);
add_edge(D, E, g);
add_edge(E, D, g);
add_edge(F, A, g);
// A directed graph
std::cout << "vertex set: ";
print_vertices(g, name);
std::cout << std::endl;
typedef adjacency_matrix< directedS > Graph;
Graph g(N);
add_edge(B, C, g);
add_edge(B, F, g);
add_edge(C, A, g);
add_edge(C, C, g);
add_edge(D, E, g);
add_edge(E, D, g);
add_edge(F, A, g);
std::cout << "edge set: ";
print_edges(g, name);
std::cout << std::endl;
std::cout << "vertex set: ";
print_vertices(g, name);
std::cout << std::endl;
std::cout << "out-edges: " << std::endl;
print_graph(g, name);
std::cout << std::endl;
std::cout << "edge set: ";
print_edges(g, name);
std::cout << std::endl;
// An undirected graph
std::cout << "out-edges: " << std::endl;
print_graph(g, name);
std::cout << std::endl;
typedef adjacency_matrix<undirectedS> UGraph;
UGraph ug(N);
add_edge(B, C, ug);
add_edge(B, F, ug);
add_edge(C, A, ug);
add_edge(D, E, ug);
add_edge(F, A, ug);
// An undirected graph
std::cout << "vertex set: ";
print_vertices(ug, name);
std::cout << std::endl;
typedef adjacency_matrix< undirectedS > UGraph;
UGraph ug(N);
add_edge(B, C, ug);
add_edge(B, F, ug);
add_edge(C, A, ug);
add_edge(D, E, ug);
add_edge(F, A, ug);
std::cout << "edge set: ";
print_edges(ug, name);
std::cout << std::endl;
std::cout << "vertex set: ";
print_vertices(ug, name);
std::cout << std::endl;
std::cout << "incident edges: " << std::endl;
print_graph(ug, name);
std::cout << std::endl;
return 0;
std::cout << "edge set: ";
print_edges(ug, name);
std::cout << std::endl;
std::cout << "incident edges: " << std::endl;
print_graph(ug, name);
std::cout << std::endl;
return 0;
}

View File

@@ -10,7 +10,6 @@
//=======================================================================
//
#include <boost/graph/astar_search.hpp>
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/random.hpp>
@@ -21,204 +20,218 @@
#include <list>
#include <iostream>
#include <fstream>
#include <math.h> // for sqrt
#include <math.h> // for sqrt
using namespace boost;
using namespace std;
// auxiliary types
struct location
{
float y, x; // lat, long
float y, x; // lat, long
};
typedef float cost;
template <class Name, class LocMap>
class city_writer {
public:
city_writer(Name n, LocMap l, float _minx, float _maxx,
float _miny, float _maxy,
unsigned int _ptx, unsigned int _pty)
: name(n), loc(l), minx(_minx), maxx(_maxx), miny(_miny),
maxy(_maxy), ptx(_ptx), pty(_pty) {}
template <class Vertex>
void operator()(ostream& out, const Vertex& v) const {
float px = 1 - (loc[v].x - minx) / (maxx - minx);
float py = (loc[v].y - miny) / (maxy - miny);
out << "[label=\"" << name[v] << "\", pos=\""
<< static_cast<unsigned int>(ptx * px) << ","
<< static_cast<unsigned int>(pty * py)
<< "\", fontsize=\"11\"]";
}
private:
Name name;
LocMap loc;
float minx, maxx, miny, maxy;
unsigned int ptx, pty;
};
template <class WeightMap>
class time_writer {
public:
time_writer(WeightMap w) : wm(w) {}
template <class Edge>
void operator()(ostream &out, const Edge& e) const {
out << "[label=\"" << wm[e] << "\", fontsize=\"11\"]";
}
private:
WeightMap wm;
};
// euclidean distance heuristic
template <class Graph, class CostType, class LocMap>
class distance_heuristic : public astar_heuristic<Graph, CostType>
template < class Name, class LocMap > class city_writer
{
public:
typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
distance_heuristic(LocMap l, Vertex goal)
: m_location(l), m_goal(goal) {}
CostType operator()(Vertex u)
{
CostType dx = m_location[m_goal].x - m_location[u].x;
CostType dy = m_location[m_goal].y - m_location[u].y;
return ::sqrt(dx * dx + dy * dy);
}
city_writer(Name n, LocMap l, float _minx, float _maxx, float _miny,
float _maxy, unsigned int _ptx, unsigned int _pty)
: name(n)
, loc(l)
, minx(_minx)
, maxx(_maxx)
, miny(_miny)
, maxy(_maxy)
, ptx(_ptx)
, pty(_pty)
{
}
template < class Vertex >
void operator()(ostream& out, const Vertex& v) const
{
float px = 1 - (loc[v].x - minx) / (maxx - minx);
float py = (loc[v].y - miny) / (maxy - miny);
out << "[label=\"" << name[v] << "\", pos=\""
<< static_cast< unsigned int >(ptx * px) << ","
<< static_cast< unsigned int >(pty * py) << "\", fontsize=\"11\"]";
}
private:
LocMap m_location;
Vertex m_goal;
Name name;
LocMap loc;
float minx, maxx, miny, maxy;
unsigned int ptx, pty;
};
template < class WeightMap > class time_writer
{
public:
time_writer(WeightMap w) : wm(w) {}
template < class Edge > void operator()(ostream& out, const Edge& e) const
{
out << "[label=\"" << wm[e] << "\", fontsize=\"11\"]";
}
struct found_goal {}; // exception for termination
private:
WeightMap wm;
};
// euclidean distance heuristic
template < class Graph, class CostType, class LocMap >
class distance_heuristic : public astar_heuristic< Graph, CostType >
{
public:
typedef typename graph_traits< Graph >::vertex_descriptor Vertex;
distance_heuristic(LocMap l, Vertex goal) : m_location(l), m_goal(goal) {}
CostType operator()(Vertex u)
{
CostType dx = m_location[m_goal].x - m_location[u].x;
CostType dy = m_location[m_goal].y - m_location[u].y;
return ::sqrt(dx * dx + dy * dy);
}
private:
LocMap m_location;
Vertex m_goal;
};
struct found_goal
{
}; // exception for termination
// visitor that terminates when we find the goal
template <class Vertex>
template < class Vertex >
class astar_goal_visitor : public boost::default_astar_visitor
{
public:
astar_goal_visitor(Vertex goal) : m_goal(goal) {}
template <class Graph>
void examine_vertex(Vertex u, Graph& g) {
if(u == m_goal)
throw found_goal();
}
astar_goal_visitor(Vertex goal) : m_goal(goal) {}
template < class Graph > void examine_vertex(Vertex u, Graph& g)
{
if (u == m_goal)
throw found_goal();
}
private:
Vertex m_goal;
Vertex m_goal;
};
int main(int argc, char **argv)
int main(int argc, char** argv)
{
// specify some types
typedef adjacency_list<listS, vecS, undirectedS, no_property,
property<edge_weight_t, cost> > mygraph_t;
typedef property_map<mygraph_t, edge_weight_t>::type WeightMap;
typedef mygraph_t::vertex_descriptor vertex;
typedef mygraph_t::edge_descriptor edge_descriptor;
typedef std::pair<int, int> edge;
// specify data
enum nodes {
Troy, LakePlacid, Plattsburgh, Massena, Watertown, Utica,
Syracuse, Rochester, Buffalo, Ithaca, Binghamton, Woodstock,
NewYork, N
};
const char *name[] = {
"Troy", "Lake Placid", "Plattsburgh", "Massena",
"Watertown", "Utica", "Syracuse", "Rochester", "Buffalo",
"Ithaca", "Binghamton", "Woodstock", "New York"
};
location locations[] = { // lat/long
{42.73, 73.68}, {44.28, 73.99}, {44.70, 73.46},
{44.93, 74.89}, {43.97, 75.91}, {43.10, 75.23},
{43.04, 76.14}, {43.17, 77.61}, {42.89, 78.86},
{42.44, 76.50}, {42.10, 75.91}, {42.04, 74.11},
{40.67, 73.94}
};
edge edge_array[] = {
edge(Troy,Utica), edge(Troy,LakePlacid),
edge(Troy,Plattsburgh), edge(LakePlacid,Plattsburgh),
edge(Plattsburgh,Massena), edge(LakePlacid,Massena),
edge(Massena,Watertown), edge(Watertown,Utica),
edge(Watertown,Syracuse), edge(Utica,Syracuse),
edge(Syracuse,Rochester), edge(Rochester,Buffalo),
edge(Syracuse,Ithaca), edge(Ithaca,Binghamton),
edge(Ithaca,Rochester), edge(Binghamton,Troy),
edge(Binghamton,Woodstock), edge(Binghamton,NewYork),
edge(Syracuse,Binghamton), edge(Woodstock,Troy),
edge(Woodstock,NewYork)
};
unsigned int num_edges = sizeof(edge_array) / sizeof(edge);
cost weights[] = { // estimated travel time (mins)
96, 134, 143, 65, 115, 133, 117, 116, 74, 56,
84, 73, 69, 70, 116, 147, 173, 183, 74, 71, 124
};
// create graph
mygraph_t g(N);
WeightMap weightmap = get(edge_weight, g);
for(std::size_t j = 0; j < num_edges; ++j) {
edge_descriptor e; bool inserted;
boost::tie(e, inserted) = add_edge(edge_array[j].first,
edge_array[j].second, g);
weightmap[e] = weights[j];
}
// pick random start/goal
boost::mt19937 gen(std::time(0));
vertex start = random_vertex(g, gen);
vertex goal = random_vertex(g, gen);
cout << "Start vertex: " << name[start] << endl;
cout << "Goal vertex: " << name[goal] << endl;
ofstream dotfile;
dotfile.open("test-astar-cities.dot");
write_graphviz(dotfile, g,
city_writer<const char **, location*>
(name, locations, 73.46, 78.86, 40.67, 44.93,
480, 400),
time_writer<WeightMap>(weightmap));
vector<mygraph_t::vertex_descriptor> p(num_vertices(g));
vector<cost> d(num_vertices(g));
try {
// call astar named parameter interface
astar_search_tree
(g, start,
distance_heuristic<mygraph_t, cost, location*>
(locations, goal),
predecessor_map(make_iterator_property_map(p.begin(), get(vertex_index, g))).
distance_map(make_iterator_property_map(d.begin(), get(vertex_index, g))).
visitor(astar_goal_visitor<vertex>(goal)));
} catch(found_goal fg) { // found a path to the goal
list<vertex> shortest_path;
for(vertex v = goal;; v = p[v]) {
shortest_path.push_front(v);
if(p[v] == v)
break;
// specify some types
typedef adjacency_list< listS, vecS, undirectedS, no_property,
property< edge_weight_t, cost > >
mygraph_t;
typedef property_map< mygraph_t, edge_weight_t >::type WeightMap;
typedef mygraph_t::vertex_descriptor vertex;
typedef mygraph_t::edge_descriptor edge_descriptor;
typedef std::pair< int, int > edge;
// specify data
enum nodes
{
Troy,
LakePlacid,
Plattsburgh,
Massena,
Watertown,
Utica,
Syracuse,
Rochester,
Buffalo,
Ithaca,
Binghamton,
Woodstock,
NewYork,
N
};
const char* name[] = { "Troy", "Lake Placid", "Plattsburgh", "Massena",
"Watertown", "Utica", "Syracuse", "Rochester", "Buffalo", "Ithaca",
"Binghamton", "Woodstock", "New York" };
location locations[] = { // lat/long
{ 42.73, 73.68 }, { 44.28, 73.99 }, { 44.70, 73.46 }, { 44.93, 74.89 },
{ 43.97, 75.91 }, { 43.10, 75.23 }, { 43.04, 76.14 }, { 43.17, 77.61 },
{ 42.89, 78.86 }, { 42.44, 76.50 }, { 42.10, 75.91 }, { 42.04, 74.11 },
{ 40.67, 73.94 }
};
edge edge_array[]
= { edge(Troy, Utica), edge(Troy, LakePlacid), edge(Troy, Plattsburgh),
edge(LakePlacid, Plattsburgh), edge(Plattsburgh, Massena),
edge(LakePlacid, Massena), edge(Massena, Watertown),
edge(Watertown, Utica), edge(Watertown, Syracuse),
edge(Utica, Syracuse), edge(Syracuse, Rochester),
edge(Rochester, Buffalo), edge(Syracuse, Ithaca),
edge(Ithaca, Binghamton), edge(Ithaca, Rochester),
edge(Binghamton, Troy), edge(Binghamton, Woodstock),
edge(Binghamton, NewYork), edge(Syracuse, Binghamton),
edge(Woodstock, Troy), edge(Woodstock, NewYork) };
unsigned int num_edges = sizeof(edge_array) / sizeof(edge);
cost weights[] = { // estimated travel time (mins)
96, 134, 143, 65, 115, 133, 117, 116, 74, 56, 84, 73, 69, 70, 116, 147,
173, 183, 74, 71, 124
};
// create graph
mygraph_t g(N);
WeightMap weightmap = get(edge_weight, g);
for (std::size_t j = 0; j < num_edges; ++j)
{
edge_descriptor e;
bool inserted;
boost::tie(e, inserted)
= add_edge(edge_array[j].first, edge_array[j].second, g);
weightmap[e] = weights[j];
}
cout << "Shortest path from " << name[start] << " to "
<< name[goal] << ": ";
list<vertex>::iterator spi = shortest_path.begin();
cout << name[start];
for(++spi; spi != shortest_path.end(); ++spi)
cout << " -> " << name[*spi];
cout << endl << "Total travel time: " << d[goal] << endl;
// pick random start/goal
boost::mt19937 gen(std::time(0));
vertex start = random_vertex(g, gen);
vertex goal = random_vertex(g, gen);
cout << "Start vertex: " << name[start] << endl;
cout << "Goal vertex: " << name[goal] << endl;
ofstream dotfile;
dotfile.open("test-astar-cities.dot");
write_graphviz(dotfile, g,
city_writer< const char**, location* >(
name, locations, 73.46, 78.86, 40.67, 44.93, 480, 400),
time_writer< WeightMap >(weightmap));
vector< mygraph_t::vertex_descriptor > p(num_vertices(g));
vector< cost > d(num_vertices(g));
try
{
// call astar named parameter interface
astar_search_tree(g, start,
distance_heuristic< mygraph_t, cost, location* >(locations, goal),
predecessor_map(
make_iterator_property_map(p.begin(), get(vertex_index, g)))
.distance_map(
make_iterator_property_map(d.begin(), get(vertex_index, g)))
.visitor(astar_goal_visitor< vertex >(goal)));
}
catch (found_goal fg)
{ // found a path to the goal
list< vertex > shortest_path;
for (vertex v = goal;; v = p[v])
{
shortest_path.push_front(v);
if (p[v] == v)
break;
}
cout << "Shortest path from " << name[start] << " to " << name[goal]
<< ": ";
list< vertex >::iterator spi = shortest_path.begin();
cout << name[start];
for (++spi; spi != shortest_path.end(); ++spi)
cout << " -> " << name[*spi];
cout << endl << "Total travel time: " << d[goal] << endl;
return 0;
}
cout << "Didn't find a path from " << name[start] << "to" << name[goal]
<< "!" << endl;
return 0;
}
cout << "Didn't find a path from " << name[start] << "to"
<< name[goal] << "!" << endl;
return 0;
}

View File

@@ -4,7 +4,6 @@
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// This program uses the A-star search algorithm in the Boost Graph Library to
// solve a maze. It is an example of how to apply Boost Graph Library
// algorithms to implicit graphs.
@@ -26,11 +25,11 @@
IMPORTANT:
~~~~~~~~~~
This example appears to be broken and crashes at runtime, see https://github.com/boostorg/graph/issues/148
This example appears to be broken and crashes at runtime, see
https://github.com/boostorg/graph/issues/148
*/
#include <boost/graph/astar_search.hpp>
#include <boost/graph/filtered_graph.hpp>
#include <boost/graph/grid_graph.hpp>
@@ -49,25 +48,27 @@ boost::mt19937 random_generator;
typedef double distance;
#define GRID_RANK 2
typedef boost::grid_graph<GRID_RANK> grid;
typedef boost::graph_traits<grid>::vertex_descriptor vertex_descriptor;
typedef boost::graph_traits<grid>::vertices_size_type vertices_size_type;
typedef boost::grid_graph< GRID_RANK > grid;
typedef boost::graph_traits< grid >::vertex_descriptor vertex_descriptor;
typedef boost::graph_traits< grid >::vertices_size_type vertices_size_type;
// A hash function for vertices.
struct vertex_hash {
typedef vertex_descriptor argument_type;
typedef std::size_t result_type;
std::size_t operator()(vertex_descriptor const& u) const {
std::size_t seed = 0;
boost::hash_combine(seed, u[0]);
boost::hash_combine(seed, u[1]);
return seed;
}
struct vertex_hash
{
typedef vertex_descriptor argument_type;
typedef std::size_t result_type;
std::size_t operator()(vertex_descriptor const& u) const
{
std::size_t seed = 0;
boost::hash_combine(seed, u[0]);
boost::hash_combine(seed, u[1]);
return seed;
}
};
typedef boost::unordered_set<vertex_descriptor, vertex_hash> vertex_set;
typedef boost::vertex_subset_complement_filter<grid, vertex_set>::type
filtered_grid;
typedef boost::unordered_set< vertex_descriptor, vertex_hash > vertex_set;
typedef boost::vertex_subset_complement_filter< grid, vertex_set >::type
filtered_grid;
// A searchable maze
//
@@ -84,235 +85,260 @@ typedef boost::vertex_subset_complement_filter<grid, vertex_set>::type
// A-star search is used to find a path through the maze. Each edge has a
// weight of one, so the total path length is equal to the number of edges
// traversed.
class maze {
class maze
{
public:
friend std::ostream& operator<<(std::ostream&, const maze&);
friend void random_maze(maze&);
friend std::ostream& operator<<(std::ostream&, const maze&);
friend void random_maze(maze&);
maze():m_grid(create_grid(0, 0)),m_barrier_grid(create_barrier_grid()) {};
maze(std::size_t x, std::size_t y):m_grid(create_grid(x, y)),
m_barrier_grid(create_barrier_grid()) {};
maze()
: m_grid(create_grid(0, 0)), m_barrier_grid(create_barrier_grid()) {};
maze(std::size_t x, std::size_t y)
: m_grid(create_grid(x, y)), m_barrier_grid(create_barrier_grid()) {};
// The length of the maze along the specified dimension.
vertices_size_type length(std::size_t d) const {return m_grid.length(d);}
// The length of the maze along the specified dimension.
vertices_size_type length(std::size_t d) const { return m_grid.length(d); }
bool has_barrier(vertex_descriptor u) const {
return m_barriers.find(u) != m_barriers.end();
}
bool has_barrier(vertex_descriptor u) const
{
return m_barriers.find(u) != m_barriers.end();
}
// Try to find a path from the lower-left-hand corner source (0,0) to the
// upper-right-hand corner goal (x-1, y-1).
vertex_descriptor source() const {return vertex(0, m_grid);}
vertex_descriptor goal() const {
return vertex(num_vertices(m_grid)-1, m_grid);
}
// Try to find a path from the lower-left-hand corner source (0,0) to the
// upper-right-hand corner goal (x-1, y-1).
vertex_descriptor source() const { return vertex(0, m_grid); }
vertex_descriptor goal() const
{
return vertex(num_vertices(m_grid) - 1, m_grid);
}
bool solve();
bool solved() const {return !m_solution.empty();}
bool solution_contains(vertex_descriptor u) const {
return m_solution.find(u) != m_solution.end();
}
bool solve();
bool solved() const { return !m_solution.empty(); }
bool solution_contains(vertex_descriptor u) const
{
return m_solution.find(u) != m_solution.end();
}
private:
// Create the underlying rank-2 grid with the specified dimensions.
grid create_grid(std::size_t x, std::size_t y) {
boost::array<std::size_t, GRID_RANK> lengths = { {x, y} };
return grid(lengths);
}
// Create the underlying rank-2 grid with the specified dimensions.
grid create_grid(std::size_t x, std::size_t y)
{
boost::array< std::size_t, GRID_RANK > lengths = { { x, y } };
return grid(lengths);
}
// Filter the barrier vertices out of the underlying grid.
filtered_grid create_barrier_grid() {
return boost::make_vertex_subset_complement_filter(m_grid, m_barriers);
}
// Filter the barrier vertices out of the underlying grid.
filtered_grid create_barrier_grid()
{
return boost::make_vertex_subset_complement_filter(m_grid, m_barriers);
}
// The grid underlying the maze
grid m_grid;
// The barriers in the maze
vertex_set m_barriers;
// The underlying maze grid with barrier vertices filtered out
filtered_grid m_barrier_grid;
// The vertices on a solution path through the maze
vertex_set m_solution;
// The length of the solution path
distance m_solution_length;
// The grid underlying the maze
grid m_grid;
// The barriers in the maze
vertex_set m_barriers;
// The underlying maze grid with barrier vertices filtered out
filtered_grid m_barrier_grid;
// The vertices on a solution path through the maze
vertex_set m_solution;
// The length of the solution path
distance m_solution_length;
};
// Euclidean heuristic for a grid
//
// This calculates the Euclidean distance between a vertex and a goal
// vertex.
class euclidean_heuristic:
public boost::astar_heuristic<filtered_grid, double>
class euclidean_heuristic
: public boost::astar_heuristic< filtered_grid, double >
{
public:
euclidean_heuristic(vertex_descriptor goal):m_goal(goal) {};
euclidean_heuristic(vertex_descriptor goal) : m_goal(goal) {};
double operator()(vertex_descriptor v) {
return sqrt(pow(double(m_goal[0] - v[0]), 2) + pow(double(m_goal[1] - v[1]), 2));
}
double operator()(vertex_descriptor v)
{
return sqrt(pow(double(m_goal[0] - v[0]), 2)
+ pow(double(m_goal[1] - v[1]), 2));
}
private:
vertex_descriptor m_goal;
vertex_descriptor m_goal;
};
// Exception thrown when the goal vertex is found
struct found_goal {};
struct found_goal
{
};
// Visitor that terminates when we find the goal vertex
struct astar_goal_visitor:public boost::default_astar_visitor {
astar_goal_visitor(vertex_descriptor goal):m_goal(goal) {};
struct astar_goal_visitor : public boost::default_astar_visitor
{
astar_goal_visitor(vertex_descriptor goal) : m_goal(goal) {};
void examine_vertex(vertex_descriptor u, const filtered_grid&) {
if (u == m_goal)
throw found_goal();
}
void examine_vertex(vertex_descriptor u, const filtered_grid&)
{
if (u == m_goal)
throw found_goal();
}
private:
vertex_descriptor m_goal;
vertex_descriptor m_goal;
};
// Solve the maze using A-star search. Return true if a solution was found.
bool maze::solve() {
boost::static_property_map<distance> weight(1);
// The predecessor map is a vertex-to-vertex mapping.
typedef boost::unordered_map<vertex_descriptor,
vertex_descriptor,
vertex_hash> pred_map;
pred_map predecessor;
boost::associative_property_map<pred_map> pred_pmap(predecessor);
// The distance map is a vertex-to-distance mapping.
typedef boost::unordered_map<vertex_descriptor,
distance,
vertex_hash> dist_map;
dist_map distance;
boost::associative_property_map<dist_map> dist_pmap(distance);
bool maze::solve()
{
boost::static_property_map< distance > weight(1);
// The predecessor map is a vertex-to-vertex mapping.
typedef boost::unordered_map< vertex_descriptor, vertex_descriptor,
vertex_hash >
pred_map;
pred_map predecessor;
boost::associative_property_map< pred_map > pred_pmap(predecessor);
// The distance map is a vertex-to-distance mapping.
typedef boost::unordered_map< vertex_descriptor, distance, vertex_hash >
dist_map;
dist_map distance;
boost::associative_property_map< dist_map > dist_pmap(distance);
vertex_descriptor s = source();
vertex_descriptor g = goal();
euclidean_heuristic heuristic(g);
astar_goal_visitor visitor(g);
vertex_descriptor s = source();
vertex_descriptor g = goal();
euclidean_heuristic heuristic(g);
astar_goal_visitor visitor(g);
try {
astar_search(m_barrier_grid, s, heuristic,
boost::weight_map(weight).
predecessor_map(pred_pmap).
distance_map(dist_pmap).
visitor(visitor) );
} catch(found_goal fg) {
// Walk backwards from the goal through the predecessor chain adding
// vertices to the solution path.
for (vertex_descriptor u = g; u != s; u = predecessor[u])
m_solution.insert(u);
m_solution.insert(s);
m_solution_length = distance[g];
return true;
}
try
{
astar_search(m_barrier_grid, s, heuristic,
boost::weight_map(weight)
.predecessor_map(pred_pmap)
.distance_map(dist_pmap)
.visitor(visitor));
}
catch (found_goal fg)
{
// Walk backwards from the goal through the predecessor chain adding
// vertices to the solution path.
for (vertex_descriptor u = g; u != s; u = predecessor[u])
m_solution.insert(u);
m_solution.insert(s);
m_solution_length = distance[g];
return true;
}
return false;
return false;
}
#define BARRIER "#"
// Print the maze as an ASCII map.
std::ostream& operator<<(std::ostream& output, const maze& m) {
// Header
for (vertices_size_type i = 0; i < m.length(0)+2; i++)
output << BARRIER;
output << std::endl;
// Body
for (int y = m.length(1)-1; y >= 0; y--) {
// Enumerate rows in reverse order and columns in regular order so that
// (0,0) appears in the lower left-hand corner. This requires that y be
// int and not the unsigned vertices_size_type because the loop exit
// condition is y==-1.
for (vertices_size_type x = 0; x < m.length(0); x++) {
// Put a barrier on the left-hand side.
if (x == 0)
std::ostream& operator<<(std::ostream& output, const maze& m)
{
// Header
for (vertices_size_type i = 0; i < m.length(0) + 2; i++)
output << BARRIER;
// Put the character representing this point in the maze grid.
vertex_descriptor u = {{x, vertices_size_type(y)}};
if (m.solution_contains(u))
output << ".";
else if (m.has_barrier(u))
output << BARRIER;
else
output << " ";
// Put a barrier on the right-hand side.
if (x == m.length(0)-1)
output << BARRIER;
}
// Put a newline after every row except the last one.
output << std::endl;
}
// Footer
for (vertices_size_type i = 0; i < m.length(0)+2; i++)
output << BARRIER;
if (m.solved())
output << std::endl << "Solution length " << m.m_solution_length;
return output;
// Body
for (int y = m.length(1) - 1; y >= 0; y--)
{
// Enumerate rows in reverse order and columns in regular order so that
// (0,0) appears in the lower left-hand corner. This requires that y be
// int and not the unsigned vertices_size_type because the loop exit
// condition is y==-1.
for (vertices_size_type x = 0; x < m.length(0); x++)
{
// Put a barrier on the left-hand side.
if (x == 0)
output << BARRIER;
// Put the character representing this point in the maze grid.
vertex_descriptor u = { { x, vertices_size_type(y) } };
if (m.solution_contains(u))
output << ".";
else if (m.has_barrier(u))
output << BARRIER;
else
output << " ";
// Put a barrier on the right-hand side.
if (x == m.length(0) - 1)
output << BARRIER;
}
// Put a newline after every row except the last one.
output << std::endl;
}
// Footer
for (vertices_size_type i = 0; i < m.length(0) + 2; i++)
output << BARRIER;
if (m.solved())
output << std::endl << "Solution length " << m.m_solution_length;
return output;
}
// Return a random integer in the interval [a, b].
std::size_t random_int(std::size_t a, std::size_t b) {
if (b < a)
b = a;
boost::uniform_int<> dist(a, b);
boost::variate_generator<boost::mt19937&, boost::uniform_int<> >
generate(random_generator, dist);
return generate();
std::size_t random_int(std::size_t a, std::size_t b)
{
if (b < a)
b = a;
boost::uniform_int<> dist(a, b);
boost::variate_generator< boost::mt19937&, boost::uniform_int<> > generate(
random_generator, dist);
return generate();
}
// Generate a maze with a random assignment of barriers.
void random_maze(maze& m) {
vertices_size_type n = num_vertices(m.m_grid);
vertex_descriptor s = m.source();
vertex_descriptor g = m.goal();
// One quarter of the cells in the maze should be barriers.
int barriers = n/4;
while (barriers > 0) {
// Choose horizontal or vertical direction.
std::size_t direction = random_int(0, 1);
// Walls range up to one quarter the dimension length in this direction.
vertices_size_type wall = random_int(1, m.length(direction)/4);
// Create the wall while decrementing the total barrier count.
vertex_descriptor u = vertex(random_int(0, n-1), m.m_grid);
while (wall) {
// Start and goal spaces should never be barriers.
if (u != s && u != g) {
wall--;
if (!m.has_barrier(u)) {
m.m_barriers.insert(u);
barriers--;
void random_maze(maze& m)
{
vertices_size_type n = num_vertices(m.m_grid);
vertex_descriptor s = m.source();
vertex_descriptor g = m.goal();
// One quarter of the cells in the maze should be barriers.
int barriers = n / 4;
while (barriers > 0)
{
// Choose horizontal or vertical direction.
std::size_t direction = random_int(0, 1);
// Walls range up to one quarter the dimension length in this direction.
vertices_size_type wall = random_int(1, m.length(direction) / 4);
// Create the wall while decrementing the total barrier count.
vertex_descriptor u = vertex(random_int(0, n - 1), m.m_grid);
while (wall)
{
// Start and goal spaces should never be barriers.
if (u != s && u != g)
{
wall--;
if (!m.has_barrier(u))
{
m.m_barriers.insert(u);
barriers--;
}
}
vertex_descriptor v = m.m_grid.next(u, direction);
// Stop creating this wall if we reached the maze's edge.
if (u == v)
break;
u = v;
}
}
vertex_descriptor v = m.m_grid.next(u, direction);
// Stop creating this wall if we reached the maze's edge.
if (u == v)
break;
u = v;
}
}
}
int main (int argc, char const *argv[]) {
// The default maze size is 20x10. A different size may be specified on
// the command line.
std::size_t x = 20;
std::size_t y = 10;
int main(int argc, char const* argv[])
{
// The default maze size is 20x10. A different size may be specified on
// the command line.
std::size_t x = 20;
std::size_t y = 10;
if (argc == 3) {
x = boost::lexical_cast<std::size_t>(argv[1]);
y = boost::lexical_cast<std::size_t>(argv[2]);
}
if (argc == 3)
{
x = boost::lexical_cast< std::size_t >(argv[1]);
y = boost::lexical_cast< std::size_t >(argv[2]);
}
random_generator.seed(std::time(0));
maze m(x, y);
random_maze(m);
if (m.solve())
std::cout << "Solved the maze." << std::endl;
else
std::cout << "The maze is not solvable." << std::endl;
std::cout << m << std::endl;
return 0;
random_generator.seed(std::time(0));
maze m(x, y);
random_maze(m);
if (m.solve())
std::cout << "Solved the maze." << std::endl;
else
std::cout << "The maze is not solvable." << std::endl;
std::cout << m << std::endl;
return 0;
}

View File

@@ -1,11 +1,11 @@
1SYMMETRIC STIFFNESS MATRIX SMALL GENERALIZED EIGENVALUE PROBLEM BCSSTK01
74 4 14 56 0
RSA 48 48 224 0
(16I5) (16I5) (4E20.12)
74 4 14 56 0
RSA 48 48 224 0
(16I5) (16I5) (4E20.12)
1 9 17 25 31 37 43 49 55 62 66 70 75 85 95 104
112 120 127 132 136 141 144 146 149 154 158 161 164 167 169 173
178 183 185 188 191 196 201 205 208 211 213 216 219 221 222 224
225
225
1 5 6 7 11 19 25 30 2 4 6 8 10 20 24 26
3 4 5 9 21 23 27 28 4 8 10 22 27 28 5 7
11 21 23 29 6 12 20 24 25 30 7 11 12 13 31 36

View File

@@ -1,5 +1,5 @@
//=======================================================================
// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee,
// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee,
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
@@ -15,114 +15,120 @@
using namespace boost;
template < typename Graph, typename ParentMap >
struct edge_writer
template < typename Graph, typename ParentMap > struct edge_writer
{
edge_writer(const Graph & g, const ParentMap & p)
: m_g(g), m_parent(p)
{
}
edge_writer(const Graph& g, const ParentMap& p) : m_g(g), m_parent(p) {}
template < typename Edge >
void operator() (std::ostream & out, const Edge & e) const
{
out << "[label=\"" << get(edge_weight, m_g, e) << "\"";
typename graph_traits < Graph >::vertex_descriptor
u = source(e, m_g), v = target(e, m_g);
if (m_parent[v] == u)
out << ", color=\"black\"";
else
out << ", color=\"grey\"";
out << "]";
}
const Graph & m_g;
ParentMap m_parent;
template < typename Edge >
void operator()(std::ostream& out, const Edge& e) const
{
out << "[label=\"" << get(edge_weight, m_g, e) << "\"";
typename graph_traits< Graph >::vertex_descriptor u = source(e, m_g),
v = target(e, m_g);
if (m_parent[v] == u)
out << ", color=\"black\"";
else
out << ", color=\"grey\"";
out << "]";
}
const Graph& m_g;
ParentMap m_parent;
};
template < typename Graph, typename Parent >
edge_writer < Graph, Parent >
make_edge_writer(const Graph & g, const Parent & p)
edge_writer< Graph, Parent > make_edge_writer(const Graph& g, const Parent& p)
{
return edge_writer < Graph, Parent > (g, p);
return edge_writer< Graph, Parent >(g, p);
}
struct EdgeProperties {
int weight;
struct EdgeProperties
{
int weight;
};
int
main()
int main()
{
enum { u, v, x, y, z, N };
char name[] = { 'u', 'v', 'x', 'y', 'z' };
typedef std::pair < int, int >E;
const int n_edges = 10;
E edge_array[] = { E(u, y), E(u, x), E(u, v), E(v, u),
E(x, y), E(x, v), E(y, v), E(y, z), E(z, u), E(z,x) };
int weight[n_edges] = { -4, 8, 5, -2, 9, -3, 7, 2, 6, 7 };
enum
{
u,
v,
x,
y,
z,
N
};
char name[] = { 'u', 'v', 'x', 'y', 'z' };
typedef std::pair< int, int > E;
const int n_edges = 10;
E edge_array[] = { E(u, y), E(u, x), E(u, v), E(v, u), E(x, y), E(x, v),
E(y, v), E(y, z), E(z, u), E(z, x) };
int weight[n_edges] = { -4, 8, 5, -2, 9, -3, 7, 2, 6, 7 };
typedef adjacency_list < vecS, vecS, directedS,
no_property, EdgeProperties> Graph;
typedef adjacency_list< vecS, vecS, directedS, no_property, EdgeProperties >
Graph;
#if defined(BOOST_MSVC) && BOOST_MSVC <= 1300
// VC++ can't handle the iterator constructor
Graph g(N);
for (std::size_t j = 0; j < n_edges; ++j)
add_edge(edge_array[j].first, edge_array[j].second, g);
// VC++ can't handle the iterator constructor
Graph g(N);
for (std::size_t j = 0; j < n_edges; ++j)
add_edge(edge_array[j].first, edge_array[j].second, g);
#else
Graph g(edge_array, edge_array + n_edges, N);
Graph g(edge_array, edge_array + n_edges, N);
#endif
graph_traits < Graph >::edge_iterator ei, ei_end;
property_map<Graph, int EdgeProperties::*>::type
weight_pmap = get(&EdgeProperties::weight, g);
int i = 0;
for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei, ++i)
weight_pmap[*ei] = weight[i];
graph_traits< Graph >::edge_iterator ei, ei_end;
property_map< Graph, int EdgeProperties::* >::type weight_pmap
= get(&EdgeProperties::weight, g);
int i = 0;
for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei, ++i)
weight_pmap[*ei] = weight[i];
std::vector<int> distance(N, (std::numeric_limits < short >::max)());
std::vector<std::size_t> parent(N);
for (i = 0; i < N; ++i)
parent[i] = i;
distance[z] = 0;
#if defined(BOOST_MSVC) && BOOST_MSVC <= 1300
bool r = bellman_ford_shortest_paths
(g, int(N), weight_pmap, &parent[0], &distance[0],
closed_plus<int>(), std::less<int>(), default_bellman_visitor());
#else
bool r = bellman_ford_shortest_paths
(g, int (N), weight_map(weight_pmap).distance_map(&distance[0]).
predecessor_map(&parent[0]));
#endif
if (r)
std::vector< int > distance(N, (std::numeric_limits< short >::max)());
std::vector< std::size_t > parent(N);
for (i = 0; i < N; ++i)
std::cout << name[i] << ": " << std::setw(3) << distance[i]
<< " " << name[parent[i]] << std::endl;
else
std::cout << "negative cycle" << std::endl;
parent[i] = i;
distance[z] = 0;
std::ofstream dot_file("figs/bellman-eg.dot");
dot_file << "digraph D {\n"
<< " rankdir=LR\n"
<< " size=\"5,3\"\n"
<< " ratio=\"fill\"\n"
<< " edge[style=\"bold\"]\n" << " node[shape=\"circle\"]\n";
#if defined(BOOST_MSVC) && BOOST_MSVC <= 1300
bool r = bellman_ford_shortest_paths(g, int(N), weight_pmap, &parent[0],
&distance[0], closed_plus< int >(), std::less< int >(),
default_bellman_visitor());
#else
bool r = bellman_ford_shortest_paths(g, int(N),
weight_map(weight_pmap)
.distance_map(&distance[0])
.predecessor_map(&parent[0]));
#endif
{
for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) {
graph_traits < Graph >::edge_descriptor e = *ei;
graph_traits < Graph >::vertex_descriptor
u = source(e, g), v = target(e, g);
// VC++ doesn't like the 3-argument get function, so here
// we workaround by using 2-nested get()'s.
dot_file << name[u] << " -> " << name[v]
<< "[label=\"" << get(get(&EdgeProperties::weight, g), e) << "\"";
if (parent[v] == u)
dot_file << ", color=\"black\"";
else
dot_file << ", color=\"grey\"";
dot_file << "]";
if (r)
for (i = 0; i < N; ++i)
std::cout << name[i] << ": " << std::setw(3) << distance[i] << " "
<< name[parent[i]] << std::endl;
else
std::cout << "negative cycle" << std::endl;
std::ofstream dot_file("figs/bellman-eg.dot");
dot_file << "digraph D {\n"
<< " rankdir=LR\n"
<< " size=\"5,3\"\n"
<< " ratio=\"fill\"\n"
<< " edge[style=\"bold\"]\n"
<< " node[shape=\"circle\"]\n";
{
for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei)
{
graph_traits< Graph >::edge_descriptor e = *ei;
graph_traits< Graph >::vertex_descriptor u = source(e, g),
v = target(e, g);
// VC++ doesn't like the 3-argument get function, so here
// we workaround by using 2-nested get()'s.
dot_file << name[u] << " -> " << name[v] << "[label=\""
<< get(get(&EdgeProperties::weight, g), e) << "\"";
if (parent[v] == u)
dot_file << ", color=\"black\"";
else
dot_file << ", color=\"grey\"";
dot_file << "]";
}
}
}
dot_file << "}";
return EXIT_SUCCESS;
dot_file << "}";
return EXIT_SUCCESS;
}

View File

@@ -1,5 +1,5 @@
//=======================================================================
// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee,
// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee,
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
@@ -9,55 +9,62 @@
#include <boost/graph/edge_list.hpp>
#include <boost/graph/bellman_ford_shortest_paths.hpp>
int
main()
int main()
{
using namespace boost;
// ID numbers for the routers (vertices).
enum
{ A, B, C, D, E, F, G, H, n_vertices };
const int n_edges = 11;
typedef std::pair < int, int >Edge;
using namespace boost;
// ID numbers for the routers (vertices).
enum
{
A,
B,
C,
D,
E,
F,
G,
H,
n_vertices
};
const int n_edges = 11;
typedef std::pair< int, int > Edge;
// The list of connections between routers stored in an array.
Edge edges[] = {
Edge(A, B), Edge(A, C),
Edge(B, D), Edge(B, E), Edge(C, E), Edge(C, F), Edge(D, H),
Edge(D, E), Edge(E, H), Edge(F, G), Edge(G, H)
};
// The list of connections between routers stored in an array.
Edge edges[] = { Edge(A, B), Edge(A, C), Edge(B, D), Edge(B, E), Edge(C, E),
Edge(C, F), Edge(D, H), Edge(D, E), Edge(E, H), Edge(F, G),
Edge(G, H) };
// Specify the graph type and declare a graph object
typedef edge_list < Edge*, Edge, std::ptrdiff_t, std::random_access_iterator_tag> Graph;
Graph g(edges, edges + n_edges);
// Specify the graph type and declare a graph object
typedef edge_list< Edge*, Edge, std::ptrdiff_t,
std::random_access_iterator_tag >
Graph;
Graph g(edges, edges + n_edges);
// The transmission delay values for each edge.
float delay[] =
{5.0, 1.0, 1.3, 3.0, 10.0, 2.0, 6.3, 0.4, 1.3, 1.2, 0.5};
// The transmission delay values for each edge.
float delay[] = { 5.0, 1.0, 1.3, 3.0, 10.0, 2.0, 6.3, 0.4, 1.3, 1.2, 0.5 };
// Declare some storage for some "external" vertex properties.
char name[] = "ABCDEFGH";
int parent[n_vertices];
for (int i = 0; i < n_vertices; ++i)
parent[i] = i;
float distance[n_vertices];
std::fill(distance, distance + n_vertices, (std::numeric_limits < float >::max)());
// Specify A as the source vertex
distance[A] = 0;
bool r = bellman_ford_shortest_paths(g, int (n_vertices),
weight_map(make_iterator_property_map
(&delay[0],
get(edge_index, g),
delay[0])).
distance_map(&distance[0]).
predecessor_map(&parent[0]));
if (r)
// Declare some storage for some "external" vertex properties.
char name[] = "ABCDEFGH";
int parent[n_vertices];
for (int i = 0; i < n_vertices; ++i)
std::cout << name[i] << ": " << distance[i]
<< " " << name[parent[i]] << std::endl;
else
std::cout << "negative cycle" << std::endl;
parent[i] = i;
float distance[n_vertices];
std::fill(
distance, distance + n_vertices, (std::numeric_limits< float >::max)());
// Specify A as the source vertex
distance[A] = 0;
return EXIT_SUCCESS;
bool r = bellman_ford_shortest_paths(g, int(n_vertices),
weight_map(
make_iterator_property_map(&delay[0], get(edge_index, g), delay[0]))
.distance_map(&distance[0])
.predecessor_map(&parent[0]));
if (r)
for (int i = 0; i < n_vertices; ++i)
std::cout << name[i] << ": " << distance[i] << " "
<< name[parent[i]] << std::endl;
else
std::cout << "negative cycle" << std::endl;
return EXIT_SUCCESS;
}

View File

@@ -1,5 +1,5 @@
//=======================================================================
// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee,
// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee,
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
@@ -13,72 +13,83 @@
#include <iostream>
using namespace boost;
template < typename TimeMap > class bfs_time_visitor:public default_bfs_visitor {
typedef typename property_traits < TimeMap >::value_type T;
template < typename TimeMap >
class bfs_time_visitor : public default_bfs_visitor
{
typedef typename property_traits< TimeMap >::value_type T;
public:
bfs_time_visitor(TimeMap tmap, T & t):m_timemap(tmap), m_time(t) { }
template < typename Vertex, typename Graph >
void discover_vertex(Vertex u, const Graph & g) const
{
put(m_timemap, u, m_time++);
}
TimeMap m_timemap;
T & m_time;
bfs_time_visitor(TimeMap tmap, T& t) : m_timemap(tmap), m_time(t) {}
template < typename Vertex, typename Graph >
void discover_vertex(Vertex u, const Graph& g) const
{
put(m_timemap, u, m_time++);
}
TimeMap m_timemap;
T& m_time;
};
int
main()
int main()
{
using namespace boost;
// Select the graph type we wish to use
typedef adjacency_list < vecS, vecS, undirectedS > graph_t;
// Set up the vertex IDs and names
enum { r, s, t, u, v, w, x, y, N };
const char *name = "rstuvwxy";
// Specify the edges in the graph
typedef std::pair < int, int >E;
E edge_array[] = { E(r, s), E(r, v), E(s, w), E(w, r), E(w, t),
E(w, x), E(x, t), E(t, u), E(x, y), E(u, y)
};
// Create the graph object
const int n_edges = sizeof(edge_array) / sizeof(E);
using namespace boost;
// Select the graph type we wish to use
typedef adjacency_list< vecS, vecS, undirectedS > graph_t;
// Set up the vertex IDs and names
enum
{
r,
s,
t,
u,
v,
w,
x,
y,
N
};
const char* name = "rstuvwxy";
// Specify the edges in the graph
typedef std::pair< int, int > E;
E edge_array[] = { E(r, s), E(r, v), E(s, w), E(w, r), E(w, t), E(w, x),
E(x, t), E(t, u), E(x, y), E(u, y) };
// Create the graph object
const int n_edges = sizeof(edge_array) / sizeof(E);
#if defined(BOOST_MSVC) && BOOST_MSVC <= 1300
// VC++ has trouble with the edge iterator constructor
graph_t g(N);
for (std::size_t j = 0; j < n_edges; ++j)
add_edge(edge_array[j].first, edge_array[j].second, g);
// VC++ has trouble with the edge iterator constructor
graph_t g(N);
for (std::size_t j = 0; j < n_edges; ++j)
add_edge(edge_array[j].first, edge_array[j].second, g);
#else
typedef graph_traits<graph_t>::vertices_size_type v_size_t;
graph_t g(edge_array, edge_array + n_edges, v_size_t(N));
typedef graph_traits< graph_t >::vertices_size_type v_size_t;
graph_t g(edge_array, edge_array + n_edges, v_size_t(N));
#endif
// Typedefs
typedef graph_traits < graph_t >::vertices_size_type Size;
// Typedefs
typedef graph_traits< graph_t >::vertices_size_type Size;
// a vector to hold the discover time property for each vertex
std::vector < Size > dtime(num_vertices(g));
typedef
iterator_property_map<std::vector<Size>::iterator,
property_map<graph_t, vertex_index_t>::const_type>
dtime_pm_type;
dtime_pm_type dtime_pm(dtime.begin(), get(vertex_index, g));
// a vector to hold the discover time property for each vertex
std::vector< Size > dtime(num_vertices(g));
typedef iterator_property_map< std::vector< Size >::iterator,
property_map< graph_t, vertex_index_t >::const_type >
dtime_pm_type;
dtime_pm_type dtime_pm(dtime.begin(), get(vertex_index, g));
Size time = 0;
bfs_time_visitor < dtime_pm_type >vis(dtime_pm, time);
breadth_first_search(g, vertex(s, g), visitor(vis));
Size time = 0;
bfs_time_visitor< dtime_pm_type > vis(dtime_pm, time);
breadth_first_search(g, vertex(s, g), visitor(vis));
// Use std::sort to order the vertices by their discover time
std::vector<graph_traits<graph_t>::vertices_size_type > discover_order(N);
integer_range < int >range(0, N);
std::copy(range.begin(), range.end(), discover_order.begin());
std::sort(discover_order.begin(), discover_order.end(),
indirect_cmp < dtime_pm_type, std::less < Size > >(dtime_pm));
// Use std::sort to order the vertices by their discover time
std::vector< graph_traits< graph_t >::vertices_size_type > discover_order(
N);
integer_range< int > range(0, N);
std::copy(range.begin(), range.end(), discover_order.begin());
std::sort(discover_order.begin(), discover_order.end(),
indirect_cmp< dtime_pm_type, std::less< Size > >(dtime_pm));
std::cout << "order of discovery: ";
for (int i = 0; i < N; ++i)
std::cout << name[discover_order[i]] << " ";
std::cout << std::endl;
std::cout << "order of discovery: ";
for (int i = 0; i < N; ++i)
std::cout << name[discover_order[i]] << " ";
std::cout << std::endl;
return EXIT_SUCCESS;
return EXIT_SUCCESS;
}

View File

@@ -1,5 +1,5 @@
//=======================================================================
// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee,
// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee,
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
@@ -14,95 +14,106 @@
#include <iostream>
using namespace boost;
template < typename TimeMap > class bfs_time_visitor:public default_bfs_visitor {
typedef typename property_traits < TimeMap >::value_type T;
public:
bfs_time_visitor(TimeMap tmap, T & t):m_timemap(tmap), m_time(t) { }
template < typename Vertex, typename Graph >
void discover_vertex(Vertex u, const Graph & g) const
{
put(m_timemap, u, m_time++);
}
TimeMap m_timemap;
T & m_time;
};
struct VertexProps {
boost::default_color_type color;
std::size_t discover_time;
unsigned int index;
};
int
main()
template < typename TimeMap >
class bfs_time_visitor : public default_bfs_visitor
{
using namespace boost;
// Select the graph type we wish to use
typedef adjacency_list < listS, listS, undirectedS,
VertexProps> graph_t;
// Set up the vertex IDs and names
enum { r, s, t, u, v, w, x, y, N };
const char *name = "rstuvwxy";
// Specify the edges in the graph
typedef std::pair < int, int >E;
E edge_array[] = { E(r, s), E(r, v), E(s, w), E(w, r), E(w, t),
E(w, x), E(x, t), E(t, u), E(x, y), E(u, y)
};
// Create the graph object
const int n_edges = sizeof(edge_array) / sizeof(E);
typedef typename property_traits< TimeMap >::value_type T;
public:
bfs_time_visitor(TimeMap tmap, T& t) : m_timemap(tmap), m_time(t) {}
template < typename Vertex, typename Graph >
void discover_vertex(Vertex u, const Graph& g) const
{
put(m_timemap, u, m_time++);
}
TimeMap m_timemap;
T& m_time;
};
struct VertexProps
{
boost::default_color_type color;
std::size_t discover_time;
unsigned int index;
};
int main()
{
using namespace boost;
// Select the graph type we wish to use
typedef adjacency_list< listS, listS, undirectedS, VertexProps > graph_t;
// Set up the vertex IDs and names
enum
{
r,
s,
t,
u,
v,
w,
x,
y,
N
};
const char* name = "rstuvwxy";
// Specify the edges in the graph
typedef std::pair< int, int > E;
E edge_array[] = { E(r, s), E(r, v), E(s, w), E(w, r), E(w, t), E(w, x),
E(x, t), E(t, u), E(x, y), E(u, y) };
// Create the graph object
const int n_edges = sizeof(edge_array) / sizeof(E);
#if defined(BOOST_MSVC) && BOOST_MSVC <= 1300
// VC++ has trouble with the edge iterator constructor
graph_t g;
std::vector<graph_traits<graph_t>::vertex_descriptor> verts;
for (std::size_t i = 0; i < N; ++i)
verts.push_back(add_vertex(g));
for (std::size_t j = 0; j < n_edges; ++j)
add_edge(verts[edge_array[j].first], verts[edge_array[j].second], g);
// VC++ has trouble with the edge iterator constructor
graph_t g;
std::vector< graph_traits< graph_t >::vertex_descriptor > verts;
for (std::size_t i = 0; i < N; ++i)
verts.push_back(add_vertex(g));
for (std::size_t j = 0; j < n_edges; ++j)
add_edge(verts[edge_array[j].first], verts[edge_array[j].second], g);
#else
typedef graph_traits<graph_t>::vertices_size_type v_size_t;
graph_t g(edge_array, edge_array + n_edges, v_size_t(N));
typedef graph_traits< graph_t >::vertices_size_type v_size_t;
graph_t g(edge_array, edge_array + n_edges, v_size_t(N));
#endif
// Typedefs
typedef graph_traits<graph_t>::vertices_size_type Size;
// Typedefs
typedef graph_traits< graph_t >::vertices_size_type Size;
Size time = 0;
typedef property_map<graph_t, std::size_t VertexProps::*>::type dtime_map_t;
dtime_map_t dtime_map = get(&VertexProps::discover_time, g);
bfs_time_visitor < dtime_map_t > vis(dtime_map, time);
breadth_first_search(g, vertex(s, g), color_map(get(&VertexProps::color, g)).
visitor(vis));
Size time = 0;
typedef property_map< graph_t, std::size_t VertexProps::* >::type
dtime_map_t;
dtime_map_t dtime_map = get(&VertexProps::discover_time, g);
bfs_time_visitor< dtime_map_t > vis(dtime_map, time);
breadth_first_search(
g, vertex(s, g), color_map(get(&VertexProps::color, g)).visitor(vis));
// a vector to hold the discover time property for each vertex
std::vector < Size > dtime(num_vertices(g));
typedef
iterator_property_map<std::vector<Size>::iterator,
property_map<graph_t, unsigned int VertexProps::*>::type>
dtime_pm_type;
graph_traits<graph_t>::vertex_iterator vi, vi_end;
std::size_t c = 0;
for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi, ++c) {
dtime[c] = dtime_map[*vi];
put(&VertexProps::index, g, *vi, c);
}
dtime_pm_type dtime_pm(dtime.begin(), get(&VertexProps::index, g));
// a vector to hold the discover time property for each vertex
std::vector< Size > dtime(num_vertices(g));
typedef iterator_property_map< std::vector< Size >::iterator,
property_map< graph_t, unsigned int VertexProps::* >::type >
dtime_pm_type;
graph_traits< graph_t >::vertex_iterator vi, vi_end;
std::size_t c = 0;
for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi, ++c)
{
dtime[c] = dtime_map[*vi];
put(&VertexProps::index, g, *vi, c);
}
dtime_pm_type dtime_pm(dtime.begin(), get(&VertexProps::index, g));
// Use std::sort to order the vertices by their discover time
std::vector<graph_traits<graph_t>::vertices_size_type > discover_order(N);
integer_range < int >range(0, N);
std::copy(range.begin(), range.end(), discover_order.begin());
std::sort(discover_order.begin(), discover_order.end(),
make_indirect_cmp(
std::less<Size>(),
make_iterator_property_map(
dtime.begin(),
typed_identity_property_map<std::size_t>())));
// Use std::sort to order the vertices by their discover time
std::vector< graph_traits< graph_t >::vertices_size_type > discover_order(
N);
integer_range< int > range(0, N);
std::copy(range.begin(), range.end(), discover_order.begin());
std::sort(discover_order.begin(), discover_order.end(),
make_indirect_cmp(std::less< Size >(),
make_iterator_property_map(
dtime.begin(), typed_identity_property_map< std::size_t >())));
std::cout << "order of discovery: ";
for (int i = 0; i < N; ++i)
std::cout << name[discover_order[i]] << " ";
std::cout << std::endl;
std::cout << "order of discovery: ";
for (int i = 0; i < N; ++i)
std::cout << name[discover_order[i]] << " ";
std::cout << std::endl;
return EXIT_SUCCESS;
return EXIT_SUCCESS;
}

View File

@@ -1,5 +1,5 @@
//=======================================================================
// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee,
// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee,
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
@@ -12,83 +12,81 @@
#include <boost/graph/breadth_first_search.hpp>
using namespace boost;
template <typename Graph, typename VertexNameMap, typename TransDelayMap>
void
build_router_network(Graph & g, VertexNameMap name_map,
TransDelayMap delay_map)
template < typename Graph, typename VertexNameMap, typename TransDelayMap >
void build_router_network(
Graph& g, VertexNameMap name_map, TransDelayMap delay_map)
{
typename graph_traits < Graph >::vertex_descriptor a, b, c, d, e;
a = add_vertex(g);
name_map[a] = 'a';
b = add_vertex(g);
name_map[b] = 'b';
c = add_vertex(g);
name_map[c] = 'c';
d = add_vertex(g);
name_map[d] = 'd';
e = add_vertex(g);
name_map[e] = 'e';
typename graph_traits< Graph >::vertex_descriptor a, b, c, d, e;
a = add_vertex(g);
name_map[a] = 'a';
b = add_vertex(g);
name_map[b] = 'b';
c = add_vertex(g);
name_map[c] = 'c';
d = add_vertex(g);
name_map[d] = 'd';
e = add_vertex(g);
name_map[e] = 'e';
typename graph_traits<Graph>::edge_descriptor ed;
bool inserted;
typename graph_traits< Graph >::edge_descriptor ed;
bool inserted;
boost::tie(ed, inserted) = add_edge(a, b, g);
delay_map[ed] = 1.2;
boost::tie(ed, inserted) = add_edge(a, d, g);
delay_map[ed] = 4.5;
boost::tie(ed, inserted) = add_edge(b, d, g);
delay_map[ed] = 1.8;
boost::tie(ed, inserted) = add_edge(c, a, g);
delay_map[ed] = 2.6;
boost::tie(ed, inserted) = add_edge(c, e, g);
delay_map[ed] = 5.2;
boost::tie(ed, inserted) = add_edge(d, c, g);
delay_map[ed] = 0.4;
boost::tie(ed, inserted) = add_edge(d, e, g);
delay_map[ed] = 3.3;
boost::tie(ed, inserted) = add_edge(a, b, g);
delay_map[ed] = 1.2;
boost::tie(ed, inserted) = add_edge(a, d, g);
delay_map[ed] = 4.5;
boost::tie(ed, inserted) = add_edge(b, d, g);
delay_map[ed] = 1.8;
boost::tie(ed, inserted) = add_edge(c, a, g);
delay_map[ed] = 2.6;
boost::tie(ed, inserted) = add_edge(c, e, g);
delay_map[ed] = 5.2;
boost::tie(ed, inserted) = add_edge(d, c, g);
delay_map[ed] = 0.4;
boost::tie(ed, inserted) = add_edge(d, e, g);
delay_map[ed] = 3.3;
}
template <typename VertexNameMap>
class bfs_name_printer : public default_bfs_visitor {
// inherit default (empty) event point actions
template < typename VertexNameMap >
class bfs_name_printer : public default_bfs_visitor
{
// inherit default (empty) event point actions
public:
bfs_name_printer(VertexNameMap n_map) : m_name_map(n_map) {
}
template <typename Vertex, typename Graph>
void discover_vertex(Vertex u, const Graph &) const
{
std::cout << get(m_name_map, u) << ' ';
}
bfs_name_printer(VertexNameMap n_map) : m_name_map(n_map) {}
template < typename Vertex, typename Graph >
void discover_vertex(Vertex u, const Graph&) const
{
std::cout << get(m_name_map, u) << ' ';
}
private:
VertexNameMap m_name_map;
VertexNameMap m_name_map;
};
struct VP {
char name;
};
struct EP {
double weight;
};
int
main()
struct VP
{
typedef adjacency_list < listS, vecS, directedS, VP, EP> graph_t;
graph_t g;
char name;
};
property_map<graph_t, char VP::*>::type name_map = get(&VP::name, g);
property_map<graph_t, double EP::*>::type delay_map = get(&EP::weight, g);
struct EP
{
double weight;
};
build_router_network(g, name_map, delay_map);
int main()
{
typedef adjacency_list< listS, vecS, directedS, VP, EP > graph_t;
graph_t g;
typedef property_map<graph_t, char VP::*>::type VertexNameMap;
graph_traits<graph_t>::vertex_descriptor a = *vertices(g).first;
bfs_name_printer<VertexNameMap> vis(name_map);
std::cout << "BFS vertex discover order: ";
breadth_first_search(g, a, visitor(vis));
std::cout << std::endl;
property_map< graph_t, char VP::* >::type name_map = get(&VP::name, g);
property_map< graph_t, double EP::* >::type delay_map = get(&EP::weight, g);
build_router_network(g, name_map, delay_map);
typedef property_map< graph_t, char VP::* >::type VertexNameMap;
graph_traits< graph_t >::vertex_descriptor a = *vertices(g).first;
bfs_name_printer< VertexNameMap > vis(name_map);
std::cout << "BFS vertex discover order: ";
breadth_first_search(g, a, visitor(vis));
std::cout << std::endl;
}

View File

@@ -21,7 +21,7 @@
#include <boost/graph/graph_utility.hpp>
/*
This examples shows how to use the breadth_first_search() GGCL
algorithm, specifically the 3 argument variant of bfs that assumes
the graph has a color property (property) stored internally.
@@ -37,17 +37,17 @@
Sample Output:
0 --> 2
1 --> 1 3 4
2 --> 1 3 4
3 --> 1 4
4 --> 0 1
0 --> 2
1 --> 1 3 4
2 --> 1 3 4
3 --> 1 4
4 --> 0 1
distances: 0 2 1 2 2
0 --> 2
1 --> 1 3 4
2 --> 1 3 4
3 --> 1 4
4 --> 0 1
0 --> 2
1 --> 1 3 4
2 --> 1 3 4
3 --> 1 4
4 --> 0 1
distances: 0 2 1 2 2
parent[0] = 0
parent[1] = 2
parent[2] = 0
@@ -56,105 +56,104 @@
*/
template <class ParentDecorator>
struct print_parent {
print_parent(const ParentDecorator& p_) : p(p_) { }
template <class Vertex>
void operator()(const Vertex& v) const {
std::cout << "parent[" << v << "] = " << p[v] << std::endl;
}
ParentDecorator p;
template < class ParentDecorator > struct print_parent
{
print_parent(const ParentDecorator& p_) : p(p_) {}
template < class Vertex > void operator()(const Vertex& v) const
{
std::cout << "parent[" << v << "] = " << p[v] << std::endl;
}
ParentDecorator p;
};
template <class NewGraph, class Tag>
struct graph_copier
: public boost::base_visitor<graph_copier<NewGraph, Tag> >
template < class NewGraph, class Tag >
struct graph_copier
: public boost::base_visitor< graph_copier< NewGraph, Tag > >
{
typedef Tag event_filter;
typedef Tag event_filter;
graph_copier(NewGraph& graph) : new_g(graph) { }
graph_copier(NewGraph& graph) : new_g(graph) {}
template < class Edge, class Graph > void operator()(Edge e, Graph& g)
{
boost::add_edge(boost::source(e, g), boost::target(e, g), new_g);
}
template <class Edge, class Graph>
void operator()(Edge e, Graph& g) {
boost::add_edge(boost::source(e, g), boost::target(e, g), new_g);
}
private:
NewGraph& new_g;
NewGraph& new_g;
};
template <class NewGraph, class Tag>
inline graph_copier<NewGraph, Tag>
copy_graph(NewGraph& g, Tag) {
return graph_copier<NewGraph, Tag>(g);
}
int main(int , char* [])
template < class NewGraph, class Tag >
inline graph_copier< NewGraph, Tag > copy_graph(NewGraph& g, Tag)
{
typedef boost::adjacency_list<
boost::mapS, boost::vecS, boost::bidirectionalS,
boost::property<boost::vertex_color_t, boost::default_color_type,
boost::property<boost::vertex_degree_t, int,
boost::property<boost::vertex_in_degree_t, int,
boost::property<boost::vertex_out_degree_t, int> > > >
> Graph;
Graph G(5);
boost::add_edge(0, 2, G);
boost::add_edge(1, 1, G);
boost::add_edge(1, 3, G);
boost::add_edge(1, 4, G);
boost::add_edge(2, 1, G);
boost::add_edge(2, 3, G);
boost::add_edge(2, 4, G);
boost::add_edge(3, 1, G);
boost::add_edge(3, 4, G);
boost::add_edge(4, 0, G);
boost::add_edge(4, 1, G);
typedef Graph::vertex_descriptor Vertex;
Graph G_copy(5);
// Array to store predecessor (parent) of each vertex. This will be
// used as a Decorator (actually, its iterator will be).
std::vector<Vertex> p(boost::num_vertices(G));
// VC++ version of std::vector has no ::pointer, so
// I use ::value_type* instead.
typedef std::vector<Vertex>::value_type* Piter;
// Array to store distances from the source to each vertex . We use
// a built-in array here just for variety. This will also be used as
// a Decorator.
boost::graph_traits<Graph>::vertices_size_type d[5];
std::fill_n(d, 5, 0);
// The source vertex
Vertex s = *(boost::vertices(G).first);
p[s] = s;
boost::breadth_first_search
(G, s,
boost::visitor(boost::make_bfs_visitor
(std::make_pair(boost::record_distances(d, boost::on_tree_edge()),
std::make_pair
(boost::record_predecessors(&p[0],
boost::on_tree_edge()),
copy_graph(G_copy, boost::on_examine_edge())))) ));
boost::print_graph(G);
boost::print_graph(G_copy);
if (boost::num_vertices(G) < 11) {
std::cout << "distances: ";
#ifdef BOOST_OLD_STREAM_ITERATORS
std::copy(d, d + 5, std::ostream_iterator<int, char>(std::cout, " "));
#else
std::copy(d, d + 5, std::ostream_iterator<int>(std::cout, " "));
#endif
std::cout << std::endl;
std::for_each(boost::vertices(G).first, boost::vertices(G).second,
print_parent<Piter>(&p[0]));
}
return 0;
return graph_copier< NewGraph, Tag >(g);
}
int main(int, char*[])
{
typedef boost::adjacency_list< boost::mapS, boost::vecS,
boost::bidirectionalS,
boost::property< boost::vertex_color_t, boost::default_color_type,
boost::property< boost::vertex_degree_t, int,
boost::property< boost::vertex_in_degree_t, int,
boost::property< boost::vertex_out_degree_t, int > > > > >
Graph;
Graph G(5);
boost::add_edge(0, 2, G);
boost::add_edge(1, 1, G);
boost::add_edge(1, 3, G);
boost::add_edge(1, 4, G);
boost::add_edge(2, 1, G);
boost::add_edge(2, 3, G);
boost::add_edge(2, 4, G);
boost::add_edge(3, 1, G);
boost::add_edge(3, 4, G);
boost::add_edge(4, 0, G);
boost::add_edge(4, 1, G);
typedef Graph::vertex_descriptor Vertex;
Graph G_copy(5);
// Array to store predecessor (parent) of each vertex. This will be
// used as a Decorator (actually, its iterator will be).
std::vector< Vertex > p(boost::num_vertices(G));
// VC++ version of std::vector has no ::pointer, so
// I use ::value_type* instead.
typedef std::vector< Vertex >::value_type* Piter;
// Array to store distances from the source to each vertex . We use
// a built-in array here just for variety. This will also be used as
// a Decorator.
boost::graph_traits< Graph >::vertices_size_type d[5];
std::fill_n(d, 5, 0);
// The source vertex
Vertex s = *(boost::vertices(G).first);
p[s] = s;
boost::breadth_first_search(G, s,
boost::visitor(boost::make_bfs_visitor(
std::make_pair(boost::record_distances(d, boost::on_tree_edge()),
std::make_pair(
boost::record_predecessors(&p[0], boost::on_tree_edge()),
copy_graph(G_copy, boost::on_examine_edge()))))));
boost::print_graph(G);
boost::print_graph(G_copy);
if (boost::num_vertices(G) < 11)
{
std::cout << "distances: ";
#ifdef BOOST_OLD_STREAM_ITERATORS
std::copy(d, d + 5, std::ostream_iterator< int, char >(std::cout, " "));
#else
std::copy(d, d + 5, std::ostream_iterator< int >(std::cout, " "));
#endif
std::cout << std::endl;
std::for_each(boost::vertices(G).first, boost::vertices(G).second,
print_parent< Piter >(&p[0]));
}
return 0;
}

View File

@@ -1,14 +1,14 @@
0 --> 2
1 --> 1 3 4
2 --> 1 3 4
3 --> 1 4
4 --> 0 1
0 --> 2
1 --> 1 3 4
2 --> 1 3 4
3 --> 1 4
4 --> 0 1
distances: 0 2 1 2 2
0 --> 2
1 --> 1 3 4
2 --> 1 3 4
3 --> 1 4
4 --> 0 1
0 --> 2
1 --> 1 3 4
2 --> 1 3 4
3 --> 1 4
4 --> 0 1
distances: 0 2 1 2 2
parent[0] = 0
parent[1] = 2
parent[2] = 0

View File

@@ -1,2 +1,2 @@
order of discovery: s r w v t x u y
order of finish: s r w v t x u y
order of discovery: s r w v t x u y
order of finish: s r w v t x u y

View File

@@ -21,7 +21,7 @@
#include <boost/property_map/property_map.hpp>
/*
This examples shows how to use the breadth_first_search() GGCL
algorithm, specifically the 3 argument variant of bfs that assumes
the graph has a color property (property) stored internally.
@@ -37,12 +37,12 @@
Sample Output:
0 --> 2
1 --> 1 3 4
2 --> 1 3 4
3 --> 1 4
4 --> 0 1
distances: 1 2 1 2 0
0 --> 2
1 --> 1 3 4
2 --> 1 3 4
3 --> 1 4
4 --> 0 1
distances: 1 2 1 2 0
parent[0] = 4
parent[1] = 2
parent[2] = 0
@@ -51,101 +51,100 @@
*/
template <class ParentDecorator>
struct print_parent {
print_parent(const ParentDecorator& p_) : p(p_) { }
template <class Vertex>
void operator()(const Vertex& v) const {
std::cout << "parent[" << v << "] = " << p[v] << std::endl;
}
ParentDecorator p;
template < class ParentDecorator > struct print_parent
{
print_parent(const ParentDecorator& p_) : p(p_) {}
template < class Vertex > void operator()(const Vertex& v) const
{
std::cout << "parent[" << v << "] = " << p[v] << std::endl;
}
ParentDecorator p;
};
template <class NewGraph, class Tag>
struct graph_copier
: public boost::base_visitor<graph_copier<NewGraph, Tag> >
template < class NewGraph, class Tag >
struct graph_copier
: public boost::base_visitor< graph_copier< NewGraph, Tag > >
{
typedef Tag event_filter;
typedef Tag event_filter;
graph_copier(NewGraph& graph) : new_g(graph) { }
graph_copier(NewGraph& graph) : new_g(graph) {}
template < class Edge, class Graph > void operator()(Edge e, Graph& g)
{
boost::add_edge(boost::source(e, g), boost::target(e, g), new_g);
}
template <class Edge, class Graph>
void operator()(Edge e, Graph& g) {
boost::add_edge(boost::source(e, g), boost::target(e, g), new_g);
}
private:
NewGraph& new_g;
NewGraph& new_g;
};
template <class NewGraph, class Tag>
inline graph_copier<NewGraph, Tag>
copy_graph(NewGraph& g, Tag) {
return graph_copier<NewGraph, Tag>(g);
}
int main(int , char* [])
template < class NewGraph, class Tag >
inline graph_copier< NewGraph, Tag > copy_graph(NewGraph& g, Tag)
{
typedef boost::adjacency_list<
boost::mapS, boost::vecS, boost::bidirectionalS,
boost::property<boost::vertex_color_t, boost::default_color_type,
boost::property<boost::vertex_degree_t, int,
boost::property<boost::vertex_in_degree_t, int,
boost::property<boost::vertex_out_degree_t, int> > > >
> Graph;
Graph G(5);
boost::add_edge(0, 2, G);
boost::add_edge(1, 1, G);
boost::add_edge(1, 3, G);
boost::add_edge(1, 4, G);
boost::add_edge(2, 1, G);
boost::add_edge(2, 3, G);
boost::add_edge(2, 4, G);
boost::add_edge(3, 1, G);
boost::add_edge(3, 4, G);
boost::add_edge(4, 0, G);
boost::add_edge(4, 1, G);
typedef Graph::vertex_descriptor Vertex;
// Array to store predecessor (parent) of each vertex. This will be
// used as a Decorator (actually, its iterator will be).
std::vector<Vertex> p(boost::num_vertices(G));
// VC++ version of std::vector has no ::pointer, so
// I use ::value_type* instead.
typedef std::vector<Vertex>::value_type* Piter;
// Array to store distances from the source to each vertex . We use
// a built-in array here just for variety. This will also be used as
// a Decorator.
boost::graph_traits<Graph>::vertices_size_type d[5];
std::fill_n(d, 5, 0);
// The source vertex
Vertex s = *(boost::vertices(G).first);
p[s] = s;
boost::neighbor_breadth_first_search
(G, s,
boost::visitor(boost::make_neighbor_bfs_visitor
(std::make_pair(boost::record_distances(d, boost::on_tree_edge()),
boost::record_predecessors(&p[0],
boost::on_tree_edge())))));
boost::print_graph(G);
if (boost::num_vertices(G) < 11) {
std::cout << "distances: ";
#ifdef BOOST_OLD_STREAM_ITERATORS
std::copy(d, d + 5, std::ostream_iterator<int, char>(std::cout, " "));
#else
std::copy(d, d + 5, std::ostream_iterator<int>(std::cout, " "));
#endif
std::cout << std::endl;
std::for_each(boost::vertices(G).first, boost::vertices(G).second,
print_parent<Piter>(&p[0]));
}
return 0;
return graph_copier< NewGraph, Tag >(g);
}
int main(int, char*[])
{
typedef boost::adjacency_list< boost::mapS, boost::vecS,
boost::bidirectionalS,
boost::property< boost::vertex_color_t, boost::default_color_type,
boost::property< boost::vertex_degree_t, int,
boost::property< boost::vertex_in_degree_t, int,
boost::property< boost::vertex_out_degree_t, int > > > > >
Graph;
Graph G(5);
boost::add_edge(0, 2, G);
boost::add_edge(1, 1, G);
boost::add_edge(1, 3, G);
boost::add_edge(1, 4, G);
boost::add_edge(2, 1, G);
boost::add_edge(2, 3, G);
boost::add_edge(2, 4, G);
boost::add_edge(3, 1, G);
boost::add_edge(3, 4, G);
boost::add_edge(4, 0, G);
boost::add_edge(4, 1, G);
typedef Graph::vertex_descriptor Vertex;
// Array to store predecessor (parent) of each vertex. This will be
// used as a Decorator (actually, its iterator will be).
std::vector< Vertex > p(boost::num_vertices(G));
// VC++ version of std::vector has no ::pointer, so
// I use ::value_type* instead.
typedef std::vector< Vertex >::value_type* Piter;
// Array to store distances from the source to each vertex . We use
// a built-in array here just for variety. This will also be used as
// a Decorator.
boost::graph_traits< Graph >::vertices_size_type d[5];
std::fill_n(d, 5, 0);
// The source vertex
Vertex s = *(boost::vertices(G).first);
p[s] = s;
boost::neighbor_breadth_first_search(G, s,
boost::visitor(boost::make_neighbor_bfs_visitor(
std::make_pair(boost::record_distances(d, boost::on_tree_edge()),
boost::record_predecessors(&p[0], boost::on_tree_edge())))));
boost::print_graph(G);
if (boost::num_vertices(G) < 11)
{
std::cout << "distances: ";
#ifdef BOOST_OLD_STREAM_ITERATORS
std::copy(d, d + 5, std::ostream_iterator< int, char >(std::cout, " "));
#else
std::copy(d, d + 5, std::ostream_iterator< int >(std::cout, " "));
#endif
std::cout << std::endl;
std::for_each(boost::vertices(G).first, boost::vertices(G).second,
print_parent< Piter >(&p[0]));
}
return 0;
}

View File

@@ -1,5 +1,5 @@
//=======================================================================
// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee,
// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee,
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
@@ -15,59 +15,61 @@
namespace boost
{
struct edge_component_t
{
enum
{ num = 555 };
typedef edge_property_tag kind;
}
edge_component;
}
int
main()
struct edge_component_t
{
using namespace boost;
typedef adjacency_list < vecS, vecS, undirectedS,
no_property, property < edge_component_t, std::size_t > >graph_t;
typedef graph_traits < graph_t >::vertex_descriptor vertex_t;
graph_t g(9);
add_edge(0, 5, g);
add_edge(0, 1, g);
add_edge(0, 6, g);
add_edge(1, 2, g);
add_edge(1, 3, g);
add_edge(1, 4, g);
add_edge(2, 3, g);
add_edge(4, 5, g);
add_edge(6, 8, g);
add_edge(6, 7, g);
add_edge(7, 8, g);
property_map < graph_t, edge_component_t >::type
component = get(edge_component, g);
std::size_t num_comps = biconnected_components(g, component);
std::cerr << "Found " << num_comps << " biconnected components.\n";
std::vector<vertex_t> art_points;
articulation_points(g, std::back_inserter(art_points));
std::cerr << "Found " << art_points.size() << " articulation points.\n";
std::cout << "graph A {\n" << " node[shape=\"circle\"]\n";
for (std::size_t i = 0; i < art_points.size(); ++i) {
std::cout << (char)(art_points[i] + 'A')
<< " [ style=\"filled\", fillcolor=\"red\" ];"
<< std::endl;
}
graph_traits < graph_t >::edge_iterator ei, ei_end;
for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei)
std::cout << (char)(source(*ei, g) + 'A') << " -- "
<< (char)(target(*ei, g) + 'A')
<< "[label=\"" << component[*ei] << "\"]\n";
std::cout << "}\n";
return 0;
enum
{
num = 555
};
typedef edge_property_tag kind;
} edge_component;
}
int main()
{
using namespace boost;
typedef adjacency_list< vecS, vecS, undirectedS, no_property,
property< edge_component_t, std::size_t > >
graph_t;
typedef graph_traits< graph_t >::vertex_descriptor vertex_t;
graph_t g(9);
add_edge(0, 5, g);
add_edge(0, 1, g);
add_edge(0, 6, g);
add_edge(1, 2, g);
add_edge(1, 3, g);
add_edge(1, 4, g);
add_edge(2, 3, g);
add_edge(4, 5, g);
add_edge(6, 8, g);
add_edge(6, 7, g);
add_edge(7, 8, g);
property_map< graph_t, edge_component_t >::type component
= get(edge_component, g);
std::size_t num_comps = biconnected_components(g, component);
std::cerr << "Found " << num_comps << " biconnected components.\n";
std::vector< vertex_t > art_points;
articulation_points(g, std::back_inserter(art_points));
std::cerr << "Found " << art_points.size() << " articulation points.\n";
std::cout << "graph A {\n"
<< " node[shape=\"circle\"]\n";
for (std::size_t i = 0; i < art_points.size(); ++i)
{
std::cout << (char)(art_points[i] + 'A')
<< " [ style=\"filled\", fillcolor=\"red\" ];" << std::endl;
}
graph_traits< graph_t >::edge_iterator ei, ei_end;
for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei)
std::cout << (char)(source(*ei, g) + 'A') << " -- "
<< (char)(target(*ei, g) + 'A') << "[label=\""
<< component[*ei] << "\"]\n";
std::cout << "}\n";
return 0;
}

View File

@@ -18,98 +18,108 @@ using namespace boost;
/// Example to test for bipartiteness and print the certificates.
template <typename Graph>
void print_bipartite (const Graph& g)
template < typename Graph > void print_bipartite(const Graph& g)
{
typedef graph_traits <Graph> traits;
typename traits::vertex_iterator vertex_iter, vertex_end;
typedef graph_traits< Graph > traits;
typename traits::vertex_iterator vertex_iter, vertex_end;
/// Most simple interface just tests for bipartiteness.
/// Most simple interface just tests for bipartiteness.
bool bipartite = is_bipartite (g);
bool bipartite = is_bipartite(g);
if (bipartite)
{
typedef std::vector <default_color_type> partition_t;
typedef typename property_map <Graph, vertex_index_t>::type index_map_t;
typedef iterator_property_map <partition_t::iterator, index_map_t> partition_map_t;
partition_t partition (num_vertices (g));
partition_map_t partition_map (partition.begin (), get (vertex_index, g));
/// A second interface yields a bipartition in a color map, if the graph is bipartite.
is_bipartite (g, get (vertex_index, g), partition_map);
for (boost::tie (vertex_iter, vertex_end) = vertices (g); vertex_iter != vertex_end; ++vertex_iter)
if (bipartite)
{
std::cout << "Vertex " << *vertex_iter << " has color " << (get (partition_map, *vertex_iter) == color_traits <
default_color_type>::white () ? "white" : "black") << std::endl;
typedef std::vector< default_color_type > partition_t;
typedef
typename property_map< Graph, vertex_index_t >::type index_map_t;
typedef iterator_property_map< partition_t::iterator, index_map_t >
partition_map_t;
partition_t partition(num_vertices(g));
partition_map_t partition_map(partition.begin(), get(vertex_index, g));
/// A second interface yields a bipartition in a color map, if the graph
/// is bipartite.
is_bipartite(g, get(vertex_index, g), partition_map);
for (boost::tie(vertex_iter, vertex_end) = vertices(g);
vertex_iter != vertex_end; ++vertex_iter)
{
std::cout
<< "Vertex " << *vertex_iter << " has color "
<< (get(partition_map, *vertex_iter)
== color_traits< default_color_type >::white()
? "white"
: "black")
<< std::endl;
}
}
}
else
{
typedef std::vector <typename traits::vertex_descriptor> vertex_vector_t;
vertex_vector_t odd_cycle;
/// A third interface yields an odd-cycle if the graph is not bipartite.
find_odd_cycle (g, get (vertex_index, g), std::back_inserter (odd_cycle));
std::cout << "Odd cycle consists of the vertices:";
for (size_t i = 0; i < odd_cycle.size (); ++i)
else
{
std::cout << " " << odd_cycle[i];
typedef std::vector< typename traits::vertex_descriptor >
vertex_vector_t;
vertex_vector_t odd_cycle;
/// A third interface yields an odd-cycle if the graph is not bipartite.
find_odd_cycle(g, get(vertex_index, g), std::back_inserter(odd_cycle));
std::cout << "Odd cycle consists of the vertices:";
for (size_t i = 0; i < odd_cycle.size(); ++i)
{
std::cout << " " << odd_cycle[i];
}
std::cout << std::endl;
}
std::cout << std::endl;
}
}
int main (int argc, char **argv)
int main(int argc, char** argv)
{
typedef adjacency_list <vecS, vecS, undirectedS> vector_graph_t;
typedef std::pair <int, int> E;
typedef adjacency_list< vecS, vecS, undirectedS > vector_graph_t;
typedef std::pair< int, int > E;
/**
* Create the graph drawn below.
*
* 0 - 1 - 2
* | |
* 3 - 4 - 5 - 6
* / \ /
* | 7
* | |
* 8 - 9 - 10
**/
/**
* Create the graph drawn below.
*
* 0 - 1 - 2
* | |
* 3 - 4 - 5 - 6
* / \ /
* | 7
* | |
* 8 - 9 - 10
**/
E bipartite_edges[] = { E (0, 1), E (0, 4), E (1, 2), E (2, 6), E (3, 4), E (3, 8), E (4, 5), E (4, 7), E (5, 6), E (
6, 7), E (7, 10), E (8, 9), E (9, 10) };
vector_graph_t bipartite_vector_graph (&bipartite_edges[0],
&bipartite_edges[0] + sizeof(bipartite_edges) / sizeof(E), 11);
E bipartite_edges[]
= { E(0, 1), E(0, 4), E(1, 2), E(2, 6), E(3, 4), E(3, 8), E(4, 5),
E(4, 7), E(5, 6), E(6, 7), E(7, 10), E(8, 9), E(9, 10) };
vector_graph_t bipartite_vector_graph(&bipartite_edges[0],
&bipartite_edges[0] + sizeof(bipartite_edges) / sizeof(E), 11);
/**
* Create the graph drawn below.
*
* 2 - 1 - 0
* | |
* 3 - 6 - 5 - 4
* / \ /
* | 7
* | /
* 8 ---- 9
*
**/
/**
* Create the graph drawn below.
*
* 2 - 1 - 0
* | |
* 3 - 6 - 5 - 4
* / \ /
* | 7
* | /
* 8 ---- 9
*
**/
E non_bipartite_edges[] = { E (0, 1), E (0, 4), E (1, 2), E (2, 6), E (3, 6), E (3, 8), E (4, 5), E (4, 7), E (5, 6),
E (6, 7), E (7, 9), E (8, 9) };
vector_graph_t non_bipartite_vector_graph (&non_bipartite_edges[0], &non_bipartite_edges[0]
+ sizeof(non_bipartite_edges) / sizeof(E), 10);
E non_bipartite_edges[] = { E(0, 1), E(0, 4), E(1, 2), E(2, 6), E(3, 6),
E(3, 8), E(4, 5), E(4, 7), E(5, 6), E(6, 7), E(7, 9), E(8, 9) };
vector_graph_t non_bipartite_vector_graph(&non_bipartite_edges[0],
&non_bipartite_edges[0] + sizeof(non_bipartite_edges) / sizeof(E), 10);
/// Call test routine for a bipartite and a non-bipartite graph.
/// Call test routine for a bipartite and a non-bipartite graph.
print_bipartite (bipartite_vector_graph);
print_bipartite(bipartite_vector_graph);
print_bipartite (non_bipartite_vector_graph);
print_bipartite(non_bipartite_vector_graph);
return 0;
return 0;
}

View File

@@ -19,195 +19,202 @@
#include <boost/graph/breadth_first_search.hpp>
#include <boost/graph/depth_first_search.hpp>
template <class Distance>
template < class Distance >
class calc_distance_visitor : public boost::bfs_visitor<>
{
public:
calc_distance_visitor(Distance d) : distance(d) { }
calc_distance_visitor(Distance d) : distance(d) {}
template < class Graph >
void tree_edge(
typename boost::graph_traits< Graph >::edge_descriptor e, Graph& g)
{
typename boost::graph_traits< Graph >::vertex_descriptor u, v;
u = boost::source(e, g);
v = boost::target(e, g);
distance[v] = distance[u] + 1;
}
template <class Graph>
void tree_edge(typename boost::graph_traits<Graph>::edge_descriptor e,
Graph& g)
{
typename boost::graph_traits<Graph>::vertex_descriptor u, v;
u = boost::source(e, g);
v = boost::target(e, g);
distance[v] = distance[u] + 1;
}
private:
Distance distance;
Distance distance;
};
template <class VertexNameMap, class DistanceMap>
template < class VertexNameMap, class DistanceMap >
class print_tree_visitor : public boost::dfs_visitor<>
{
public:
print_tree_visitor(VertexNameMap n, DistanceMap d) : name(n), distance(d) { }
template <class Graph>
void
discover_vertex(typename boost::graph_traits<Graph>::vertex_descriptor v,
Graph&)
{
typedef typename boost::property_traits<DistanceMap>::value_type Dist;
// indentation based on depth
for (Dist i = 0; i < distance[v]; ++i)
std::cout << " ";
std::cout << name[v] << std::endl;
}
print_tree_visitor(VertexNameMap n, DistanceMap d) : name(n), distance(d) {}
template < class Graph >
void discover_vertex(
typename boost::graph_traits< Graph >::vertex_descriptor v, Graph&)
{
typedef typename boost::property_traits< DistanceMap >::value_type Dist;
// indentation based on depth
for (Dist i = 0; i < distance[v]; ++i)
std::cout << " ";
std::cout << name[v] << std::endl;
}
template <class Graph>
void tree_edge(typename boost::graph_traits<Graph>::edge_descriptor e,
Graph& g)
{
distance[boost::target(e, g)] = distance[boost::source(e, g)] + 1;
}
template < class Graph >
void tree_edge(
typename boost::graph_traits< Graph >::edge_descriptor e, Graph& g)
{
distance[boost::target(e, g)] = distance[boost::source(e, g)] + 1;
}
private:
VertexNameMap name;
DistanceMap distance;
VertexNameMap name;
DistanceMap distance;
};
int
main(int argc, const char** argv)
int main(int argc, const char** argv)
{
using namespace boost;
using namespace boost;
std::ifstream datafile(argc >= 2 ? argv[1] : "./boost_web.dat");
if (!datafile) {
std::cerr << "No ./boost_web.dat file" << std::endl;
return -1;
}
//===========================================================================
// Declare the graph type and object, and some property maps.
typedef adjacency_list<vecS, vecS, directedS,
property<vertex_name_t, std::string,
property<vertex_color_t, default_color_type> >,
property<edge_name_t, std::string, property<edge_weight_t, int> >
> Graph;
typedef graph_traits<Graph> Traits;
typedef Traits::vertex_descriptor Vertex;
typedef Traits::edge_descriptor Edge;
typedef std::map<std::string, Vertex> NameVertexMap;
NameVertexMap name2vertex;
Graph g;
typedef property_map<Graph, vertex_name_t>::type NameMap;
NameMap node_name = get(vertex_name, g);
property_map<Graph, edge_name_t>::type link_name = get(edge_name, g);
//===========================================================================
// Read the data file and construct the graph.
std::string line;
while (std::getline(datafile,line)) {
std::list<std::string> line_toks;
boost::stringtok(line_toks, line, "|");
NameVertexMap::iterator pos;
bool inserted;
Vertex u, v;
std::list<std::string>::iterator i = line_toks.begin();
boost::tie(pos, inserted) = name2vertex.insert(std::make_pair(*i, Vertex()));
if (inserted) {
u = add_vertex(g);
put(node_name, u, *i);
pos->second = u;
} else
u = pos->second;
++i;
std::string hyperlink_name = *i++;
boost::tie(pos, inserted) = name2vertex.insert(std::make_pair(*i, Vertex()));
if (inserted) {
v = add_vertex(g);
put(node_name, v, *i);
pos->second = v;
} else
v = pos->second;
Edge e;
boost::tie(e, inserted) = add_edge(u, v, g);
if (inserted) {
put(link_name, e, hyperlink_name);
std::ifstream datafile(argc >= 2 ? argv[1] : "./boost_web.dat");
if (!datafile)
{
std::cerr << "No ./boost_web.dat file" << std::endl;
return -1;
}
}
//===========================================================================
// Calculate the diameter of the graph.
//===========================================================================
// Declare the graph type and object, and some property maps.
typedef Traits::vertices_size_type size_type;
typedef std::vector<size_type> IntVector;
// Create N x N matrix for storing the shortest distances
// between each vertex. Initialize all distances to zero.
std::vector<IntVector> d_matrix(num_vertices(g),
IntVector(num_vertices(g), 0));
typedef adjacency_list< vecS, vecS, directedS,
property< vertex_name_t, std::string,
property< vertex_color_t, default_color_type > >,
property< edge_name_t, std::string, property< edge_weight_t, int > > >
Graph;
size_type i;
for (i = 0; i < num_vertices(g); ++i) {
calc_distance_visitor<size_type*> vis(&d_matrix[i][0]);
Traits::vertex_descriptor src = vertices(g).first[i];
breadth_first_search(g, src, boost::visitor(vis));
}
typedef graph_traits< Graph > Traits;
typedef Traits::vertex_descriptor Vertex;
typedef Traits::edge_descriptor Edge;
size_type diameter = 0;
BOOST_USING_STD_MAX();
for (i = 0; i < num_vertices(g); ++i)
diameter = max BOOST_PREVENT_MACRO_SUBSTITUTION(diameter, *std::max_element(d_matrix[i].begin(),
d_matrix[i].end()));
std::cout << "The diameter of the boost web-site graph is " << diameter
<< std::endl << std::endl;
typedef std::map< std::string, Vertex > NameVertexMap;
NameVertexMap name2vertex;
Graph g;
std::cout << "Number of clicks from the home page: " << std::endl;
Traits::vertex_iterator vi, vi_end;
for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
std::cout << d_matrix[0][*vi] << "\t" << node_name[*vi] << std::endl;
std::cout << std::endl;
//===========================================================================
// Print out the breadth-first search tree starting at the home page
typedef property_map< Graph, vertex_name_t >::type NameMap;
NameMap node_name = get(vertex_name, g);
property_map< Graph, edge_name_t >::type link_name = get(edge_name, g);
// Create storage for a mapping from vertices to their parents
std::vector<Traits::vertex_descriptor> parent(num_vertices(g));
for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
parent[*vi] = *vi;
//===========================================================================
// Read the data file and construct the graph.
// Do a BFS starting at the home page, recording the parent of each
// vertex (where parent is with respect to the search tree).
Traits::vertex_descriptor src = vertices(g).first[0];
breadth_first_search
(g, src,
boost::visitor(make_bfs_visitor(record_predecessors(&parent[0],
on_tree_edge()))));
std::string line;
while (std::getline(datafile, line))
{
// Add all the search tree edges into a new graph
Graph search_tree(num_vertices(g));
boost::tie(vi, vi_end) = vertices(g);
++vi;
for (; vi != vi_end; ++vi)
add_edge(parent[*vi], *vi, search_tree);
std::list< std::string > line_toks;
boost::stringtok(line_toks, line, "|");
std::cout << "The breadth-first search tree:" << std::endl;
NameVertexMap::iterator pos;
bool inserted;
Vertex u, v;
// Print out the search tree. We use DFS because it visits
// the tree nodes in the order that we want to print out:
// a directory-structure like format.
std::vector<size_type> dfs_distances(num_vertices(g), 0);
print_tree_visitor<NameMap, size_type*>
tree_printer(node_name, &dfs_distances[0]);
for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
get(vertex_color, g)[*vi] = white_color;
depth_first_visit(search_tree, src, tree_printer, get(vertex_color, g));
return EXIT_SUCCESS;
std::list< std::string >::iterator i = line_toks.begin();
boost::tie(pos, inserted)
= name2vertex.insert(std::make_pair(*i, Vertex()));
if (inserted)
{
u = add_vertex(g);
put(node_name, u, *i);
pos->second = u;
}
else
u = pos->second;
++i;
std::string hyperlink_name = *i++;
boost::tie(pos, inserted)
= name2vertex.insert(std::make_pair(*i, Vertex()));
if (inserted)
{
v = add_vertex(g);
put(node_name, v, *i);
pos->second = v;
}
else
v = pos->second;
Edge e;
boost::tie(e, inserted) = add_edge(u, v, g);
if (inserted)
{
put(link_name, e, hyperlink_name);
}
}
//===========================================================================
// Calculate the diameter of the graph.
typedef Traits::vertices_size_type size_type;
typedef std::vector< size_type > IntVector;
// Create N x N matrix for storing the shortest distances
// between each vertex. Initialize all distances to zero.
std::vector< IntVector > d_matrix(
num_vertices(g), IntVector(num_vertices(g), 0));
size_type i;
for (i = 0; i < num_vertices(g); ++i)
{
calc_distance_visitor< size_type* > vis(&d_matrix[i][0]);
Traits::vertex_descriptor src = vertices(g).first[i];
breadth_first_search(g, src, boost::visitor(vis));
}
size_type diameter = 0;
BOOST_USING_STD_MAX();
for (i = 0; i < num_vertices(g); ++i)
diameter = max BOOST_PREVENT_MACRO_SUBSTITUTION(diameter,
*std::max_element(d_matrix[i].begin(), d_matrix[i].end()));
std::cout << "The diameter of the boost web-site graph is " << diameter
<< std::endl
<< std::endl;
std::cout << "Number of clicks from the home page: " << std::endl;
Traits::vertex_iterator vi, vi_end;
for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
std::cout << d_matrix[0][*vi] << "\t" << node_name[*vi] << std::endl;
std::cout << std::endl;
//===========================================================================
// Print out the breadth-first search tree starting at the home page
// Create storage for a mapping from vertices to their parents
std::vector< Traits::vertex_descriptor > parent(num_vertices(g));
for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
parent[*vi] = *vi;
// Do a BFS starting at the home page, recording the parent of each
// vertex (where parent is with respect to the search tree).
Traits::vertex_descriptor src = vertices(g).first[0];
breadth_first_search(g, src,
boost::visitor(
make_bfs_visitor(record_predecessors(&parent[0], on_tree_edge()))));
// Add all the search tree edges into a new graph
Graph search_tree(num_vertices(g));
boost::tie(vi, vi_end) = vertices(g);
++vi;
for (; vi != vi_end; ++vi)
add_edge(parent[*vi], *vi, search_tree);
std::cout << "The breadth-first search tree:" << std::endl;
// Print out the search tree. We use DFS because it visits
// the tree nodes in the order that we want to print out:
// a directory-structure like format.
std::vector< size_type > dfs_distances(num_vertices(g), 0);
print_tree_visitor< NameMap, size_type* > tree_printer(
node_name, &dfs_distances[0]);
for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
get(vertex_color, g)[*vi] = white_color;
depth_first_visit(search_tree, src, tree_printer, get(vertex_color, g));
return EXIT_SUCCESS;
}

View File

@@ -1,6 +1,6 @@
The diameter of the boost web-site graph is 2
Number of clicks from the home page:
Number of clicks from the home page:
0 www.boost.org
1 Boost Libraries
1 More Information

View File

@@ -68,44 +68,47 @@
int main()
{
using namespace boost;
using namespace boost;
typedef adjacency_list_traits < vecS, vecS, directedS > Traits;
typedef adjacency_list < vecS, vecS, directedS,
property < vertex_name_t, std::string,
property < vertex_index_t, long,
property < vertex_color_t, boost::default_color_type,
property < vertex_distance_t, long,
property < vertex_predecessor_t, Traits::edge_descriptor > > > > >,
typedef adjacency_list_traits< vecS, vecS, directedS > Traits;
typedef adjacency_list< vecS, vecS, directedS,
property< vertex_name_t, std::string,
property< vertex_index_t, long,
property< vertex_color_t, boost::default_color_type,
property< vertex_distance_t, long,
property< vertex_predecessor_t,
Traits::edge_descriptor > > > > >,
property < edge_capacity_t, long,
property < edge_residual_capacity_t, long,
property < edge_reverse_t, Traits::edge_descriptor > > > > Graph;
property< edge_capacity_t, long,
property< edge_residual_capacity_t, long,
property< edge_reverse_t, Traits::edge_descriptor > > > >
Graph;
Graph g;
property_map < Graph, edge_capacity_t >::type
capacity = get(edge_capacity, g);
property_map < Graph, edge_residual_capacity_t >::type
residual_capacity = get(edge_residual_capacity, g);
property_map < Graph, edge_reverse_t >::type rev = get(edge_reverse, g);
Traits::vertex_descriptor s, t;
read_dimacs_max_flow(g, capacity, rev, s, t);
Graph g;
property_map< Graph, edge_capacity_t >::type capacity
= get(edge_capacity, g);
property_map< Graph, edge_residual_capacity_t >::type residual_capacity
= get(edge_residual_capacity, g);
property_map< Graph, edge_reverse_t >::type rev = get(edge_reverse, g);
Traits::vertex_descriptor s, t;
read_dimacs_max_flow(g, capacity, rev, s, t);
std::vector<default_color_type> color(num_vertices(g));
std::vector<long> distance(num_vertices(g));
long flow = boykov_kolmogorov_max_flow(g ,s, t);
std::vector< default_color_type > color(num_vertices(g));
std::vector< long > distance(num_vertices(g));
long flow = boykov_kolmogorov_max_flow(g, s, t);
std::cout << "c The total flow:" << std::endl;
std::cout << "s " << flow << std::endl << std::endl;
std::cout << "c The total flow:" << std::endl;
std::cout << "s " << flow << std::endl << std::endl;
std::cout << "c flow values:" << std::endl;
graph_traits < Graph >::vertex_iterator u_iter, u_end;
graph_traits < Graph >::out_edge_iterator ei, e_end;
for (boost::tie(u_iter, u_end) = vertices(g); u_iter != u_end; ++u_iter)
for (boost::tie(ei, e_end) = out_edges(*u_iter, g); ei != e_end; ++ei)
if (capacity[*ei] > 0)
std::cout << "f " << *u_iter << " " << target(*ei, g) << " "
<< (capacity[*ei] - residual_capacity[*ei]) << std::endl;
std::cout << "c flow values:" << std::endl;
graph_traits< Graph >::vertex_iterator u_iter, u_end;
graph_traits< Graph >::out_edge_iterator ei, e_end;
for (boost::tie(u_iter, u_end) = vertices(g); u_iter != u_end; ++u_iter)
for (boost::tie(ei, e_end) = out_edges(*u_iter, g); ei != e_end; ++ei)
if (capacity[*ei] > 0)
std::cout << "f " << *u_iter << " " << target(*ei, g) << " "
<< (capacity[*ei] - residual_capacity[*ei])
<< std::endl;
return EXIT_SUCCESS;
return EXIT_SUCCESS;
}

View File

@@ -19,11 +19,10 @@ using namespace boost;
// Declare the graph type and its vertex and edge types.
typedef undirected_graph<> Graph;
typedef graph_traits<Graph>::vertex_descriptor Vertex;
typedef graph_traits<Graph>::edge_descriptor Edge;
typedef graph_traits< Graph >::vertex_descriptor Vertex;
typedef graph_traits< Graph >::edge_descriptor Edge;
int
main(int argc, char *argv[])
int main(int argc, char* argv[])
{
// Create the graph and read it from standard input.
Graph g;

View File

@@ -17,19 +17,17 @@ using namespace boost;
// The clique_printer is a visitor that will print the vertices that comprise
// a clique. Note that the vertices are not given in any specific order.
template <typename OutputStream>
struct clique_printer
template < typename OutputStream > struct clique_printer
{
clique_printer(OutputStream& stream)
: os(stream)
{ }
clique_printer(OutputStream& stream) : os(stream) {}
template <typename Clique, typename Graph>
template < typename Clique, typename Graph >
void clique(const Clique& c, const Graph& g)
{
// Iterate over the clique and print each vertex within it.
typename Clique::const_iterator i, end = c.end();
for(i = c.begin(); i != end; ++i) {
for (i = c.begin(); i != end; ++i)
{
os << g[*i].name << " ";
}
os << endl;
@@ -44,16 +42,15 @@ struct Actor
};
// Declare the graph type and its vertex and edge types.
typedef undirected_graph<Actor> Graph;
typedef graph_traits<Graph>::vertex_descriptor Vertex;
typedef graph_traits<Graph>::edge_descriptor Edge;
typedef undirected_graph< Actor > Graph;
typedef graph_traits< Graph >::vertex_descriptor Vertex;
typedef graph_traits< Graph >::edge_descriptor Edge;
// The name map provides an abstract accessor for the names of
// each vertex. This is used during graph creation.
typedef property_map<Graph, string Actor::*>::type NameMap;
typedef property_map< Graph, string Actor::* >::type NameMap;
int
main(int argc, char *argv[])
int main(int argc, char* argv[])
{
// Create the graph and and its name map accessor.
Graph g;
@@ -63,7 +60,7 @@ main(int argc, char *argv[])
read_graph(g, nm, cin);
// Instantiate the visitor for printing cliques
clique_printer<ostream> vis(cout);
clique_printer< ostream > vis(cout);
// Use the Bron-Kerbosch algorithm to find all cliques, printing them
// as they are found.

View File

@@ -14,85 +14,102 @@
#include <stdlib.h>
#include <boost/pending/bucket_sorter.hpp>
int main() {
using namespace std;
using boost::bucket_sorter;
int main()
{
using namespace std;
using boost::bucket_sorter;
const std::size_t N = 10;
const std::size_t N = 10;
vector<std::size_t> bucket(N);
for (std::size_t i=0; i<N; i++) {
bucket[i] = rand() % N;
cout.width(6);
cout << "Number " << i << " is in bucket " << bucket[i] << endl;
}
typedef boost::identity_property_map ID;
typedef bucket_sorter<std::size_t, int,
vector<std::size_t>::iterator, ID> BS;
BS my_bucket_sorter(N, N, bucket.begin());
for (std::size_t ii=0; ii<N; ii++)
my_bucket_sorter.push(ii);
std::size_t j;
for (j=0; j<N; j++) {
cout << "The bucket " << j;
if ( ! my_bucket_sorter[j].empty() ) {
cout << " has number ";
do {
int v = my_bucket_sorter[j].top();
my_bucket_sorter[j].pop();
cout << v << " ";
} while ( ! my_bucket_sorter[j].empty() );
cout << endl;
} else {
cout << " has no number associated with it." << endl;
vector< std::size_t > bucket(N);
for (std::size_t i = 0; i < N; i++)
{
bucket[i] = rand() % N;
cout.width(6);
cout << "Number " << i << " is in bucket " << bucket[i] << endl;
}
}
for (std::size_t k=0; k<N; k++)
my_bucket_sorter.push(k);
typedef boost::identity_property_map ID;
typedef bucket_sorter< std::size_t, int, vector< std::size_t >::iterator,
ID >
BS;
BS my_bucket_sorter(N, N, bucket.begin());
my_bucket_sorter.remove(5);
my_bucket_sorter.remove(7);
for (std::size_t ii = 0; ii < N; ii++)
my_bucket_sorter.push(ii);
cout << "After removing numbers 5 and 7, check correctness again." << endl;
for (j=0; j<N; j++) {
cout << "The bucket " << j;
if ( ! my_bucket_sorter[j].empty() ) {
cout << " has number ";
do {
int v = my_bucket_sorter[j].top();
my_bucket_sorter[j].pop();
cout << v << " ";
} while ( ! my_bucket_sorter[j].empty() );
cout << endl;
} else {
cout << " has no number associated with it." << endl;
std::size_t j;
for (j = 0; j < N; j++)
{
cout << "The bucket " << j;
if (!my_bucket_sorter[j].empty())
{
cout << " has number ";
do
{
int v = my_bucket_sorter[j].top();
my_bucket_sorter[j].pop();
cout << v << " ";
} while (!my_bucket_sorter[j].empty());
cout << endl;
}
else
{
cout << " has no number associated with it." << endl;
}
}
}
std::size_t iii;
for (iii=0; iii<N; iii++) {
std::size_t current = rand() % N;
if ( ! my_bucket_sorter[current].empty() ) {
int v = my_bucket_sorter[current].top();
my_bucket_sorter[current].pop();
bucket[v] = rand() % N;
my_bucket_sorter.push(v);
}
}
for (std::size_t k = 0; k < N; k++)
my_bucket_sorter.push(k);
for (iii=0; iii<N; iii++) {
std::size_t current = rand() % N;
if ( ! my_bucket_sorter[current].empty() ) {
int v = my_bucket_sorter[current].top();
bucket[v] = rand() % N;
my_bucket_sorter.update(v);
my_bucket_sorter.remove(5);
my_bucket_sorter.remove(7);
cout << "After removing numbers 5 and 7, check correctness again." << endl;
for (j = 0; j < N; j++)
{
cout << "The bucket " << j;
if (!my_bucket_sorter[j].empty())
{
cout << " has number ";
do
{
int v = my_bucket_sorter[j].top();
my_bucket_sorter[j].pop();
cout << v << " ";
} while (!my_bucket_sorter[j].empty());
cout << endl;
}
else
{
cout << " has no number associated with it." << endl;
}
}
std::size_t iii;
for (iii = 0; iii < N; iii++)
{
std::size_t current = rand() % N;
if (!my_bucket_sorter[current].empty())
{
int v = my_bucket_sorter[current].top();
my_bucket_sorter[current].pop();
bucket[v] = rand() % N;
my_bucket_sorter.push(v);
}
}
for (iii = 0; iii < N; iii++)
{
std::size_t current = rand() % N;
if (!my_bucket_sorter[current].empty())
{
int v = my_bucket_sorter[current].top();
bucket[v] = rand() % N;
my_bucket_sorter.update(v);
}
}
}
return 0;
}

View File

@@ -16,77 +16,65 @@
#include <boost/graph/planar_canonical_ordering.hpp>
#include <boost/graph/boyer_myrvold_planar_test.hpp>
using namespace boost;
int main(int argc, char** argv)
{
typedef adjacency_list
< vecS,
vecS,
undirectedS,
property<vertex_index_t, int>,
property<edge_index_t, int>
>
graph;
typedef adjacency_list< vecS, vecS, undirectedS,
property< vertex_index_t, int >, property< edge_index_t, int > >
graph;
// Create a maximal planar graph on 6 vertices
graph g(6);
// Create a maximal planar graph on 6 vertices
graph g(6);
add_edge(0,1,g);
add_edge(1,2,g);
add_edge(2,3,g);
add_edge(3,4,g);
add_edge(4,5,g);
add_edge(5,0,g);
add_edge(0, 1, g);
add_edge(1, 2, g);
add_edge(2, 3, g);
add_edge(3, 4, g);
add_edge(4, 5, g);
add_edge(5, 0, g);
add_edge(0,2,g);
add_edge(0,3,g);
add_edge(0,4,g);
add_edge(0, 2, g);
add_edge(0, 3, g);
add_edge(0, 4, g);
add_edge(1,3,g);
add_edge(1,4,g);
add_edge(1,5,g);
add_edge(1, 3, g);
add_edge(1, 4, g);
add_edge(1, 5, g);
// Initialize the interior edge index
property_map<graph, edge_index_t>::type e_index = get(edge_index, g);
graph_traits<graph>::edges_size_type edge_count = 0;
graph_traits<graph>::edge_iterator ei, ei_end;
for(boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei)
put(e_index, *ei, edge_count++);
// Initialize the interior edge index
property_map< graph, edge_index_t >::type e_index = get(edge_index, g);
graph_traits< graph >::edges_size_type edge_count = 0;
graph_traits< graph >::edge_iterator ei, ei_end;
for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei)
put(e_index, *ei, edge_count++);
// Test for planarity - we know it is planar, we just want to
// compute the planar embedding as a side-effect
typedef std::vector< graph_traits<graph>::edge_descriptor > vec_t;
std::vector<vec_t> embedding(num_vertices(g));
if (boyer_myrvold_planarity_test(boyer_myrvold_params::graph = g,
boyer_myrvold_params::embedding =
make_iterator_property_map(
embedding.begin(), get(vertex_index, g))
)
)
std::cout << "Input graph is planar" << std::endl;
else
std::cout << "Input graph is not planar" << std::endl;
// Test for planarity - we know it is planar, we just want to
// compute the planar embedding as a side-effect
typedef std::vector< graph_traits< graph >::edge_descriptor > vec_t;
std::vector< vec_t > embedding(num_vertices(g));
if (boyer_myrvold_planarity_test(boyer_myrvold_params::graph = g,
boyer_myrvold_params::embedding = make_iterator_property_map(
embedding.begin(), get(vertex_index, g))))
std::cout << "Input graph is planar" << std::endl;
else
std::cout << "Input graph is not planar" << std::endl;
typedef std::vector<graph_traits<graph>::vertex_descriptor>
ordering_storage_t;
ordering_storage_t ordering;
planar_canonical_ordering(g,
make_iterator_property_map(
embedding.begin(), get(vertex_index, g)),
std::back_inserter(ordering));
typedef std::vector< graph_traits< graph >::vertex_descriptor >
ordering_storage_t;
ordering_storage_t::iterator oi, oi_end;
oi_end = ordering.end();
std::cout << "The planar canonical ordering is: ";
for(oi = ordering.begin(); oi != oi_end; ++oi)
std::cout << *oi << " ";
std::cout << std::endl;
ordering_storage_t ordering;
planar_canonical_ordering(g,
make_iterator_property_map(embedding.begin(), get(vertex_index, g)),
std::back_inserter(ordering));
return 0;
ordering_storage_t::iterator oi, oi_end;
oi_end = ordering.end();
std::cout << "The planar canonical ordering is: ";
for (oi = ordering.begin(); oi != oi_end; ++oi)
std::cout << *oi << " ";
std::cout << std::endl;
return 0;
}

View File

@@ -1,5 +1,5 @@
//=======================================================================
// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee,
// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee,
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
@@ -9,8 +9,8 @@
/*
IMPORTANT!!!
~~~~~~~~~~~~
This example uses interfaces that have been deprecated and removed from Boost.Grpah.
Someone needs to update it, as it does NOT compile.
This example uses interfaces that have been deprecated and removed from
Boost.Grpah. Someone needs to update it, as it does NOT compile.
*/
#include <boost/config.hpp>
@@ -20,30 +20,28 @@
#include <boost/graph/connected_components.hpp>
#include <boost/graph/graphviz.hpp>
int
main()
int main()
{
using namespace boost;
GraphvizGraph g;
read_graphviz("figs/cc-internet.dot", g);
using namespace boost;
GraphvizGraph g;
read_graphviz("figs/cc-internet.dot", g);
std::vector<int> component(num_vertices(g));
std::vector< int > component(num_vertices(g));
connected_components
(g, make_iterator_property_map(component.begin(),
get(vertex_index, g), component[0]));
property_map < GraphvizGraph, vertex_attribute_t >::type
vertex_attr_map = get(vertex_attribute, g);
std::string color[] = {
"white", "gray", "black", "lightgray"};
graph_traits < GraphvizGraph >::vertex_iterator vi, vi_end;
for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) {
vertex_attr_map[*vi]["color"] = color[component[*vi]];
vertex_attr_map[*vi]["style"] = "filled";
if (vertex_attr_map[*vi]["color"] == "black")
vertex_attr_map[*vi]["fontcolor"] = "white";
}
write_graphviz("figs/cc-internet-out.dot", g);
connected_components(g,
make_iterator_property_map(
component.begin(), get(vertex_index, g), component[0]));
property_map< GraphvizGraph, vertex_attribute_t >::type vertex_attr_map
= get(vertex_attribute, g);
std::string color[] = { "white", "gray", "black", "lightgray" };
graph_traits< GraphvizGraph >::vertex_iterator vi, vi_end;
for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
{
vertex_attr_map[*vi]["color"] = color[component[*vi]];
vertex_attr_map[*vi]["style"] = "filled";
if (vertex_attr_map[*vi]["color"] == "black")
vertex_attr_map[*vi]["fontcolor"] = "white";
}
write_graphviz("figs/cc-internet-out.dot", g);
}

View File

@@ -19,9 +19,8 @@
#include <boost/property_map/property_map.hpp>
#include <boost/graph/graph_utility.hpp> // for boost::make_list
/*
Example of using a visitor with the depth first search
Example of using a visitor with the depth first search
and breadth first search algorithm
Sacramento ---- Reno ---- Salt Lake City
@@ -32,11 +31,11 @@
|
Los Angeles ---- Las Vegas ---- Phoenix
|
San Diego
San Diego
The visitor has three main functions:
The visitor has three main functions:
discover_vertex(u,g) is invoked when the algorithm first arrives at the
vertex u. This will happen in the depth first or breadth first
order depending on which algorithm you use.
@@ -47,94 +46,103 @@
visit(u).
finish_vertex(u,g) is called when after all the vertices reachable from vertex
u have already been visited.
u have already been visited.
*/
using namespace std;
using namespace boost;
struct city_arrival : public base_visitor<city_arrival>
struct city_arrival : public base_visitor< city_arrival >
{
city_arrival(string* n) : names(n) { }
typedef on_discover_vertex event_filter;
template <class Vertex, class Graph>
inline void operator()(Vertex u, Graph&) {
cout << endl << "arriving at " << names[u] << endl
<< " neighboring cities are: ";
}
string* names;
city_arrival(string* n) : names(n) {}
typedef on_discover_vertex event_filter;
template < class Vertex, class Graph >
inline void operator()(Vertex u, Graph&)
{
cout << endl
<< "arriving at " << names[u] << endl
<< " neighboring cities are: ";
}
string* names;
};
struct neighbor_cities : public base_visitor<neighbor_cities>
struct neighbor_cities : public base_visitor< neighbor_cities >
{
neighbor_cities(string* n) : names(n) { }
typedef on_examine_edge event_filter;
template <class Edge, class Graph>
inline void operator()(Edge e, Graph& g) {
cout << names[ target(e, g) ] << ", ";
}
string* names;
neighbor_cities(string* n) : names(n) {}
typedef on_examine_edge event_filter;
template < class Edge, class Graph >
inline void operator()(Edge e, Graph& g)
{
cout << names[target(e, g)] << ", ";
}
string* names;
};
struct finish_city : public base_visitor<finish_city>
struct finish_city : public base_visitor< finish_city >
{
finish_city(string* n) : names(n) { }
typedef on_finish_vertex event_filter;
template <class Vertex, class Graph>
inline void operator()(Vertex u, Graph&) {
cout << endl << "finished with " << names[u] << endl;
}
string* names;
finish_city(string* n) : names(n) {}
typedef on_finish_vertex event_filter;
template < class Vertex, class Graph >
inline void operator()(Vertex u, Graph&)
{
cout << endl << "finished with " << names[u] << endl;
}
string* names;
};
int main(int, char*[])
int main(int, char*[])
{
enum { SanJose, SanFran, LA, SanDiego, Fresno, LasVegas, Reno,
Sacramento, SaltLake, Phoenix, N };
enum
{
SanJose,
SanFran,
LA,
SanDiego,
Fresno,
LasVegas,
Reno,
Sacramento,
SaltLake,
Phoenix,
N
};
string names[] = { "San Jose", "San Francisco", "Los Angeles", "San Diego",
"Fresno", "Las Vegas", "Reno", "Sacramento",
"Salt Lake City", "Phoenix" };
string names[]
= { "San Jose", "San Francisco", "Los Angeles", "San Diego", "Fresno",
"Las Vegas", "Reno", "Sacramento", "Salt Lake City", "Phoenix" };
typedef std::pair<int,int> E;
E edge_array[] = { E(Sacramento, Reno), E(Sacramento, SanFran),
E(Reno, SaltLake),
E(SanFran, SanJose),
E(SanJose, Fresno), E(SanJose, LA),
E(LA, LasVegas), E(LA, SanDiego),
E(LasVegas, Phoenix) };
typedef std::pair< int, int > E;
E edge_array[]
= { E(Sacramento, Reno), E(Sacramento, SanFran), E(Reno, SaltLake),
E(SanFran, SanJose), E(SanJose, Fresno), E(SanJose, LA),
E(LA, LasVegas), E(LA, SanDiego), E(LasVegas, Phoenix) };
/* Create the graph type we want. */
typedef adjacency_list<vecS, vecS, undirectedS> Graph;
/* Create the graph type we want. */
typedef adjacency_list< vecS, vecS, undirectedS > Graph;
#if defined(BOOST_MSVC) && BOOST_MSVC <= 1300
// VC++ has trouble with the edge iterator constructor
Graph G(N);
for (std::size_t j = 0; j < sizeof(edge_array)/sizeof(E); ++j)
add_edge(edge_array[j].first, edge_array[j].second, G);
// VC++ has trouble with the edge iterator constructor
Graph G(N);
for (std::size_t j = 0; j < sizeof(edge_array) / sizeof(E); ++j)
add_edge(edge_array[j].first, edge_array[j].second, G);
#else
Graph G(edge_array, edge_array + sizeof(edge_array)/sizeof(E), N);
Graph G(edge_array, edge_array + sizeof(edge_array) / sizeof(E), N);
#endif
cout << "*** Depth First ***" << endl;
depth_first_search
(G,
visitor(make_dfs_visitor(boost::make_list(city_arrival(names),
neighbor_cities(names),
finish_city(names)))));
cout << endl;
cout << "*** Depth First ***" << endl;
depth_first_search(G,
visitor(make_dfs_visitor(boost::make_list(
city_arrival(names), neighbor_cities(names), finish_city(names)))));
cout << endl;
/* Get the source vertex */
boost::graph_traits<Graph>::vertex_descriptor
s = vertex(SanJose,G);
/* Get the source vertex */
boost::graph_traits< Graph >::vertex_descriptor s = vertex(SanJose, G);
cout << "*** Breadth First ***" << endl;
breadth_first_search
(G, s, visitor(make_bfs_visitor(boost::make_list(city_arrival(names),
neighbor_cities(names),
finish_city(names)))));
return 0;
cout << "*** Breadth First ***" << endl;
breadth_first_search(G, s,
visitor(make_bfs_visitor(boost::make_list(
city_arrival(names), neighbor_cities(names), finish_city(names)))));
return 0;
}

View File

@@ -25,32 +25,31 @@ struct Actor
};
// Declare the graph type and its vertex and edge types.
typedef undirected_graph<Actor> Graph;
typedef graph_traits<Graph>::vertex_descriptor Vertex;
typedef graph_traits<Graph>::edge_descriptor Edge;
typedef undirected_graph< Actor > Graph;
typedef graph_traits< Graph >::vertex_descriptor Vertex;
typedef graph_traits< Graph >::edge_descriptor Edge;
// The name map provides an abstract accessor for the names of
// each vertex. This is used during graph creation.
typedef property_map<Graph, string Actor::*>::type NameMap;
typedef property_map< Graph, string Actor::* >::type NameMap;
// Declare a matrix type and its corresponding property map that
// will contain the distances between each pair of vertices.
typedef exterior_vertex_property<Graph, int> DistanceProperty;
typedef exterior_vertex_property< Graph, int > DistanceProperty;
typedef DistanceProperty::matrix_type DistanceMatrix;
typedef DistanceProperty::matrix_map_type DistanceMatrixMap;
// Declare the weight map so that each edge returns the same value.
typedef constant_property_map<Edge, int> WeightMap;
typedef constant_property_map< Edge, int > WeightMap;
// Declare a container and its corresponding property map that
// will contain the resulting closeness centralities of each
// vertex in the graph.
typedef boost::exterior_vertex_property<Graph, float> ClosenessProperty;
typedef boost::exterior_vertex_property< Graph, float > ClosenessProperty;
typedef ClosenessProperty::container_type ClosenessContainer;
typedef ClosenessProperty::map_type ClosenessMap;
int
main(int argc, char *argv[])
int main(int argc, char* argv[])
{
// Create the graph and a property map that provides access to[
// tha actor names.
@@ -74,10 +73,11 @@ main(int argc, char *argv[])
all_closeness_centralities(g, dm, cm);
// Print the closeness centrality of each vertex.
graph_traits<Graph>::vertex_iterator i, end;
for(boost::tie(i, end) = vertices(g); i != end; ++i) {
cout << setw(12) << setiosflags(ios::left)
<< g[*i].name << get(cm, *i) << endl;
graph_traits< Graph >::vertex_iterator i, end;
for (boost::tie(i, end) = vertices(g); i != end; ++i)
{
cout << setw(12) << setiosflags(ios::left) << g[*i].name << get(cm, *i)
<< endl;
}
return 0;

View File

@@ -4,7 +4,6 @@
// Boost Software License, Version 1.0 (See accompanying file
// LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
//[code_clustering_coefficient
#include <iostream>
#include <iomanip>
@@ -24,22 +23,21 @@ struct Actor
};
// Declare the graph type and its vertex and edge types.
typedef undirected_graph<Actor> Graph;
typedef graph_traits<Graph>::vertex_descriptor Vertex;
typedef graph_traits<Graph>::edge_descriptor Edge;
typedef undirected_graph< Actor > Graph;
typedef graph_traits< Graph >::vertex_descriptor Vertex;
typedef graph_traits< Graph >::edge_descriptor Edge;
// The name map provides an abstract accessor for the names of
// each vertex. This is used during graph creation.
typedef property_map<Graph, string Actor::*>::type NameMap;
typedef property_map< Graph, string Actor::* >::type NameMap;
// The clustering property, container, and map define the containment
// and abstract accessor for the clustering coefficients of vertices.
typedef exterior_vertex_property<Graph, float> ClusteringProperty;
typedef exterior_vertex_property< Graph, float > ClusteringProperty;
typedef ClusteringProperty::container_type ClusteringContainer;
typedef ClusteringProperty::map_type ClusteringMap;
int
main(int argc, char *argv[])
int main(int argc, char* argv[])
{
// Create the graph and a name map that provides access to
// then actor names.
@@ -57,10 +55,11 @@ main(int argc, char *argv[])
float cc = all_clustering_coefficients(g, cm);
// Print the clustering coefficient of each vertex.
graph_traits<Graph>::vertex_iterator i, end;
for(boost::tie(i, end) = vertices(g); i != end; ++i) {
cout << setw(12) << setiosflags(ios::left)
<< g[*i].name << get(cm, *i) << endl;
graph_traits< Graph >::vertex_iterator i, end;
for (boost::tie(i, end) = vertices(g); i != end; ++i)
{
cout << setw(12) << setiosflags(ios::left) << g[*i].name << get(cm, *i)
<< endl;
}
cout << "mean clustering coefficient: " << cc << endl;

View File

@@ -33,7 +33,7 @@
Sample output:
An undirected graph (edge list):
(0,1) (1,4) (4,0) (2,5)
(0,1) (1,4) (4,0) (2,5)
Total number of components: 3
Vertex 0 is in the component who's representative is 1
Vertex 1 is in the component who's representative is 1
@@ -42,53 +42,52 @@
Vertex 4 is in the component who's representative is 1
Vertex 5 is in the component who's representative is 5
component 0 contains: 4 1 0
component 1 contains: 3
component 2 contains: 5 2
*/
component 0 contains: 4 1 0
component 1 contains: 3
component 2 contains: 5 2
*/
using namespace std;
using boost::tie;
int main(int , char* [])
int main(int, char*[])
{
using namespace boost;
typedef int Index; // ID of a Vertex
typedef pair<Index,Index> Edge;
const int N = 6;
const int E = 4;
Edge edgelist[] = { Edge(0, 1), Edge(1, 4), Edge(4, 0), Edge(2, 5) };
using namespace boost;
typedef int Index; // ID of a Vertex
typedef pair< Index, Index > Edge;
const int N = 6;
const int E = 4;
Edge edgelist[] = { Edge(0, 1), Edge(1, 4), Edge(4, 0), Edge(2, 5) };
edge_list<Edge*,Edge,ptrdiff_t,std::random_access_iterator_tag> g(edgelist, edgelist + E);
cout << "An undirected graph (edge list):" << endl;
print_edges(g, identity_property_map());
cout << endl;
disjoint_sets_with_storage<> ds(N);
incremental_components(g, ds);
component_index<int> components(&ds.parents()[0],
&ds.parents()[0] + ds.parents().size());
cout << "Total number of components: " << components.size() << endl;
for (int k = 0; k != N; ++k)
cout << "Vertex " << k << " is in the component who's representative is "
<< ds.find_set(k) << endl;
cout << endl;
for (std::size_t i = 0; i < components.size(); ++i) {
cout << "component " << i << " contains: ";
component_index<int>::component_iterator
j = components[i].first,
jend = components[i].second;
for ( ; j != jend; ++j)
cout << *j << " ";
edge_list< Edge*, Edge, ptrdiff_t, std::random_access_iterator_tag > g(
edgelist, edgelist + E);
cout << "An undirected graph (edge list):" << endl;
print_edges(g, identity_property_map());
cout << endl;
}
return 0;
disjoint_sets_with_storage<> ds(N);
incremental_components(g, ds);
component_index< int > components(
&ds.parents()[0], &ds.parents()[0] + ds.parents().size());
cout << "Total number of components: " << components.size() << endl;
for (int k = 0; k != N; ++k)
cout << "Vertex " << k
<< " is in the component who's representative is "
<< ds.find_set(k) << endl;
cout << endl;
for (std::size_t i = 0; i < components.size(); ++i)
{
cout << "component " << i << " contains: ";
component_index< int >::component_iterator j = components[i].first,
jend = components[i].second;
for (; j != jend; ++j)
cout << *j << " ";
cout << endl;
}
return 0;
}

View File

@@ -1,5 +1,5 @@
An undirected graph (edge list):
(0,1) (1,4) (4,0) (2,5)
(0,1) (1,4) (4,0) (2,5)
Total number of components: 3
Vertex 0 is in the component who's representative is 1
@@ -9,6 +9,6 @@ Vertex 3 is in the component who's representative is 3
Vertex 4 is in the component who's representative is 1
Vertex 5 is in the component who's representative is 5
component 0 contains: 4 1 0
component 1 contains: 3
component 2 contains: 5 2
component 0 contains: 4 1 0
component 1 contains: 3
component 2 contains: 5 2

View File

@@ -1,5 +1,5 @@
//=======================================================================
// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee,
// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee,
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
@@ -11,29 +11,28 @@
#include <boost/graph/connected_components.hpp>
#include <boost/graph/adjacency_list.hpp>
int
main()
int main()
{
using namespace boost;
typedef adjacency_list < vecS, vecS, undirectedS > Graph;
using namespace boost;
typedef adjacency_list< vecS, vecS, undirectedS > Graph;
const int N = 6;
Graph G(N);
add_edge(0, 1, G);
add_edge(1, 4, G);
add_edge(4, 0, G);
add_edge(2, 5, G);
const int N = 6;
Graph G(N);
add_edge(0, 1, G);
add_edge(1, 4, G);
add_edge(4, 0, G);
add_edge(2, 5, G);
std::vector<int> c(num_vertices(G));
int num = connected_components
(G, make_iterator_property_map(c.begin(), get(vertex_index, G), c[0]));
std::vector< int > c(num_vertices(G));
int num = connected_components(
G, make_iterator_property_map(c.begin(), get(vertex_index, G), c[0]));
std::cout << std::endl;
std::vector < int >::iterator i;
std::cout << "Total number of components: " << num << std::endl;
for (i = c.begin(); i != c.end(); ++i)
std::cout << "Vertex " << i - c.begin()
<< " is in component " << *i << std::endl;
std::cout << std::endl;
return EXIT_SUCCESS;
std::cout << std::endl;
std::vector< int >::iterator i;
std::cout << "Total number of components: " << num << std::endl;
for (i = c.begin(); i != c.end(); ++i)
std::cout << "Vertex " << i - c.begin() << " is in component " << *i
<< std::endl;
std::cout << std::endl;
return EXIT_SUCCESS;
}

View File

@@ -36,27 +36,27 @@
using namespace std;
int main(int , char* [])
int main(int, char*[])
{
using namespace boost;
{
typedef adjacency_list <vecS, vecS, undirectedS> Graph;
using namespace boost;
{
typedef adjacency_list< vecS, vecS, undirectedS > Graph;
Graph G;
add_edge(0, 1, G);
add_edge(1, 4, G);
add_edge(4, 0, G);
add_edge(2, 5, G);
std::vector<int> component(num_vertices(G));
int num = connected_components(G, &component[0]);
std::vector<int>::size_type i;
cout << "Total number of components: " << num << endl;
for (i = 0; i != component.size(); ++i)
cout << "Vertex " << i <<" is in component " << component[i] << endl;
cout << endl;
}
return 0;
Graph G;
add_edge(0, 1, G);
add_edge(1, 4, G);
add_edge(4, 0, G);
add_edge(2, 5, G);
std::vector< int > component(num_vertices(G));
int num = connected_components(G, &component[0]);
std::vector< int >::size_type i;
cout << "Total number of components: " << num << endl;
for (i = 0; i != component.size(); ++i)
cout << "Vertex " << i << " is in component " << component[i]
<< endl;
cout << endl;
}
return 0;
}

View File

@@ -8,40 +8,43 @@
//=======================================================================
#include <boost/graph/adjacency_list.hpp>
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(BOOST_NO_STD_ALLOCATOR)
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \
&& !defined(BOOST_NO_STD_ALLOCATOR)
template <class Allocator>
struct list_with_allocatorS { };
template < class Allocator > struct list_with_allocatorS
{
};
namespace boost {
template <class Alloc, class ValueType>
struct container_gen<list_with_allocatorS<Alloc>, ValueType> {
typedef typename Alloc::template rebind<ValueType>::other Allocator;
typedef std::list<ValueType, Allocator> type;
};
template <class Alloc>
struct parallel_edge_traits< list_with_allocatorS<Alloc> > {
namespace boost
{
template < class Alloc, class ValueType >
struct container_gen< list_with_allocatorS< Alloc >, ValueType >
{
typedef typename Alloc::template rebind< ValueType >::other Allocator;
typedef std::list< ValueType, Allocator > type;
};
template < class Alloc >
struct parallel_edge_traits< list_with_allocatorS< Alloc > >
{
typedef allow_parallel_edge_tag type;
};
};
}
// now you can define a graph using std::list and a specific allocator
typedef boost::adjacency_list< list_with_allocatorS< std::allocator<int> >,
boost::vecS, boost::directedS> MyGraph;
// now you can define a graph using std::list and a specific allocator
typedef boost::adjacency_list< list_with_allocatorS< std::allocator< int > >,
boost::vecS, boost::directedS >
MyGraph;
int main(int, char*[])
{
MyGraph g(5);
return 0;
MyGraph g(5);
return 0;
}
#else
int main(int, char*[])
{
return 0;
}
int main(int, char*[]) { return 0; }
#endif

View File

@@ -1,5 +1,5 @@
//=======================================================================
// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee,
// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee,
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
@@ -11,37 +11,44 @@
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/graph_utility.hpp>
int
main()
int main()
{
using namespace boost;
typedef adjacency_list < vecS, vecS, directedS,
property < vertex_name_t, char > > graph_t;
using namespace boost;
typedef adjacency_list< vecS, vecS, directedS,
property< vertex_name_t, char > >
graph_t;
enum
{ a, b, c, d, e, f, g, N };
graph_t G(N);
property_map < graph_t, vertex_name_t >::type
name_map = get(vertex_name, G);
char name = 'a';
graph_traits < graph_t >::vertex_iterator v, v_end;
for (boost::tie(v, v_end) = vertices(G); v != v_end; ++v, ++name)
name_map[*v] = name;
enum
{
a,
b,
c,
d,
e,
f,
g,
N
};
graph_t G(N);
property_map< graph_t, vertex_name_t >::type name_map = get(vertex_name, G);
char name = 'a';
graph_traits< graph_t >::vertex_iterator v, v_end;
for (boost::tie(v, v_end) = vertices(G); v != v_end; ++v, ++name)
name_map[*v] = name;
typedef std::pair < int, int >E;
E edges[] = { E(a, c), E(a, d), E(b, a), E(b, d), E(c, f),
E(d, c), E(d, e), E(d, f), E(e, b), E(e, g), E(f, e), E(f, g)
};
for (int i = 0; i < 12; ++i)
add_edge(edges[i].first, edges[i].second, G);
typedef std::pair< int, int > E;
E edges[] = { E(a, c), E(a, d), E(b, a), E(b, d), E(c, f), E(d, c), E(d, e),
E(d, f), E(e, b), E(e, g), E(f, e), E(f, g) };
for (int i = 0; i < 12; ++i)
add_edge(edges[i].first, edges[i].second, G);
print_graph(G, name_map);
std::cout << std::endl;
print_graph(G, name_map);
std::cout << std::endl;
graph_t G_copy;
copy_graph(G, G_copy);
graph_t G_copy;
copy_graph(G, G_copy);
print_graph(G_copy, name_map);
print_graph(G_copy, name_map);
return 0;
return 0;
}

View File

@@ -18,44 +18,44 @@ using namespace boost;
class WebPage
{
public:
std::string url;
public:
std::string url;
};
int main()
{
typedef std::pair<int, int> E;
const char* urls[6] = {
"http://www.boost.org/libs/graph/doc/index.html",
"http://www.boost.org/libs/graph/doc/table_of_contents.html",
"http://www.boost.org/libs/graph/doc/adjacency_list.html",
"http://www.boost.org/libs/graph/doc/history.html",
"http://www.boost.org/libs/graph/doc/bundles.html",
"http://www.boost.org/libs/graph/doc/using_adjacency_list.html",
};
typedef std::pair< int, int > E;
const char* urls[6] = {
"http://www.boost.org/libs/graph/doc/index.html",
"http://www.boost.org/libs/graph/doc/table_of_contents.html",
"http://www.boost.org/libs/graph/doc/adjacency_list.html",
"http://www.boost.org/libs/graph/doc/history.html",
"http://www.boost.org/libs/graph/doc/bundles.html",
"http://www.boost.org/libs/graph/doc/using_adjacency_list.html",
};
E the_edges[] = { E(0, 1), E(0, 2), E(0, 3), E(1, 0), E(1, 3), E(1, 5),
E(2, 0), E(2, 5), E(3, 1), E(3, 4), E(4, 1), E(5, 0),
E(5, 2) };
E the_edges[] = { E(0, 1), E(0, 2), E(0, 3), E(1, 0), E(1, 3), E(1, 5),
E(2, 0), E(2, 5), E(3, 1), E(3, 4), E(4, 1), E(5, 0), E(5, 2) };
typedef compressed_sparse_row_graph<directedS, WebPage> WebGraph;
WebGraph g(boost::edges_are_sorted, &the_edges[0], &the_edges[0] + sizeof(the_edges)/sizeof(E), 6);
typedef compressed_sparse_row_graph< directedS, WebPage > WebGraph;
WebGraph g(boost::edges_are_sorted, &the_edges[0],
&the_edges[0] + sizeof(the_edges) / sizeof(E), 6);
// Set the URLs of each vertex
int index = 0;
BGL_FORALL_VERTICES(v, g, WebGraph)
// Set the URLs of each vertex
int index = 0;
BGL_FORALL_VERTICES(v, g, WebGraph)
g[v].url = urls[index++];
// Output each of the links
std::cout << "The web graph:" << std::endl;
BGL_FORALL_EDGES(e, g, WebGraph)
// Output each of the links
std::cout << "The web graph:" << std::endl;
BGL_FORALL_EDGES(e, g, WebGraph)
std::cout << " " << g[source(e, g)].url << " -> " << g[target(e, g)].url
<< std::endl;
// Output the graph in DOT format
dynamic_properties dp;
dp.property("label", get(&WebPage::url, g));
std::ofstream out("web-graph.dot");
write_graphviz_dp(out, g, dp, std::string(), get(vertex_index, g));
return 0;
// Output the graph in DOT format
dynamic_properties dp;
dp.property("label", get(&WebPage::url, g));
std::ofstream out("web-graph.dot");
write_graphviz_dp(out, g, dp, std::string(), get(vertex_index, g));
return 0;
}

View File

@@ -20,112 +20,119 @@
Sample Output
original bandwidth: 8
Reverse Cuthill-McKee ordering starting at: 6
8 3 0 9 2 5 1 4 7 6
8 3 0 9 2 5 1 4 7 6
bandwidth: 4
Reverse Cuthill-McKee ordering starting at: 0
9 1 4 6 7 2 8 5 3 0
9 1 4 6 7 2 8 5 3 0
bandwidth: 4
Reverse Cuthill-McKee ordering:
0 8 5 7 3 6 4 2 1 9
0 8 5 7 3 6 4 2 1 9
bandwidth: 4
*/
int main(int , char* [])
int main(int, char*[])
{
using namespace boost;
using namespace std;
typedef adjacency_list<vecS, vecS, undirectedS,
property<vertex_color_t, default_color_type,
property<vertex_degree_t,int> > > Graph;
typedef graph_traits<Graph>::vertex_descriptor Vertex;
typedef graph_traits<Graph>::vertices_size_type size_type;
using namespace boost;
using namespace std;
typedef adjacency_list< vecS, vecS, undirectedS,
property< vertex_color_t, default_color_type,
property< vertex_degree_t, int > > >
Graph;
typedef graph_traits< Graph >::vertex_descriptor Vertex;
typedef graph_traits< Graph >::vertices_size_type size_type;
typedef std::pair<std::size_t, std::size_t> Pair;
Pair edges[14] = { Pair(0,3), //a-d
Pair(0,5), //a-f
Pair(1,2), //b-c
Pair(1,4), //b-e
Pair(1,6), //b-g
Pair(1,9), //b-j
Pair(2,3), //c-d
Pair(2,4), //c-e
Pair(3,5), //d-f
Pair(3,8), //d-i
Pair(4,6), //e-g
Pair(5,6), //f-g
Pair(5,7), //f-h
Pair(6,7) }; //g-h
Graph G(10);
for (int i = 0; i < 14; ++i)
add_edge(edges[i].first, edges[i].second, G);
typedef std::pair< std::size_t, std::size_t > Pair;
Pair edges[14] = { Pair(0, 3), // a-d
Pair(0, 5), // a-f
Pair(1, 2), // b-c
Pair(1, 4), // b-e
Pair(1, 6), // b-g
Pair(1, 9), // b-j
Pair(2, 3), // c-d
Pair(2, 4), // c-e
Pair(3, 5), // d-f
Pair(3, 8), // d-i
Pair(4, 6), // e-g
Pair(5, 6), // f-g
Pair(5, 7), // f-h
Pair(6, 7) }; // g-h
graph_traits<Graph>::vertex_iterator ui, ui_end;
Graph G(10);
for (int i = 0; i < 14; ++i)
add_edge(edges[i].first, edges[i].second, G);
property_map<Graph,vertex_degree_t>::type deg = get(vertex_degree, G);
for (boost::tie(ui, ui_end) = vertices(G); ui != ui_end; ++ui)
deg[*ui] = degree(*ui, G);
graph_traits< Graph >::vertex_iterator ui, ui_end;
property_map<Graph, vertex_index_t>::type
index_map = get(vertex_index, G);
property_map< Graph, vertex_degree_t >::type deg = get(vertex_degree, G);
for (boost::tie(ui, ui_end) = vertices(G); ui != ui_end; ++ui)
deg[*ui] = degree(*ui, G);
std::cout << "original bandwidth: " << bandwidth(G) << std::endl;
property_map< Graph, vertex_index_t >::type index_map
= get(vertex_index, G);
std::vector<Vertex> inv_perm(num_vertices(G));
std::vector<size_type> perm(num_vertices(G));
{
Vertex s = vertex(6, G);
//reverse cuthill_mckee_ordering
cuthill_mckee_ordering(G, s, inv_perm.rbegin(), get(vertex_color, G),
get(vertex_degree, G));
cout << "Reverse Cuthill-McKee ordering starting at: " << s << endl;
cout << " ";
for (std::vector<Vertex>::const_iterator i = inv_perm.begin();
i != inv_perm.end(); ++i)
cout << index_map[*i] << " ";
cout << endl;
std::cout << "original bandwidth: " << bandwidth(G) << std::endl;
for (size_type c = 0; c != inv_perm.size(); ++c)
perm[index_map[inv_perm[c]]] = c;
std::cout << " bandwidth: "
<< bandwidth(G, make_iterator_property_map(&perm[0], index_map, perm[0]))
<< std::endl;
}
{
Vertex s = vertex(0, G);
//reverse cuthill_mckee_ordering
cuthill_mckee_ordering(G, s, inv_perm.rbegin(), get(vertex_color, G),
get(vertex_degree, G));
cout << "Reverse Cuthill-McKee ordering starting at: " << s << endl;
cout << " ";
for (std::vector<Vertex>::const_iterator i=inv_perm.begin();
i != inv_perm.end(); ++i)
cout << index_map[*i] << " ";
cout << endl;
std::vector< Vertex > inv_perm(num_vertices(G));
std::vector< size_type > perm(num_vertices(G));
{
Vertex s = vertex(6, G);
// reverse cuthill_mckee_ordering
cuthill_mckee_ordering(G, s, inv_perm.rbegin(), get(vertex_color, G),
get(vertex_degree, G));
cout << "Reverse Cuthill-McKee ordering starting at: " << s << endl;
cout << " ";
for (std::vector< Vertex >::const_iterator i = inv_perm.begin();
i != inv_perm.end(); ++i)
cout << index_map[*i] << " ";
cout << endl;
for (size_type c = 0; c != inv_perm.size(); ++c)
perm[index_map[inv_perm[c]]] = c;
std::cout << " bandwidth: "
<< bandwidth(G, make_iterator_property_map(&perm[0], index_map, perm[0]))
<< std::endl;
}
for (size_type c = 0; c != inv_perm.size(); ++c)
perm[index_map[inv_perm[c]]] = c;
std::cout << " bandwidth: "
<< bandwidth(G,
make_iterator_property_map(
&perm[0], index_map, perm[0]))
<< std::endl;
}
{
Vertex s = vertex(0, G);
// reverse cuthill_mckee_ordering
cuthill_mckee_ordering(G, s, inv_perm.rbegin(), get(vertex_color, G),
get(vertex_degree, G));
cout << "Reverse Cuthill-McKee ordering starting at: " << s << endl;
cout << " ";
for (std::vector< Vertex >::const_iterator i = inv_perm.begin();
i != inv_perm.end(); ++i)
cout << index_map[*i] << " ";
cout << endl;
{
//reverse cuthill_mckee_ordering
cuthill_mckee_ordering(G, inv_perm.rbegin(), get(vertex_color, G),
make_degree_map(G));
cout << "Reverse Cuthill-McKee ordering:" << endl;
cout << " ";
for (std::vector<Vertex>::const_iterator i=inv_perm.begin();
i != inv_perm.end(); ++i)
cout << index_map[*i] << " ";
cout << endl;
for (size_type c = 0; c != inv_perm.size(); ++c)
perm[index_map[inv_perm[c]]] = c;
std::cout << " bandwidth: "
<< bandwidth(G,
make_iterator_property_map(
&perm[0], index_map, perm[0]))
<< std::endl;
}
for (size_type c = 0; c != inv_perm.size(); ++c)
perm[index_map[inv_perm[c]]] = c;
std::cout << " bandwidth: "
<< bandwidth(G, make_iterator_property_map(&perm[0], index_map, perm[0]))
<< std::endl;
}
return 0;
{
// reverse cuthill_mckee_ordering
cuthill_mckee_ordering(
G, inv_perm.rbegin(), get(vertex_color, G), make_degree_map(G));
cout << "Reverse Cuthill-McKee ordering:" << endl;
cout << " ";
for (std::vector< Vertex >::const_iterator i = inv_perm.begin();
i != inv_perm.end(); ++i)
cout << index_map[*i] << " ";
cout << endl;
for (size_type c = 0; c != inv_perm.size(); ++c)
perm[index_map[inv_perm[c]]] = c;
std::cout << " bandwidth: "
<< bandwidth(G,
make_iterator_property_map(
&perm[0], index_map, perm[0]))
<< std::endl;
}
return 0;
}

View File

@@ -1,8 +1,8 @@
degree:
2 4 3 4 3 4 4 2 1 1
degree:
2 4 3 4 3 4 4 2 1 1
Reverse Cuthill-McKee ordering starting at :6
8 3 0 9 2 5 1 4 7 6
8 3 0 9 2 5 1 4 7 6
Reverse Cuthill-McKee ordering starting at :0
9 1 4 6 7 2 8 5 3 0
9 1 4 6 7 2 8 5 3 0
Reverse Cuthill-McKee ordering:
0 8 5 7 3 6 4 2 1 9
0 8 5 7 3 6 4 2 1 9

View File

@@ -1,5 +1,5 @@
//=======================================================================
// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee,
// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee,
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
@@ -16,78 +16,79 @@ using namespace boost;
namespace std
{
template < typename T >
std::istream & operator >> (std::istream & in, std::pair < T, T > &p)
{
template < typename T >
std::istream& operator>>(std::istream& in, std::pair< T, T >& p)
{
in >> p.first >> p.second;
return in;
}
}
}
typedef adjacency_list < listS, // Store out-edges of each vertex in a std::list
vecS, // Store vertex set in a std::vector
directedS // The file dependency graph is directed
> file_dep_graph;
typedef adjacency_list< listS, // Store out-edges of each vertex in a std::list
vecS, // Store vertex set in a std::vector
directedS // The file dependency graph is directed
>
file_dep_graph;
typedef graph_traits < file_dep_graph >::vertex_descriptor vertex_t;
typedef graph_traits < file_dep_graph >::edge_descriptor edge_t;
typedef graph_traits< file_dep_graph >::vertex_descriptor vertex_t;
typedef graph_traits< file_dep_graph >::edge_descriptor edge_t;
bool
has_cycle_dfs(const file_dep_graph & g, vertex_t u,
default_color_type * color)
bool has_cycle_dfs(
const file_dep_graph& g, vertex_t u, default_color_type* color)
{
color[u] = gray_color;
graph_traits < file_dep_graph >::adjacency_iterator vi, vi_end;
for (boost::tie(vi, vi_end) = adjacent_vertices(u, g); vi != vi_end; ++vi)
if (color[*vi] == white_color) {
if (has_cycle_dfs(g, *vi, color))
return true; // cycle detected, return immediately
} else if (color[*vi] == gray_color) // *vi is an ancestor!
return true;
color[u] = black_color;
return false;
color[u] = gray_color;
graph_traits< file_dep_graph >::adjacency_iterator vi, vi_end;
for (boost::tie(vi, vi_end) = adjacent_vertices(u, g); vi != vi_end; ++vi)
if (color[*vi] == white_color)
{
if (has_cycle_dfs(g, *vi, color))
return true; // cycle detected, return immediately
}
else if (color[*vi] == gray_color) // *vi is an ancestor!
return true;
color[u] = black_color;
return false;
}
bool
has_cycle(const file_dep_graph & g)
bool has_cycle(const file_dep_graph& g)
{
std::vector < default_color_type > color(num_vertices(g), white_color);
graph_traits < file_dep_graph >::vertex_iterator vi, vi_end;
for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
if (color[*vi] == white_color)
if (has_cycle_dfs(g, *vi, &color[0]))
return true;
return false;
std::vector< default_color_type > color(num_vertices(g), white_color);
graph_traits< file_dep_graph >::vertex_iterator vi, vi_end;
for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
if (color[*vi] == white_color)
if (has_cycle_dfs(g, *vi, &color[0]))
return true;
return false;
}
int
main(int argc, const char** argv)
int main(int argc, const char** argv)
{
std::ifstream file_in(argc >= 2 ? argv[1] : "makefile-dependencies.dat");
typedef graph_traits < file_dep_graph >::vertices_size_type size_type;
size_type n_vertices;
file_in >> n_vertices; // read in number of vertices
std::istream_iterator < std::pair < size_type,
size_type > > input_begin(file_in), input_end;
std::ifstream file_in(argc >= 2 ? argv[1] : "makefile-dependencies.dat");
typedef graph_traits< file_dep_graph >::vertices_size_type size_type;
size_type n_vertices;
file_in >> n_vertices; // read in number of vertices
std::istream_iterator< std::pair< size_type, size_type > > input_begin(
file_in),
input_end;
#if defined(BOOST_MSVC) && BOOST_MSVC <= 1300
// VC++ has trouble with the edge iterator constructor
file_dep_graph g(n_vertices);
while (input_begin != input_end) {
size_type i, j;
boost::tie(i, j) = *input_begin++;
add_edge(i, j, g);
}
// VC++ has trouble with the edge iterator constructor
file_dep_graph g(n_vertices);
while (input_begin != input_end)
{
size_type i, j;
boost::tie(i, j) = *input_begin++;
add_edge(i, j, g);
}
#else
file_dep_graph g(input_begin, input_end, n_vertices);
file_dep_graph g(input_begin, input_end, n_vertices);
#endif
std::vector < std::string > name(num_vertices(g));
std::ifstream name_in(argc >= 3 ? argv[2] : "makefile-target-names.dat");
graph_traits < file_dep_graph >::vertex_iterator vi, vi_end;
for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
name_in >> name[*vi];
std::vector< std::string > name(num_vertices(g));
std::ifstream name_in(argc >= 3 ? argv[2] : "makefile-target-names.dat");
graph_traits< file_dep_graph >::vertex_iterator vi, vi_end;
for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
name_in >> name[*vi];
assert(has_cycle(g) == false);
return 0;
assert(has_cycle(g) == false);
return 0;
}

View File

@@ -1,5 +1,5 @@
//=======================================================================
// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee,
// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee,
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
@@ -16,135 +16,118 @@
// we get conflict with boost::default_dfs_visitor.
using namespace boost;
namespace std {
template <typename T >
std::istream& operator >> (std::istream & in, std::pair < T, T > &p)
{
namespace std
{
template < typename T >
std::istream& operator>>(std::istream& in, std::pair< T, T >& p)
{
in >> p.first >> p.second;
return
in;
}
return in;
}
}
typedef adjacency_list<
listS, // Store out-edges of each vertex in a std::list
vecS, // Store vertex set in a std::vector
directedS // The file dependency graph is directed
> file_dep_graph;
typedef adjacency_list< listS, // Store out-edges of each vertex in a std::list
vecS, // Store vertex set in a std::vector
directedS // The file dependency graph is directed
>
file_dep_graph;
typedef graph_traits<file_dep_graph>::vertex_descriptor vertex_t;
typedef graph_traits<file_dep_graph>::edge_descriptor edge_t;
typedef graph_traits< file_dep_graph >::vertex_descriptor vertex_t;
typedef graph_traits< file_dep_graph >::edge_descriptor edge_t;
template < typename Visitor > void
dfs_v1(const file_dep_graph & g, vertex_t u, default_color_type * color,
Visitor vis)
template < typename Visitor >
void dfs_v1(
const file_dep_graph& g, vertex_t u, default_color_type* color, Visitor vis)
{
color[u] = gray_color;
vis.discover_vertex(u, g);
graph_traits < file_dep_graph >::out_edge_iterator ei, ei_end;
for (boost::tie(ei, ei_end) = out_edges(u, g); ei != ei_end; ++ei) {
if (color[target(*ei, g)] == white_color) {
vis.tree_edge(*ei, g);
dfs_v1(g, target(*ei, g), color, vis);
} else if (color[target(*ei, g)] == gray_color)
vis.back_edge(*ei, g);
else
vis.forward_or_cross_edge(*ei, g);
}
color[u] = black_color;
vis.finish_vertex(u, g);
color[u] = gray_color;
vis.discover_vertex(u, g);
graph_traits< file_dep_graph >::out_edge_iterator ei, ei_end;
for (boost::tie(ei, ei_end) = out_edges(u, g); ei != ei_end; ++ei)
{
if (color[target(*ei, g)] == white_color)
{
vis.tree_edge(*ei, g);
dfs_v1(g, target(*ei, g), color, vis);
}
else if (color[target(*ei, g)] == gray_color)
vis.back_edge(*ei, g);
else
vis.forward_or_cross_edge(*ei, g);
}
color[u] = black_color;
vis.finish_vertex(u, g);
}
template < typename Visitor > void
generic_dfs_v1(const file_dep_graph & g, Visitor vis)
template < typename Visitor >
void generic_dfs_v1(const file_dep_graph& g, Visitor vis)
{
std::vector < default_color_type > color(num_vertices(g), white_color);
graph_traits < file_dep_graph >::vertex_iterator vi, vi_end;
for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) {
if (color[*vi] == white_color)
dfs_v1(g, *vi, &color[0], vis);
}
std::vector< default_color_type > color(num_vertices(g), white_color);
graph_traits< file_dep_graph >::vertex_iterator vi, vi_end;
for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
{
if (color[*vi] == white_color)
dfs_v1(g, *vi, &color[0], vis);
}
}
struct dfs_visitor_default
{
template <typename V, typename G > void
discover_vertex(V, const G &)
{
}
template < typename V, typename G > void discover_vertex(V, const G&) {}
template <typename E, typename G > void
tree_edge(E, const G &)
{
}
template < typename E, typename G > void tree_edge(E, const G&) {}
template < typename E, typename G > void
back_edge(E, const G &)
{
}
template < typename E, typename G > void back_edge(E, const G&) {}
template < typename E, typename G > void
forward_or_cross_edge(E, const G &)
{
}
template < typename E, typename G > void forward_or_cross_edge(E, const G&)
{
}
template < typename V, typename G > void
finish_vertex(V, const G &)
{
}
template < typename V, typename G > void finish_vertex(V, const G&) {}
};
struct cycle_detector : public dfs_visitor_default
{
cycle_detector(bool & cycle):
has_cycle(cycle)
{
}
void
back_edge(edge_t, const file_dep_graph &)
{
has_cycle = true;
}
bool & has_cycle;
cycle_detector(bool& cycle) : has_cycle(cycle) {}
void back_edge(edge_t, const file_dep_graph&) { has_cycle = true; }
bool& has_cycle;
};
bool
has_cycle(const file_dep_graph & g)
bool has_cycle(const file_dep_graph& g)
{
bool has_cycle = false;
cycle_detector vis(has_cycle);
generic_dfs_v1(g, vis);
return has_cycle;
bool has_cycle = false;
cycle_detector vis(has_cycle);
generic_dfs_v1(g, vis);
return has_cycle;
}
int
main(int argc, const char** argv)
int main(int argc, const char** argv)
{
std::ifstream file_in(argc >= 2 ? argv[1] : "makefile-dependencies.dat");
typedef graph_traits <file_dep_graph >::vertices_size_type size_type;
size_type n_vertices;
file_in >> n_vertices; // read in number of vertices
std::istream_iterator < std::pair < size_type,
size_type > >input_begin(file_in), input_end;
std::ifstream file_in(argc >= 2 ? argv[1] : "makefile-dependencies.dat");
typedef graph_traits< file_dep_graph >::vertices_size_type size_type;
size_type n_vertices;
file_in >> n_vertices; // read in number of vertices
std::istream_iterator< std::pair< size_type, size_type > > input_begin(
file_in),
input_end;
#if defined(BOOST_MSVC) && BOOST_MSVC <= 1300
// VC++ has trouble with the edge iterator constructor
file_dep_graph g(n_vertices);
while (input_begin != input_end) {
size_type i, j;
boost::tie(i, j) = *input_begin++;
add_edge(i, j, g);
}
// VC++ has trouble with the edge iterator constructor
file_dep_graph g(n_vertices);
while (input_begin != input_end)
{
size_type i, j;
boost::tie(i, j) = *input_begin++;
add_edge(i, j, g);
}
#else
file_dep_graph g(input_begin, input_end, n_vertices);
file_dep_graph g(input_begin, input_end, n_vertices);
#endif
std::vector < std::string > name(num_vertices(g));
std::ifstream name_in(argc >= 3 ? argv[2] : "makefile-target-names.dat");
graph_traits < file_dep_graph >::vertex_iterator vi, vi_end;
for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
name_in >> name[*vi];
std::vector< std::string > name(num_vertices(g));
std::ifstream name_in(argc >= 3 ? argv[2] : "makefile-target-names.dat");
graph_traits< file_dep_graph >::vertex_iterator vi, vi_end;
for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
name_in >> name[*vi];
assert(has_cycle(g) == false);
return 0;
assert(has_cycle(g) == false);
return 0;
}

View File

@@ -1,6 +1,6 @@
//=======================================================================
// Copyright 2013 University of Warsaw.
// Authors: Piotr Wygocki
// Authors: Piotr Wygocki
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
@@ -12,9 +12,9 @@
#include "../test/min_cost_max_flow_utils.hpp"
int main() {
boost::SampleGraph::vertex_descriptor s,t;
int main()
{
boost::SampleGraph::vertex_descriptor s, t;
boost::SampleGraph::Graph g;
boost::SampleGraph::getSampleGraph(g, s, t);
@@ -25,4 +25,3 @@ int main() {
assert(cost == 29);
return 0;
}

View File

@@ -18,27 +18,25 @@
*/
using namespace boost;
typedef adjacency_list<
listS, listS, directedS,
property<vertex_index_t, int>,
property<
edge_weight_t, double, property<edge_weight2_t, double>
>
> grap_real_t;
typedef adjacency_list< listS, listS, directedS,
property< vertex_index_t, int >,
property< edge_weight_t, double, property< edge_weight2_t, double > > >
grap_real_t;
template <typename TG>
void gen_rand_graph(TG &g, size_t nV, size_t nE)
template < typename TG > void gen_rand_graph(TG& g, size_t nV, size_t nE)
{
g.clear();
mt19937 rng;
rng.seed(uint32_t(time(0)));
boost::generate_random_graph(g, nV, nE, rng, true, true);
boost::uniform_real<> ur(-1,10);
boost::variate_generator<boost::mt19937&, boost::uniform_real<> > ew1rg(rng, ur);
randomize_property<edge_weight_t>(g, ew1rg);
boost::uniform_int<size_t> uint(1,5);
boost::variate_generator<boost::mt19937&, boost::uniform_int<size_t> > ew2rg(rng, uint);
randomize_property<edge_weight2_t>(g, ew2rg);
boost::uniform_real<> ur(-1, 10);
boost::variate_generator< boost::mt19937&, boost::uniform_real<> > ew1rg(
rng, ur);
randomize_property< edge_weight_t >(g, ew1rg);
boost::uniform_int< size_t > uint(1, 5);
boost::variate_generator< boost::mt19937&, boost::uniform_int< size_t > >
ew2rg(rng, uint);
randomize_property< edge_weight2_t >(g, ew2rg);
}
int main(int argc, char* argv[])
@@ -46,38 +44,42 @@ int main(int argc, char* argv[])
using std::cout;
using std::endl;
const double epsilon = 0.0000001;
double min_cr, max_cr; ///Minimum and maximum cycle ratio
typedef std::vector<graph_traits<grap_real_t>::edge_descriptor> ccReal_t;
ccReal_t cc; ///critical cycle
double min_cr, max_cr; /// Minimum and maximum cycle ratio
typedef std::vector< graph_traits< grap_real_t >::edge_descriptor >
ccReal_t;
ccReal_t cc; /// critical cycle
grap_real_t tgr;
property_map<grap_real_t, vertex_index_t>::type vim = get(vertex_index, tgr);
property_map<grap_real_t, edge_weight_t>::type ew1 = get(edge_weight, tgr);
property_map<grap_real_t, edge_weight2_t>::type ew2 = get(edge_weight2, tgr);
property_map< grap_real_t, vertex_index_t >::type vim
= get(vertex_index, tgr);
property_map< grap_real_t, edge_weight_t >::type ew1
= get(edge_weight, tgr);
property_map< grap_real_t, edge_weight2_t >::type ew2
= get(edge_weight2, tgr);
gen_rand_graph(tgr, 1000, 30000);
cout << "Vertices number: " << num_vertices(tgr) << endl;
cout << "Edges number: " << num_edges(tgr) << endl;
int i = 0;
graph_traits<grap_real_t>::vertex_iterator vi, vi_end;
for (boost::tie(vi, vi_end) = vertices(tgr); vi != vi_end; vi++) {
vim[*vi] = i++; ///Initialize vertex index property
graph_traits< grap_real_t >::vertex_iterator vi, vi_end;
for (boost::tie(vi, vi_end) = vertices(tgr); vi != vi_end; vi++)
{
vim[*vi] = i++; /// Initialize vertex index property
}
max_cr = maximum_cycle_ratio(tgr, vim, ew1, ew2);
cout << "Maximum cycle ratio is " << max_cr << endl;
min_cr = minimum_cycle_ratio(tgr, vim, ew1, ew2, &cc);
cout << "Minimum cycle ratio is " << min_cr << endl;
std::pair<double, double> cr(.0,.0);
std::pair< double, double > cr(.0, .0);
cout << "Critical cycle:\n";
for (ccReal_t::iterator itr = cc.begin(); itr != cc.end(); ++itr)
{
cr.first += ew1[*itr];
cr.second += ew2[*itr];
std::cout << "(" << vim[source(*itr, tgr)] << "," <<
vim[target(*itr, tgr)] << ") ";
std::cout << "(" << vim[source(*itr, tgr)] << ","
<< vim[target(*itr, tgr)] << ") ";
}
cout << endl;
assert(std::abs(cr.first / cr.second - min_cr) < epsilon * 2);
return EXIT_SUCCESS;
}

View File

@@ -24,46 +24,55 @@
int main()
{
using namespace boost;
typedef adjacency_list<vecS, vecS, directedS,
property<vertex_distance_t, int>, property<edge_weight_t, int> > graph_t;
graph_t g(6);
enum verts { r, s, t, u, v, x };
char name[] = "rstuvx";
add_edge(r, s, 5, g);
add_edge(r, t, 3, g);
add_edge(s, t, 2, g);
add_edge(s, u, 6, g);
add_edge(t, u, 7, g);
add_edge(t, v, 4, g);
add_edge(t, x, 2, g);
add_edge(u, v, -1, g);
add_edge(u, x, 1, g);
add_edge(v, x, -2, g);
using namespace boost;
typedef adjacency_list< vecS, vecS, directedS,
property< vertex_distance_t, int >, property< edge_weight_t, int > >
graph_t;
graph_t g(6);
enum verts
{
r,
s,
t,
u,
v,
x
};
char name[] = "rstuvx";
add_edge(r, s, 5, g);
add_edge(r, t, 3, g);
add_edge(s, t, 2, g);
add_edge(s, u, 6, g);
add_edge(t, u, 7, g);
add_edge(t, v, 4, g);
add_edge(t, x, 2, g);
add_edge(u, v, -1, g);
add_edge(u, x, 1, g);
add_edge(v, x, -2, g);
property_map<graph_t, vertex_distance_t>::type
d_map = get(vertex_distance, g);
property_map< graph_t, vertex_distance_t >::type d_map
= get(vertex_distance, g);
#if defined(BOOST_MSVC) && BOOST_MSVC <= 1300
// VC++ has trouble with the named-parameter mechanism, so
// we make a direct call to the underlying implementation function.
std::vector<default_color_type> color(num_vertices(g));
std::vector<std::size_t> pred(num_vertices(g));
default_dijkstra_visitor vis;
std::less<int> compare;
closed_plus<int> combine;
property_map<graph_t, edge_weight_t>::type w_map = get(edge_weight, g);
dag_shortest_paths(g, s, d_map, w_map, &color[0], &pred[0],
vis, compare, combine, (std::numeric_limits<int>::max)(), 0);
// VC++ has trouble with the named-parameter mechanism, so
// we make a direct call to the underlying implementation function.
std::vector< default_color_type > color(num_vertices(g));
std::vector< std::size_t > pred(num_vertices(g));
default_dijkstra_visitor vis;
std::less< int > compare;
closed_plus< int > combine;
property_map< graph_t, edge_weight_t >::type w_map = get(edge_weight, g);
dag_shortest_paths(g, s, d_map, w_map, &color[0], &pred[0], vis, compare,
combine, (std::numeric_limits< int >::max)(), 0);
#else
dag_shortest_paths(g, s, distance_map(d_map));
dag_shortest_paths(g, s, distance_map(d_map));
#endif
graph_traits<graph_t>::vertex_iterator vi , vi_end;
for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
if (d_map[*vi] == (std::numeric_limits<int>::max)())
std::cout << name[*vi] << ": inifinity\n";
else
std::cout << name[*vi] << ": " << d_map[*vi] << '\n';
return 0;
graph_traits< graph_t >::vertex_iterator vi, vi_end;
for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
if (d_map[*vi] == (std::numeric_limits< int >::max)())
std::cout << name[*vi] << ": inifinity\n";
else
std::cout << name[*vi] << ": " << d_map[*vi] << '\n';
return 0;
}

View File

@@ -8,5 +8,5 @@ n 5
# the edges
e
1 2
0 1
2 0
0 1
2 0

View File

@@ -45,7 +45,7 @@ using namespace boost;
a
Sample Output:
a --> c d
a --> c d
b --> a d
c --> f
d --> c e f
@@ -67,183 +67,172 @@ c(3); f
f(9); g e
e(4); g b
g(7);
b(14); d a
b(14); d a
*/
typedef property<vertex_color_t, default_color_type,
property<vertex_distance_t,int> > VProperty;
typedef property< vertex_color_t, default_color_type,
property< vertex_distance_t, int > >
VProperty;
typedef int weight_t;
typedef property<edge_weight_t,weight_t> EProperty;
typedef property< edge_weight_t, weight_t > EProperty;
typedef adjacency_list<vecS, vecS, directedS, VProperty, EProperty > Graph;
typedef adjacency_list< vecS, vecS, directedS, VProperty, EProperty > Graph;
template <class Tag>
struct endl_printer
: public boost::base_visitor< endl_printer<Tag> >
template < class Tag >
struct endl_printer : public boost::base_visitor< endl_printer< Tag > >
{
typedef Tag event_filter;
endl_printer(std::ostream& os) : m_os(os) { }
template <class T, class Graph>
void operator()(T, Graph&) { m_os << std::endl; }
std::ostream& m_os;
typedef Tag event_filter;
endl_printer(std::ostream& os) : m_os(os) {}
template < class T, class Graph > void operator()(T, Graph&)
{
m_os << std::endl;
}
std::ostream& m_os;
};
template <class Tag>
endl_printer<Tag> print_endl(std::ostream& os, Tag) {
return endl_printer<Tag>(os);
template < class Tag > endl_printer< Tag > print_endl(std::ostream& os, Tag)
{
return endl_printer< Tag >(os);
}
template <class PA, class Tag>
struct edge_printer
: public boost::base_visitor< edge_printer<PA, Tag> >
template < class PA, class Tag >
struct edge_printer : public boost::base_visitor< edge_printer< PA, Tag > >
{
typedef Tag event_filter;
typedef Tag event_filter;
edge_printer(PA pa, std::ostream& os) : m_pa(pa), m_os(os) { }
edge_printer(PA pa, std::ostream& os) : m_pa(pa), m_os(os) {}
template <class T, class Graph>
void operator()(T x, Graph& g) {
m_os << "(" << get(m_pa, source(x, g)) << ","
<< get(m_pa, target(x, g)) << ") ";
}
PA m_pa;
std::ostream& m_os;
template < class T, class Graph > void operator()(T x, Graph& g)
{
m_os << "(" << get(m_pa, source(x, g)) << "," << get(m_pa, target(x, g))
<< ") ";
}
PA m_pa;
std::ostream& m_os;
};
template <class PA, class Tag>
edge_printer<PA, Tag>
print_edge(PA pa, std::ostream& os, Tag) {
return edge_printer<PA, Tag>(pa, os);
template < class PA, class Tag >
edge_printer< PA, Tag > print_edge(PA pa, std::ostream& os, Tag)
{
return edge_printer< PA, Tag >(pa, os);
}
template <class NewGraph, class Tag>
struct graph_copier
: public boost::base_visitor<graph_copier<NewGraph, Tag> >
template < class NewGraph, class Tag >
struct graph_copier
: public boost::base_visitor< graph_copier< NewGraph, Tag > >
{
typedef Tag event_filter;
typedef Tag event_filter;
graph_copier(NewGraph& graph) : new_g(graph) { }
graph_copier(NewGraph& graph) : new_g(graph) {}
template < class Edge, class Graph > void operator()(Edge e, Graph& g)
{
add_edge(source(e, g), target(e, g), new_g);
}
template <class Edge, class Graph>
void operator()(Edge e, Graph& g) {
add_edge(source(e, g), target(e, g), new_g);
}
private:
NewGraph& new_g;
NewGraph& new_g;
};
template <class NewGraph, class Tag>
inline graph_copier<NewGraph, Tag>
copy_graph(NewGraph& g, Tag) {
return graph_copier<NewGraph, Tag>(g);
template < class NewGraph, class Tag >
inline graph_copier< NewGraph, Tag > copy_graph(NewGraph& g, Tag)
{
return graph_copier< NewGraph, Tag >(g);
}
template <class Graph, class Name>
void print(Graph& G, Name name)
template < class Graph, class Name > void print(Graph& G, Name name)
{
typename boost::graph_traits<Graph>::vertex_iterator ui, uiend;
for (boost::tie(ui, uiend) = vertices(G); ui != uiend; ++ui) {
cout << name[*ui] << " --> ";
typename boost::graph_traits<Graph>::adjacency_iterator vi, viend;
for(boost::tie(vi, viend) = adjacent_vertices(*ui, G); vi != viend; ++vi)
cout << name[*vi] << " ";
typename boost::graph_traits< Graph >::vertex_iterator ui, uiend;
for (boost::tie(ui, uiend) = vertices(G); ui != uiend; ++ui)
{
cout << name[*ui] << " --> ";
typename boost::graph_traits< Graph >::adjacency_iterator vi, viend;
for (boost::tie(vi, viend) = adjacent_vertices(*ui, G); vi != viend;
++vi)
cout << name[*vi] << " ";
cout << endl;
}
}
int main(int, char*[])
{
// Name and ID numbers for the vertices
char name[] = "abcdefg";
enum
{
a,
b,
c,
d,
e,
f,
g,
N
};
Graph G(N);
boost::property_map< Graph, vertex_index_t >::type vertex_id
= get(vertex_index, G);
std::vector< weight_t > distance(N, (numeric_limits< weight_t >::max)());
typedef boost::graph_traits< Graph >::vertex_descriptor Vertex;
std::vector< Vertex > parent(N);
typedef std::pair< int, int > E;
E edges[] = { E(a, c), E(a, d), E(b, a), E(b, d), E(c, f), E(d, c), E(d, e),
E(d, f), E(e, b), E(e, g), E(f, e), E(f, g) };
int weight[] = { 3, 4, 6, 8, 12, 7, 0, 5, 10, 3, 1, 2 };
for (int i = 0; i < 12; ++i)
add_edge(edges[i].first, edges[i].second, weight[i], G);
print(G, name);
adjacency_list< listS, vecS, directedS,
property< vertex_color_t, default_color_type > >
G_copy(N);
cout << "Starting graph:" << endl;
std::ostream_iterator< int > cout_int(std::cout, " ");
std::ostream_iterator< char > cout_char(std::cout, " ");
boost::queue< Vertex > Q;
boost::breadth_first_search(G, vertex(a, G), Q,
make_bfs_visitor(boost::make_list(
write_property(make_iterator_property_map(name, vertex_id, name[0]),
cout_char, on_examine_vertex()),
write_property(make_iterator_property_map(
distance.begin(), vertex_id, distance[0]),
cout_int, on_examine_vertex()),
print_edge(make_iterator_property_map(name, vertex_id, name[0]),
std::cout, on_examine_edge()),
print_endl(std::cout, on_finish_vertex()))),
get(vertex_color, G));
std::cout << "about to call dijkstra's" << std::endl;
parent[vertex(a, G)] = vertex(a, G);
boost::dijkstra_shortest_paths(G, vertex(a, G),
distance_map(make_iterator_property_map(
distance.begin(), vertex_id, distance[0]))
.predecessor_map(make_iterator_property_map(
parent.begin(), vertex_id, parent[0]))
.visitor(
make_dijkstra_visitor(copy_graph(G_copy, on_examine_edge()))));
cout << endl;
}
}
int
main(int , char* [])
{
// Name and ID numbers for the vertices
char name[] = "abcdefg";
enum { a, b, c, d, e, f, g, N};
Graph G(N);
boost::property_map<Graph, vertex_index_t>::type
vertex_id = get(vertex_index, G);
std::vector<weight_t> distance(N, (numeric_limits<weight_t>::max)());
typedef boost::graph_traits<Graph>::vertex_descriptor Vertex;
std::vector<Vertex> parent(N);
typedef std::pair<int,int> E;
E edges[] = { E(a,c), E(a,d),
E(b,a), E(b,d),
E(c,f),
E(d,c), E(d,e), E(d,f),
E(e,b), E(e,g),
E(f,e), E(f,g) };
int weight[] = { 3, 4,
6, 8,
12,
7, 0, 5,
10, 3,
1, 2 };
for (int i = 0; i < 12; ++i)
add_edge(edges[i].first, edges[i].second, weight[i], G);
print(G, name);
adjacency_list<listS, vecS, directedS,
property<vertex_color_t, default_color_type> > G_copy(N);
cout << "Starting graph:" << endl;
std::ostream_iterator<int> cout_int(std::cout, " ");
std::ostream_iterator<char> cout_char(std::cout, " ");
boost::queue<Vertex> Q;
boost::breadth_first_search
(G, vertex(a, G), Q,
make_bfs_visitor(
boost::make_list
(write_property(make_iterator_property_map(name, vertex_id,
name[0]),
cout_char, on_examine_vertex()),
write_property(make_iterator_property_map(distance.begin(),
vertex_id,
distance[0]),
cout_int, on_examine_vertex()),
print_edge(make_iterator_property_map(name, vertex_id,
name[0]),
std::cout, on_examine_edge()),
print_endl(std::cout, on_finish_vertex()))),
get(vertex_color, G));
std::cout << "about to call dijkstra's" << std::endl;
parent[vertex(a, G)] = vertex(a, G);
boost::dijkstra_shortest_paths
(G, vertex(a, G),
distance_map(make_iterator_property_map(distance.begin(), vertex_id,
distance[0])).
predecessor_map(make_iterator_property_map(parent.begin(), vertex_id,
parent[0])).
visitor(make_dijkstra_visitor(copy_graph(G_copy, on_examine_edge()))));
cout << endl;
cout << "Result:" << endl;
boost::breadth_first_search
(G, vertex(a, G),
visitor(make_bfs_visitor(
boost::make_list
(write_property(make_iterator_property_map(name, vertex_id,
name[0]),
cout_char, on_examine_vertex()),
write_property(make_iterator_property_map(distance.begin(),
vertex_id,
distance[0]),
cout_int, on_examine_vertex()),
print_edge(make_iterator_property_map(name, vertex_id,
name[0]),
std::cout, on_examine_edge()),
print_endl(std::cout, on_finish_vertex())))));
return 0;
cout << "Result:" << endl;
boost::breadth_first_search(G, vertex(a, G),
visitor(make_bfs_visitor(boost::make_list(
write_property(make_iterator_property_map(name, vertex_id, name[0]),
cout_char, on_examine_vertex()),
write_property(make_iterator_property_map(
distance.begin(), vertex_id, distance[0]),
cout_int, on_examine_vertex()),
print_edge(make_iterator_property_map(name, vertex_id, name[0]),
std::cout, on_examine_edge()),
print_endl(std::cout, on_finish_vertex())))));
return 0;
}

View File

@@ -1,24 +1,24 @@
a --> c d
b --> a d
c --> f
d --> c e f
e --> b g
f --> e g
g -->
a --> c d
b --> a d
c --> f
d --> c e f
e --> b g
f --> e g
g -->
Starting graph:
a 2147483647 (a,c) (a,d)
c 2147483647 (c,f)
d 2147483647 (d,c) (d,e) (d,f)
f 2147483647 (f,e) (f,g)
e 2147483647 (e,b) (e,g)
g 2147483647
b 2147483647 (b,a) (b,d)
a 2147483647 (a,c) (a,d)
c 2147483647 (c,f)
d 2147483647 (d,c) (d,e) (d,f)
f 2147483647 (f,e) (f,g)
e 2147483647 (e,b) (e,g)
g 2147483647
b 2147483647 (b,a) (b,d)
Result:
a 0 (a,c) (a,d)
c 3 (c,f)
d 4 (d,c) (d,e) (d,f)
f 9 (f,e) (f,g)
e 4 (e,b) (e,g)
g 7
b 14 (b,a) (b,d)
a 0 (a,c) (a,d)
c 3 (c,f)
d 4 (d,c) (d,e) (d,f)
f 9 (f,e) (f,g)
e 4 (e,b) (e,g)
g 7
b 14 (b,a) (b,d)

View File

@@ -1,5 +1,5 @@
//=======================================================================
// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee,
// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee,
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
@@ -11,36 +11,35 @@
using namespace boost;
template < typename Graph > void
read_graph_file(std::istream & in, Graph & g)
template < typename Graph > void read_graph_file(std::istream& in, Graph& g)
{
typedef typename graph_traits < Graph >::vertices_size_type size_type;
size_type n_vertices;
in >> n_vertices; // read in number of vertices
for (size_type i = 0; i < n_vertices; ++i) // Add n vertices to the graph
add_vertex(g);
size_type u, v;
while (in >> u) // Read in pairs of integers as edges
if (in >> v)
add_edge(u, v, g);
else
break;
typedef typename graph_traits< Graph >::vertices_size_type size_type;
size_type n_vertices;
in >> n_vertices; // read in number of vertices
for (size_type i = 0; i < n_vertices; ++i) // Add n vertices to the graph
add_vertex(g);
size_type u, v;
while (in >> u) // Read in pairs of integers as edges
if (in >> v)
add_edge(u, v, g);
else
break;
}
int
main(int argc, const char** argv)
int main(int argc, const char** argv)
{
typedef adjacency_list < listS, // Store out-edges of each vertex in a std::list
vecS, // Store vertex set in a std::vector
directedS // The graph is directed
> graph_type;
typedef adjacency_list< listS, // Store out-edges of each vertex in a
// std::list
vecS, // Store vertex set in a std::vector
directedS // The graph is directed
>
graph_type;
graph_type g; // use default constructor to create empty graph
std::ifstream file_in(argc >= 2 ? argv[1] : "makefile-dependencies.dat");
read_graph_file(file_in, g);
graph_type g; // use default constructor to create empty graph
std::ifstream file_in(argc >= 2 ? argv[1] : "makefile-dependencies.dat");
read_graph_file(file_in, g);
assert(num_vertices(g) == 15);
assert(num_edges(g) == 19);
return 0;
assert(num_vertices(g) == 15);
assert(num_edges(g) == 19);
return 0;
}

View File

@@ -1,5 +1,5 @@
//=======================================================================
// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee,
// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee,
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
@@ -11,39 +11,38 @@
using namespace boost;
template < typename Graph > void
read_graph_file(std::istream & in, Graph & g)
template < typename Graph > void read_graph_file(std::istream& in, Graph& g)
{
typedef typename graph_traits < Graph >::vertex_descriptor Vertex;
typedef typename graph_traits < Graph >::vertices_size_type size_type;
size_type n_vertices;
in >> n_vertices; // read in number of vertices
std::vector < Vertex > vertex_set(n_vertices);
for (size_type i = 0; i < n_vertices; ++i)
vertex_set[i] = add_vertex(g);
typedef typename graph_traits< Graph >::vertex_descriptor Vertex;
typedef typename graph_traits< Graph >::vertices_size_type size_type;
size_type n_vertices;
in >> n_vertices; // read in number of vertices
std::vector< Vertex > vertex_set(n_vertices);
for (size_type i = 0; i < n_vertices; ++i)
vertex_set[i] = add_vertex(g);
size_type u, v;
while (in >> u)
if (in >> v)
add_edge(vertex_set[u], vertex_set[v], g);
else
break;
size_type u, v;
while (in >> u)
if (in >> v)
add_edge(vertex_set[u], vertex_set[v], g);
else
break;
}
int
main(int argc, const char** argv)
int main(int argc, const char** argv)
{
typedef adjacency_list < listS, // Store out-edges of each vertex in a std::list
vecS, // Store vertex set in a std::vector
directedS // The graph is directed
> graph_type;
typedef adjacency_list< listS, // Store out-edges of each vertex in a
// std::list
vecS, // Store vertex set in a std::vector
directedS // The graph is directed
>
graph_type;
graph_type g; // use default constructor to create empty graph
std::ifstream file_in(argc >= 2 ? argv[1] : "makefile-dependencies.dat");
read_graph_file(file_in, g);
graph_type g; // use default constructor to create empty graph
std::ifstream file_in(argc >= 2 ? argv[1] : "makefile-dependencies.dat");
read_graph_file(file_in, g);
assert(num_vertices(g) == 15);
assert(num_edges(g) == 19);
return 0;
assert(num_vertices(g) == 15);
assert(num_edges(g) == 19);
return 0;
}

View File

@@ -4,7 +4,6 @@
// Boost Software License, Version 1.0 (See accompanying file
// LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
//[degree_centrality_example
#include <iostream>
#include <iomanip>
@@ -25,22 +24,21 @@ struct Actor
};
// Declare the graph type and its vertex and edge types.
typedef undirected_graph<Actor> Graph;
typedef graph_traits<Graph>::vertex_descriptor Vertex;
typedef graph_traits<Graph>::edge_descriptor Edge;
typedef undirected_graph< Actor > Graph;
typedef graph_traits< Graph >::vertex_descriptor Vertex;
typedef graph_traits< Graph >::edge_descriptor Edge;
// The name map provides an abstract accessor for the names of
// each vertex. This is used during graph creation.
typedef property_map<Graph, string Actor::*>::type NameMap;
typedef property_map< Graph, string Actor::* >::type NameMap;
// Declare a container type for degree centralities and its
// corresponding property map.
typedef exterior_vertex_property<Graph, unsigned> CentralityProperty;
typedef exterior_vertex_property< Graph, unsigned > CentralityProperty;
typedef CentralityProperty::container_type CentralityContainer;
typedef CentralityProperty::map_type CentralityMap;
int
main(int argc, char *argv[])
int main(int argc, char* argv[])
{
// Create the graph and a property map that provides access
// to the actor names.
@@ -56,10 +54,11 @@ main(int argc, char *argv[])
all_degree_centralities(g, cm);
// Print the degree centrality of each vertex.
graph_traits<Graph>::vertex_iterator i, end;
for(boost::tie(i, end) = vertices(g); i != end; ++i) {
cout << setiosflags(ios::left) << setw(12)
<< g[*i].name << cm[*i] << endl;
graph_traits< Graph >::vertex_iterator i, end;
for (boost::tie(i, end) = vertices(g); i != end; ++i)
{
cout << setiosflags(ios::left) << setw(12) << g[*i].name << cm[*i]
<< endl;
}
return 0;

View File

@@ -1,5 +1,5 @@
//=======================================================================
// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee,
// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee,
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
@@ -13,84 +13,92 @@
#include <iostream>
using namespace boost;
template < typename TimeMap > class dfs_time_visitor:public default_dfs_visitor {
typedef typename property_traits < TimeMap >::value_type T;
template < typename TimeMap >
class dfs_time_visitor : public default_dfs_visitor
{
typedef typename property_traits< TimeMap >::value_type T;
public:
dfs_time_visitor(TimeMap dmap, TimeMap fmap, T & t)
: m_dtimemap(dmap), m_ftimemap(fmap), m_time(t) {
}
template < typename Vertex, typename Graph >
void discover_vertex(Vertex u, const Graph & g) const
{
put(m_dtimemap, u, m_time++);
}
template < typename Vertex, typename Graph >
void finish_vertex(Vertex u, const Graph & g) const
{
put(m_ftimemap, u, m_time++);
}
TimeMap m_dtimemap;
TimeMap m_ftimemap;
T & m_time;
dfs_time_visitor(TimeMap dmap, TimeMap fmap, T& t)
: m_dtimemap(dmap), m_ftimemap(fmap), m_time(t)
{
}
template < typename Vertex, typename Graph >
void discover_vertex(Vertex u, const Graph& g) const
{
put(m_dtimemap, u, m_time++);
}
template < typename Vertex, typename Graph >
void finish_vertex(Vertex u, const Graph& g) const
{
put(m_ftimemap, u, m_time++);
}
TimeMap m_dtimemap;
TimeMap m_ftimemap;
T& m_time;
};
int
main()
int main()
{
// Select the graph type we wish to use
typedef adjacency_list < vecS, vecS, directedS > graph_t;
typedef graph_traits < graph_t >::vertices_size_type size_type;
// Set up the vertex names
enum
{ u, v, w, x, y, z, N };
char name[] = { 'u', 'v', 'w', 'x', 'y', 'z' };
// Specify the edges in the graph
typedef std::pair < int, int >E;
E edge_array[] = { E(u, v), E(u, x), E(x, v), E(y, x),
E(v, y), E(w, y), E(w, z), E(z, z)
};
// Select the graph type we wish to use
typedef adjacency_list< vecS, vecS, directedS > graph_t;
typedef graph_traits< graph_t >::vertices_size_type size_type;
// Set up the vertex names
enum
{
u,
v,
w,
x,
y,
z,
N
};
char name[] = { 'u', 'v', 'w', 'x', 'y', 'z' };
// Specify the edges in the graph
typedef std::pair< int, int > E;
E edge_array[] = { E(u, v), E(u, x), E(x, v), E(y, x), E(v, y), E(w, y),
E(w, z), E(z, z) };
#if defined(BOOST_MSVC) && BOOST_MSVC <= 1300
graph_t g(N);
for (std::size_t j = 0; j < sizeof(edge_array) / sizeof(E); ++j)
add_edge(edge_array[j].first, edge_array[j].second, g);
graph_t g(N);
for (std::size_t j = 0; j < sizeof(edge_array) / sizeof(E); ++j)
add_edge(edge_array[j].first, edge_array[j].second, g);
#else
graph_t g(edge_array, edge_array + sizeof(edge_array) / sizeof(E), N);
graph_t g(edge_array, edge_array + sizeof(edge_array) / sizeof(E), N);
#endif
// discover time and finish time properties
std::vector < size_type > dtime(num_vertices(g));
std::vector < size_type > ftime(num_vertices(g));
typedef
iterator_property_map<std::vector<size_type>::iterator,
property_map<graph_t, vertex_index_t>::const_type>
time_pm_type;
time_pm_type dtime_pm(dtime.begin(), get(vertex_index, g));
time_pm_type ftime_pm(ftime.begin(), get(vertex_index, g));
size_type t = 0;
dfs_time_visitor < time_pm_type >vis(dtime_pm, ftime_pm, t);
// discover time and finish time properties
std::vector< size_type > dtime(num_vertices(g));
std::vector< size_type > ftime(num_vertices(g));
typedef iterator_property_map< std::vector< size_type >::iterator,
property_map< graph_t, vertex_index_t >::const_type >
time_pm_type;
time_pm_type dtime_pm(dtime.begin(), get(vertex_index, g));
time_pm_type ftime_pm(ftime.begin(), get(vertex_index, g));
size_type t = 0;
dfs_time_visitor< time_pm_type > vis(dtime_pm, ftime_pm, t);
depth_first_search(g, visitor(vis));
depth_first_search(g, visitor(vis));
// use std::sort to order the vertices by their discover time
std::vector < size_type > discover_order(N);
integer_range < size_type > r(0, N);
std::copy(r.begin(), r.end(), discover_order.begin());
std::sort(discover_order.begin(), discover_order.end(),
indirect_cmp < time_pm_type, std::less < size_type > >(dtime_pm));
std::cout << "order of discovery: ";
int i;
for (i = 0; i < N; ++i)
std::cout << name[discover_order[i]] << " ";
// use std::sort to order the vertices by their discover time
std::vector< size_type > discover_order(N);
integer_range< size_type > r(0, N);
std::copy(r.begin(), r.end(), discover_order.begin());
std::sort(discover_order.begin(), discover_order.end(),
indirect_cmp< time_pm_type, std::less< size_type > >(dtime_pm));
std::cout << "order of discovery: ";
int i;
for (i = 0; i < N; ++i)
std::cout << name[discover_order[i]] << " ";
std::vector < size_type > finish_order(N);
std::copy(r.begin(), r.end(), finish_order.begin());
std::sort(finish_order.begin(), finish_order.end(),
indirect_cmp < time_pm_type, std::less < size_type > >(ftime_pm));
std::cout << std::endl << "order of finish: ";
for (i = 0; i < N; ++i)
std::cout << name[finish_order[i]] << " ";
std::cout << std::endl;
std::vector< size_type > finish_order(N);
std::copy(r.begin(), r.end(), finish_order.begin());
std::sort(finish_order.begin(), finish_order.end(),
indirect_cmp< time_pm_type, std::less< size_type > >(ftime_pm));
std::cout << std::endl << "order of finish: ";
for (i = 0; i < N; ++i)
std::cout << name[finish_order[i]] << " ";
std::cout << std::endl;
return EXIT_SUCCESS;
return EXIT_SUCCESS;
}

View File

@@ -1,5 +1,5 @@
//=======================================================================
// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee,
// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee,
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
@@ -9,8 +9,8 @@
/*
IMPORTANT!!!
~~~~~~~~~~~~
This example uses interfaces that have been deprecated and removed from Boost.Grpah.
Someone needs to update it, as it does NOT compile.
This example uses interfaces that have been deprecated and removed from
Boost.Grpah. Someone needs to update it, as it does NOT compile.
*/
#include <boost/graph/graphviz.hpp>
@@ -20,36 +20,34 @@ char name[] = "abcdefghij";
struct parenthesis_visitor : public boost::default_dfs_visitor
{
template <class Vertex, class Graph> void
start_vertex(Vertex v, const Graph &)
{
std::cout << ' ';
}
template <class Vertex, class Graph> void
discover_vertex(Vertex v, const Graph &)
{
std::cout << "(" << name[v] << ' ';
}
template <class Vertex, class Graph> void
finish_vertex(Vertex v, const Graph &)
{
std::cout << ' ' << name[v] << ")";
}
template < class Vertex, class Graph >
void start_vertex(Vertex v, const Graph&)
{
std::cout << ' ';
}
template < class Vertex, class Graph >
void discover_vertex(Vertex v, const Graph&)
{
std::cout << "(" << name[v] << ' ';
}
template < class Vertex, class Graph >
void finish_vertex(Vertex v, const Graph&)
{
std::cout << ' ' << name[v] << ")";
}
};
int
main()
int main()
{
using namespace boost;
GraphvizGraph g;
read_graphviz("figs/dfs-example.dot", g);
graph_traits < GraphvizGraph >::edge_iterator e, e_end;
for (boost::tie(e, e_end) = edges(g); e != e_end; ++e)
std::cout << '(' << name[source(*e, g)] << ' '
<< name[target(*e, g)] << ')' << std::endl;
parenthesis_visitor
paren_vis;
depth_first_search(g, visitor(paren_vis));
std::cout << std::endl;
return 0;
using namespace boost;
GraphvizGraph g;
read_graphviz("figs/dfs-example.dot", g);
graph_traits< GraphvizGraph >::edge_iterator e, e_end;
for (boost::tie(e, e_end) = edges(g); e != e_end; ++e)
std::cout << '(' << name[source(*e, g)] << ' ' << name[target(*e, g)]
<< ')' << std::endl;
parenthesis_visitor paren_vis;
depth_first_search(g, visitor(paren_vis));
std::cout << std::endl;
return 0;
}

View File

@@ -14,7 +14,6 @@
#include <algorithm>
#include <utility>
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/depth_first_search.hpp>
#include <boost/graph/visitors.hpp>
@@ -50,76 +49,76 @@
using namespace boost;
using namespace std;
template < class VisitorList >
struct edge_categorizer : public dfs_visitor< VisitorList >
{
typedef dfs_visitor< VisitorList > Base;
template <class VisitorList>
struct edge_categorizer : public dfs_visitor<VisitorList> {
typedef dfs_visitor<VisitorList> Base;
edge_categorizer(const VisitorList& v = null_visitor()) : Base(v) {}
edge_categorizer(const VisitorList& v = null_visitor()) : Base(v) { }
template <class Edge, class Graph>
void tree_edge(Edge e, Graph& G) {
cout << "Tree edge: " << source(e, G) <<
" --> " << target(e, G) << endl;
Base::tree_edge(e, G);
}
template <class Edge, class Graph>
void back_edge(Edge e, Graph& G) {
cout << "Back edge: " << source(e, G)
<< " --> " << target(e, G) << endl;
Base::back_edge(e, G);
}
template <class Edge, class Graph>
void forward_or_cross_edge(Edge e, Graph& G) {
cout << "Forward or cross edge: " << source(e, G)
<< " --> " << target(e, G) << endl;
Base::forward_or_cross_edge(e, G);
}
template <class Edge, class Graph>
void finish_edge(Edge e, Graph& G) {
cout << "Finish edge: " << source(e, G) <<
" --> " << target(e, G) << endl;
Base::finish_edge(e, G);
}
template < class Edge, class Graph > void tree_edge(Edge e, Graph& G)
{
cout << "Tree edge: " << source(e, G) << " --> " << target(e, G)
<< endl;
Base::tree_edge(e, G);
}
template < class Edge, class Graph > void back_edge(Edge e, Graph& G)
{
cout << "Back edge: " << source(e, G) << " --> " << target(e, G)
<< endl;
Base::back_edge(e, G);
}
template < class Edge, class Graph >
void forward_or_cross_edge(Edge e, Graph& G)
{
cout << "Forward or cross edge: " << source(e, G) << " --> "
<< target(e, G) << endl;
Base::forward_or_cross_edge(e, G);
}
template < class Edge, class Graph > void finish_edge(Edge e, Graph& G)
{
cout << "Finish edge: " << source(e, G) << " --> " << target(e, G)
<< endl;
Base::finish_edge(e, G);
}
};
template <class VisitorList>
edge_categorizer<VisitorList>
categorize_edges(const VisitorList& v) {
return edge_categorizer<VisitorList>(v);
template < class VisitorList >
edge_categorizer< VisitorList > categorize_edges(const VisitorList& v)
{
return edge_categorizer< VisitorList >(v);
}
int
main(int , char* [])
int main(int, char*[])
{
using namespace boost;
typedef adjacency_list<> Graph;
Graph G(5);
add_edge(0, 2, G);
add_edge(1, 1, G);
add_edge(1, 3, G);
add_edge(2, 1, G);
add_edge(2, 3, G);
add_edge(3, 1, G);
add_edge(3, 4, G);
add_edge(4, 0, G);
add_edge(4, 1, G);
using namespace boost;
typedef graph_traits<Graph>::vertices_size_type size_type;
typedef adjacency_list<> Graph;
std::vector<size_type> d(num_vertices(G));
std::vector<size_type> f(num_vertices(G));
int t = 0;
depth_first_search(G, visitor(categorize_edges(
make_pair(stamp_times(&d[0], t, on_discover_vertex()),
stamp_times(&f[0], t, on_finish_vertex())))));
Graph G(5);
add_edge(0, 2, G);
add_edge(1, 1, G);
add_edge(1, 3, G);
add_edge(2, 1, G);
add_edge(2, 3, G);
add_edge(3, 1, G);
add_edge(3, 4, G);
add_edge(4, 0, G);
add_edge(4, 1, G);
std::vector<size_type>::iterator i, j;
for (i = d.begin(), j = f.begin(); i != d.end(); ++i, ++j)
cout << *i << " " << *j << endl;
typedef graph_traits< Graph >::vertices_size_type size_type;
return 0;
std::vector< size_type > d(num_vertices(G));
std::vector< size_type > f(num_vertices(G));
int t = 0;
depth_first_search(G,
visitor(categorize_edges(
make_pair(stamp_times(&d[0], t, on_discover_vertex()),
stamp_times(&f[0], t, on_finish_vertex())))));
std::vector< size_type >::iterator i, j;
for (i = d.begin(), j = f.begin(); i != d.end(); ++i, ++j)
cout << *i << " " << *j << endl;
return 0;
}

View File

@@ -1,2 +1,2 @@
order of discovery: u v y x w z
order of finish: x y v u z w
order of discovery: u v y x w z
order of finish: x y v u z w

View File

@@ -27,47 +27,43 @@
using namespace boost;
using namespace std;
struct open_paren : public base_visitor<open_paren> {
typedef on_discover_vertex event_filter;
template <class Vertex, class Graph>
void operator()(Vertex v, Graph&) {
std::cout << "(" << v;
}
struct open_paren : public base_visitor< open_paren >
{
typedef on_discover_vertex event_filter;
template < class Vertex, class Graph > void operator()(Vertex v, Graph&)
{
std::cout << "(" << v;
}
};
struct close_paren : public base_visitor<close_paren> {
typedef on_finish_vertex event_filter;
template <class Vertex, class Graph>
void operator()(Vertex v, Graph&) {
std::cout << v << ")";
}
struct close_paren : public base_visitor< close_paren >
{
typedef on_finish_vertex event_filter;
template < class Vertex, class Graph > void operator()(Vertex v, Graph&)
{
std::cout << v << ")";
}
};
int
main(int, char*[])
int main(int, char*[])
{
using namespace boost;
typedef adjacency_list<> Graph;
typedef std::pair<int,int> E;
E edge_array[] = { E(0, 2),
E(1, 1), E(1, 3),
E(2, 1), E(2, 3),
E(3, 1), E(3, 4),
E(4, 0), E(4, 1) };
using namespace boost;
typedef adjacency_list<> Graph;
typedef std::pair< int, int > E;
E edge_array[] = { E(0, 2), E(1, 1), E(1, 3), E(2, 1), E(2, 3), E(3, 1),
E(3, 4), E(4, 0), E(4, 1) };
#if defined(BOOST_MSVC) && BOOST_MSVC <= 1300
Graph G(5);
for (std::size_t j = 0; j < sizeof(edge_array) / sizeof(E); ++j)
add_edge(edge_array[j].first, edge_array[j].second, G);
Graph G(5);
for (std::size_t j = 0; j < sizeof(edge_array) / sizeof(E); ++j)
add_edge(edge_array[j].first, edge_array[j].second, G);
#else
Graph G(edge_array, edge_array + sizeof(edge_array)/sizeof(E), 5);
Graph G(edge_array, edge_array + sizeof(edge_array) / sizeof(E), 5);
#endif
std::cout << "DFS parenthesis:" << std::endl;
depth_first_search(G, visitor(make_dfs_visitor(std::make_pair(open_paren(),
close_paren()))));
std::cout << std::endl;
return 0;
std::cout << "DFS parenthesis:" << std::endl;
depth_first_search(G,
visitor(make_dfs_visitor(std::make_pair(open_paren(), close_paren()))));
std::cout << std::endl;
return 0;
}

View File

@@ -1,5 +1,5 @@
//=======================================================================
// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee,
// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee,
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
@@ -15,77 +15,89 @@
using namespace boost;
int
main(int, char *[])
int main(int, char*[])
{
typedef adjacency_list_traits<listS, listS,
directedS>::vertex_descriptor vertex_descriptor;
typedef adjacency_list < listS, listS, directedS,
property<vertex_index_t, int,
property<vertex_name_t, char,
property<vertex_distance_t, int,
property<vertex_predecessor_t, vertex_descriptor> > > >,
property<edge_weight_t, int> > graph_t;
typedef std::pair<int, int> Edge;
typedef adjacency_list_traits< listS, listS, directedS >::vertex_descriptor
vertex_descriptor;
typedef adjacency_list< listS, listS, directedS,
property< vertex_index_t, int,
property< vertex_name_t, char,
property< vertex_distance_t, int,
property< vertex_predecessor_t, vertex_descriptor > > > >,
property< edge_weight_t, int > >
graph_t;
typedef std::pair< int, int > Edge;
const int num_nodes = 5;
enum nodes { A, B, C, D, E };
Edge edge_array[] = { Edge(A, C), Edge(B, B), Edge(B, D), Edge(B, E),
Edge(C, B), Edge(C, D), Edge(D, E), Edge(E, A), Edge(E, B)
};
int weights[] = { 1, 2, 1, 2, 7, 3, 1, 1, 1 };
int num_arcs = sizeof(edge_array) / sizeof(Edge);
graph_traits<graph_t>::vertex_iterator i, iend;
const int num_nodes = 5;
enum nodes
{
A,
B,
C,
D,
E
};
Edge edge_array[] = { Edge(A, C), Edge(B, B), Edge(B, D), Edge(B, E),
Edge(C, B), Edge(C, D), Edge(D, E), Edge(E, A), Edge(E, B) };
int weights[] = { 1, 2, 1, 2, 7, 3, 1, 1, 1 };
int num_arcs = sizeof(edge_array) / sizeof(Edge);
graph_traits< graph_t >::vertex_iterator i, iend;
graph_t g(edge_array, edge_array + num_arcs, weights, num_nodes);
property_map<graph_t, edge_weight_t>::type weightmap = get(edge_weight, g);
graph_t g(edge_array, edge_array + num_arcs, weights, num_nodes);
property_map< graph_t, edge_weight_t >::type weightmap
= get(edge_weight, g);
// Manually intialize the vertex index and name maps
property_map<graph_t, vertex_index_t>::type indexmap = get(vertex_index, g);
property_map<graph_t, vertex_name_t>::type name = get(vertex_name, g);
int c = 0;
for (boost::tie(i, iend) = vertices(g); i != iend; ++i, ++c) {
indexmap[*i] = c;
name[*i] = 'A' + c;
}
// Manually intialize the vertex index and name maps
property_map< graph_t, vertex_index_t >::type indexmap
= get(vertex_index, g);
property_map< graph_t, vertex_name_t >::type name = get(vertex_name, g);
int c = 0;
for (boost::tie(i, iend) = vertices(g); i != iend; ++i, ++c)
{
indexmap[*i] = c;
name[*i] = 'A' + c;
}
vertex_descriptor s = vertex(A, g);
vertex_descriptor s = vertex(A, g);
property_map<graph_t, vertex_distance_t>::type
d = get(vertex_distance, g);
property_map<graph_t, vertex_predecessor_t>::type
p = get(vertex_predecessor, g);
dijkstra_shortest_paths(g, s, predecessor_map(p).distance_map(d));
property_map< graph_t, vertex_distance_t >::type d
= get(vertex_distance, g);
property_map< graph_t, vertex_predecessor_t >::type p
= get(vertex_predecessor, g);
dijkstra_shortest_paths(g, s, predecessor_map(p).distance_map(d));
std::cout << "distances and parents:" << std::endl;
graph_traits < graph_t >::vertex_iterator vi, vend;
for (boost::tie(vi, vend) = vertices(g); vi != vend; ++vi) {
std::cout << "distance(" << name[*vi] << ") = " << d[*vi] << ", ";
std::cout << "parent(" << name[*vi] << ") = " << name[p[*vi]] << std::
endl;
}
std::cout << std::endl;
std::cout << "distances and parents:" << std::endl;
graph_traits< graph_t >::vertex_iterator vi, vend;
for (boost::tie(vi, vend) = vertices(g); vi != vend; ++vi)
{
std::cout << "distance(" << name[*vi] << ") = " << d[*vi] << ", ";
std::cout << "parent(" << name[*vi] << ") = " << name[p[*vi]]
<< std::endl;
}
std::cout << std::endl;
std::ofstream dot_file("figs/dijkstra-eg.dot");
dot_file << "digraph D {\n"
<< " rankdir=LR\n"
<< " size=\"4,3\"\n"
<< " ratio=\"fill\"\n"
<< " edge[style=\"bold\"]\n" << " node[shape=\"circle\"]\n";
std::ofstream dot_file("figs/dijkstra-eg.dot");
dot_file << "digraph D {\n"
<< " rankdir=LR\n"
<< " size=\"4,3\"\n"
<< " ratio=\"fill\"\n"
<< " edge[style=\"bold\"]\n"
<< " node[shape=\"circle\"]\n";
graph_traits < graph_t >::edge_iterator ei, ei_end;
for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) {
graph_traits < graph_t >::edge_descriptor e = *ei;
graph_traits < graph_t >::vertex_descriptor
u = source(e, g), v = target(e, g);
dot_file << name[u] << " -> " << name[v]
<< "[label=\"" << get(weightmap, e) << "\"";
if (p[v] == u)
dot_file << ", color=\"black\"";
else
dot_file << ", color=\"grey\"";
dot_file << "]";
}
dot_file << "}";
return EXIT_SUCCESS;
graph_traits< graph_t >::edge_iterator ei, ei_end;
for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei)
{
graph_traits< graph_t >::edge_descriptor e = *ei;
graph_traits< graph_t >::vertex_descriptor u = source(e, g),
v = target(e, g);
dot_file << name[u] << " -> " << name[v] << "[label=\""
<< get(weightmap, e) << "\"";
if (p[v] == u)
dot_file << ", color=\"black\"";
else
dot_file << ", color=\"grey\"";
dot_file << "]";
}
dot_file << "}";
return EXIT_SUCCESS;
}

View File

@@ -1,5 +1,5 @@
//=======================================================================
// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee,
// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee,
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
@@ -16,62 +16,74 @@
using namespace boost;
int
main(int, char *[])
int main(int, char*[])
{
typedef adjacency_list < listS, vecS, directedS,
no_property, property < edge_weight_t, int > > graph_t;
typedef graph_traits < graph_t >::vertex_descriptor vertex_descriptor;
typedef std::pair<int, int> Edge;
typedef adjacency_list< listS, vecS, directedS, no_property,
property< edge_weight_t, int > >
graph_t;
typedef graph_traits< graph_t >::vertex_descriptor vertex_descriptor;
typedef std::pair< int, int > Edge;
const int num_nodes = 5;
enum nodes { A, B, C, D, E };
char name[] = "ABCDE";
Edge edge_array[] = { Edge(A, C), Edge(B, B), Edge(B, D), Edge(B, E),
Edge(C, B), Edge(C, D), Edge(D, E), Edge(E, A), Edge(E, B)
};
int weights[] = { 1, 2, 1, 2, 7, 3, 1, 1, 1 };
int num_arcs = sizeof(edge_array) / sizeof(Edge);
graph_t g(edge_array, edge_array + num_arcs, weights, num_nodes);
property_map<graph_t, edge_weight_t>::type weightmap = get(edge_weight, g);
std::vector<vertex_descriptor> p(num_vertices(g));
std::vector<int> d(num_vertices(g));
vertex_descriptor s = vertex(A, g);
const int num_nodes = 5;
enum nodes
{
A,
B,
C,
D,
E
};
char name[] = "ABCDE";
Edge edge_array[] = { Edge(A, C), Edge(B, B), Edge(B, D), Edge(B, E),
Edge(C, B), Edge(C, D), Edge(D, E), Edge(E, A), Edge(E, B) };
int weights[] = { 1, 2, 1, 2, 7, 3, 1, 1, 1 };
int num_arcs = sizeof(edge_array) / sizeof(Edge);
graph_t g(edge_array, edge_array + num_arcs, weights, num_nodes);
property_map< graph_t, edge_weight_t >::type weightmap
= get(edge_weight, g);
std::vector< vertex_descriptor > p(num_vertices(g));
std::vector< int > d(num_vertices(g));
vertex_descriptor s = vertex(A, g);
dijkstra_shortest_paths(g, s,
predecessor_map(boost::make_iterator_property_map(p.begin(), get(boost::vertex_index, g))).
distance_map(boost::make_iterator_property_map(d.begin(), get(boost::vertex_index, g))));
dijkstra_shortest_paths(g, s,
predecessor_map(boost::make_iterator_property_map(
p.begin(), get(boost::vertex_index, g)))
.distance_map(boost::make_iterator_property_map(
d.begin(), get(boost::vertex_index, g))));
std::cout << "distances and parents:" << std::endl;
graph_traits < graph_t >::vertex_iterator vi, vend;
for (boost::tie(vi, vend) = vertices(g); vi != vend; ++vi) {
std::cout << "distance(" << name[*vi] << ") = " << d[*vi] << ", ";
std::cout << "parent(" << name[*vi] << ") = " << name[p[*vi]] << std::
endl;
}
std::cout << std::endl;
std::cout << "distances and parents:" << std::endl;
graph_traits< graph_t >::vertex_iterator vi, vend;
for (boost::tie(vi, vend) = vertices(g); vi != vend; ++vi)
{
std::cout << "distance(" << name[*vi] << ") = " << d[*vi] << ", ";
std::cout << "parent(" << name[*vi] << ") = " << name[p[*vi]]
<< std::endl;
}
std::cout << std::endl;
std::ofstream dot_file("figs/dijkstra-eg.dot");
std::ofstream dot_file("figs/dijkstra-eg.dot");
dot_file << "digraph D {\n"
<< " rankdir=LR\n"
<< " size=\"4,3\"\n"
<< " ratio=\"fill\"\n"
<< " edge[style=\"bold\"]\n" << " node[shape=\"circle\"]\n";
dot_file << "digraph D {\n"
<< " rankdir=LR\n"
<< " size=\"4,3\"\n"
<< " ratio=\"fill\"\n"
<< " edge[style=\"bold\"]\n"
<< " node[shape=\"circle\"]\n";
graph_traits < graph_t >::edge_iterator ei, ei_end;
for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) {
graph_traits < graph_t >::edge_descriptor e = *ei;
graph_traits < graph_t >::vertex_descriptor
u = source(e, g), v = target(e, g);
dot_file << name[u] << " -> " << name[v]
<< "[label=\"" << get(weightmap, e) << "\"";
if (p[v] == u)
dot_file << ", color=\"black\"";
else
dot_file << ", color=\"grey\"";
dot_file << "]";
}
dot_file << "}";
return EXIT_SUCCESS;
graph_traits< graph_t >::edge_iterator ei, ei_end;
for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei)
{
graph_traits< graph_t >::edge_descriptor e = *ei;
graph_traits< graph_t >::vertex_descriptor u = source(e, g),
v = target(e, g);
dot_file << name[u] << " -> " << name[v] << "[label=\""
<< get(weightmap, e) << "\"";
if (p[v] == u)
dot_file << ", color=\"black\"";
else
dot_file << ", color=\"grey\"";
dot_file << "]";
}
dot_file << "}";
return EXIT_SUCCESS;
}

View File

@@ -1,7 +1,7 @@
//=======================================================================
// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee
// Copyright 2009 Trustees of Indiana University.
// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee,
// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee,
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
@@ -20,62 +20,74 @@
using namespace boost;
int
main(int, char *[])
int main(int, char*[])
{
typedef adjacency_list < listS, vecS, directedS,
no_property, property < edge_weight_t, int > > graph_t;
typedef graph_traits < graph_t >::vertex_descriptor vertex_descriptor;
typedef std::pair<int, int> Edge;
typedef adjacency_list< listS, vecS, directedS, no_property,
property< edge_weight_t, int > >
graph_t;
typedef graph_traits< graph_t >::vertex_descriptor vertex_descriptor;
typedef std::pair< int, int > Edge;
const int num_nodes = 5;
enum nodes { A, B, C, D, E };
char name[] = "ABCDE";
Edge edge_array[] = { Edge(A, C), Edge(B, B), Edge(B, D), Edge(B, E),
Edge(C, B), Edge(C, D), Edge(D, E), Edge(E, A), Edge(E, B)
};
int weights[] = { 1, 2, 1, 2, 7, 3, 1, 1, 1 };
int num_arcs = sizeof(edge_array) / sizeof(Edge);
graph_t g(edge_array, edge_array + num_arcs, weights, num_nodes);
property_map<graph_t, edge_weight_t>::type weightmap = get(edge_weight, g);
std::vector<vertex_descriptor> p(num_vertices(g));
std::vector<int> d(num_vertices(g));
vertex_descriptor s = vertex(A, g);
const int num_nodes = 5;
enum nodes
{
A,
B,
C,
D,
E
};
char name[] = "ABCDE";
Edge edge_array[] = { Edge(A, C), Edge(B, B), Edge(B, D), Edge(B, E),
Edge(C, B), Edge(C, D), Edge(D, E), Edge(E, A), Edge(E, B) };
int weights[] = { 1, 2, 1, 2, 7, 3, 1, 1, 1 };
int num_arcs = sizeof(edge_array) / sizeof(Edge);
graph_t g(edge_array, edge_array + num_arcs, weights, num_nodes);
property_map< graph_t, edge_weight_t >::type weightmap
= get(edge_weight, g);
std::vector< vertex_descriptor > p(num_vertices(g));
std::vector< int > d(num_vertices(g));
vertex_descriptor s = vertex(A, g);
dijkstra_shortest_paths_no_color_map(g, s,
predecessor_map(boost::make_iterator_property_map(p.begin(), get(boost::vertex_index, g))).
distance_map(boost::make_iterator_property_map(d.begin(), get(boost::vertex_index, g))));
dijkstra_shortest_paths_no_color_map(g, s,
predecessor_map(boost::make_iterator_property_map(
p.begin(), get(boost::vertex_index, g)))
.distance_map(boost::make_iterator_property_map(
d.begin(), get(boost::vertex_index, g))));
std::cout << "distances and parents:" << std::endl;
graph_traits < graph_t >::vertex_iterator vi, vend;
for (boost::tie(vi, vend) = vertices(g); vi != vend; ++vi) {
std::cout << "distance(" << name[*vi] << ") = " << d[*vi] << ", ";
std::cout << "parent(" << name[*vi] << ") = " << name[p[*vi]] << std::
endl;
}
std::cout << std::endl;
std::cout << "distances and parents:" << std::endl;
graph_traits< graph_t >::vertex_iterator vi, vend;
for (boost::tie(vi, vend) = vertices(g); vi != vend; ++vi)
{
std::cout << "distance(" << name[*vi] << ") = " << d[*vi] << ", ";
std::cout << "parent(" << name[*vi] << ") = " << name[p[*vi]]
<< std::endl;
}
std::cout << std::endl;
std::ofstream dot_file("figs/dijkstra-no-color-map-eg.dot");
std::ofstream dot_file("figs/dijkstra-no-color-map-eg.dot");
dot_file << "digraph D {\n"
<< " rankdir=LR\n"
<< " size=\"4,3\"\n"
<< " ratio=\"fill\"\n"
<< " edge[style=\"bold\"]\n" << " node[shape=\"circle\"]\n";
dot_file << "digraph D {\n"
<< " rankdir=LR\n"
<< " size=\"4,3\"\n"
<< " ratio=\"fill\"\n"
<< " edge[style=\"bold\"]\n"
<< " node[shape=\"circle\"]\n";
graph_traits < graph_t >::edge_iterator ei, ei_end;
for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) {
graph_traits < graph_t >::edge_descriptor e = *ei;
graph_traits < graph_t >::vertex_descriptor
u = source(e, g), v = target(e, g);
dot_file << name[u] << " -> " << name[v]
<< "[label=\"" << get(weightmap, e) << "\"";
if (p[v] == u)
dot_file << ", color=\"black\"";
else
dot_file << ", color=\"grey\"";
dot_file << "]";
}
dot_file << "}";
return EXIT_SUCCESS;
graph_traits< graph_t >::edge_iterator ei, ei_end;
for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei)
{
graph_traits< graph_t >::edge_descriptor e = *ei;
graph_traits< graph_t >::vertex_descriptor u = source(e, g),
v = target(e, g);
dot_file << name[u] << " -> " << name[v] << "[label=\""
<< get(weightmap, e) << "\"";
if (p[v] == u)
dot_file << ", color=\"black\"";
else
dot_file << ", color=\"grey\"";
dot_file << "]";
}
dot_file << "}";
return EXIT_SUCCESS;
}

View File

@@ -6,8 +6,8 @@ distance(3) = 4
distance(4) = 5
shortest paths tree
0 --> 2
1 -->
2 --> 3
3 --> 4
4 --> 1
0 --> 2
1 -->
2 --> 3
3 --> 4
4 --> 1

View File

@@ -9,18 +9,19 @@
#include <boost/graph/directed_graph.hpp> // A subclass to provide reasonable arguments to adjacency_list for a typical directed graph
int main(int,char*[])
int main(int, char*[])
{
// 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.
// 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;
boost::graph_traits<Graph>::vertex_descriptor v0 = g.add_vertex();
boost::graph_traits<Graph>::vertex_descriptor v1 = g.add_vertex();
typedef boost::directed_graph<> Graph;
Graph g;
boost::graph_traits< Graph >::vertex_descriptor v0 = g.add_vertex();
boost::graph_traits< Graph >::vertex_descriptor v1 = g.add_vertex();
g.add_edge(v0, v1);
g.add_edge(v0, v1);
return 0;
return 0;
}

View File

@@ -4,7 +4,6 @@
// Boost Software License, Version 1.0 (See accompanying file
// LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
//[eccentricity_example
#include <iostream>
#include <iomanip>
@@ -25,32 +24,31 @@ struct Actor
};
// Declare the graph type and its vertex and edge types.
typedef undirected_graph<Actor> Graph;
typedef graph_traits<Graph>::vertex_descriptor Vertex;
typedef graph_traits<Graph>::edge_descriptor Edge;
typedef undirected_graph< Actor > Graph;
typedef graph_traits< Graph >::vertex_descriptor Vertex;
typedef graph_traits< Graph >::edge_descriptor Edge;
// The name map provides an abstract accessor for the names of
// each vertex. This is used during graph creation.
typedef property_map<Graph, string Actor::*>::type NameMap;
typedef property_map< Graph, string Actor::* >::type NameMap;
// Declare a matrix type and its corresponding property map that
// will contain the distances between each pair of vertices.
typedef exterior_vertex_property<Graph, int> DistanceProperty;
typedef exterior_vertex_property< Graph, int > DistanceProperty;
typedef DistanceProperty::matrix_type DistanceMatrix;
typedef DistanceProperty::matrix_map_type DistanceMatrixMap;
// Declare the weight map so that each edge returns the same value.
typedef constant_property_map<Edge, int> WeightMap;
typedef constant_property_map< Edge, int > WeightMap;
// Declare a container and its corresponding property map that
// will contain the resulting eccentricities of each vertex in
// the graph.
typedef boost::exterior_vertex_property<Graph, int> EccentricityProperty;
typedef boost::exterior_vertex_property< Graph, int > EccentricityProperty;
typedef EccentricityProperty::container_type EccentricityContainer;
typedef EccentricityProperty::map_type EccentricityMap;
int
main(int argc, char *argv[])
int main(int argc, char* argv[])
{
// Create the graph and a name map that provides access to
// then actor names.
@@ -76,10 +74,11 @@ main(int argc, char *argv[])
boost::tie(r, d) = all_eccentricities(g, dm, em);
// Print the closeness centrality of each vertex.
graph_traits<Graph>::vertex_iterator i, end;
for(boost::tie(i, end) = vertices(g); i != end; ++i) {
cout << setw(12) << setiosflags(ios::left)
<< g[*i].name << get(em, *i) << endl;
graph_traits< Graph >::vertex_iterator i, end;
for (boost::tie(i, end) = vertices(g); i != end; ++i)
{
cout << setw(12) << setiosflags(ios::left) << g[*i].name << get(em, *i)
<< endl;
}
cout << "radius: " << r << endl;
cout << "diamter: " << d << endl;

View File

@@ -1,5 +1,5 @@
//=======================================================================
// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee,
// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee,
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
@@ -9,8 +9,8 @@
/*
IMPORTANT!!!
~~~~~~~~~~~~
This example uses interfaces that have been deprecated and removed from Boost.Grpah.
Someone needs to update it, as it does NOT compile.
This example uses interfaces that have been deprecated and removed from
Boost.Grpah. Someone needs to update it, as it does NOT compile.
*/
#include <boost/config.hpp>
@@ -23,86 +23,86 @@
namespace boost
{
template < typename Graph >
std::pair < typename graph_traits < Graph >::vertex_descriptor,
typename graph_traits < Graph >::degree_size_type >
min_degree_vertex(Graph & g)
{
typename graph_traits < Graph >::vertex_descriptor p;
typedef typename graph_traits < Graph >::degree_size_type size_type;
size_type delta = (std::numeric_limits < size_type >::max)();
typename graph_traits < Graph >::vertex_iterator i, iend;
template < typename Graph >
std::pair< typename graph_traits< Graph >::vertex_descriptor,
typename graph_traits< Graph >::degree_size_type >
min_degree_vertex(Graph& g)
{
typename graph_traits< Graph >::vertex_descriptor p;
typedef typename graph_traits< Graph >::degree_size_type size_type;
size_type delta = (std::numeric_limits< size_type >::max)();
typename graph_traits< Graph >::vertex_iterator i, iend;
for (boost::tie(i, iend) = vertices(g); i != iend; ++i)
if (degree(*i, g) < delta)
{
delta = degree(*i, g);
p = *i;
}
if (degree(*i, g) < delta)
{
delta = degree(*i, g);
p = *i;
}
return std::make_pair(p, delta);
}
}
template < typename Graph, typename OutputIterator >
void neighbors(const Graph & g,
typename graph_traits < Graph >::vertex_descriptor u,
OutputIterator result)
{
typename graph_traits < Graph >::adjacency_iterator ai, aend;
template < typename Graph, typename OutputIterator >
void neighbors(const Graph& g,
typename graph_traits< Graph >::vertex_descriptor u, OutputIterator result)
{
typename graph_traits< Graph >::adjacency_iterator ai, aend;
for (boost::tie(ai, aend) = adjacent_vertices(u, g); ai != aend; ++ai)
*result++ = *ai;
}
template < typename Graph, typename VertexIterator,
typename OutputIterator > void neighbors(const Graph & g,
VertexIterator first,
VertexIterator last,
OutputIterator result)
{
*result++ = *ai;
}
template < typename Graph, typename VertexIterator, typename OutputIterator >
void neighbors(const Graph& g, VertexIterator first, VertexIterator last,
OutputIterator result)
{
for (; first != last; ++first)
neighbors(g, *first, result);
}
neighbors(g, *first, result);
}
template < typename VertexListGraph, typename OutputIterator >
typename graph_traits < VertexListGraph >::degree_size_type
edge_connectivity(VertexListGraph & g, OutputIterator disconnecting_set)
{
typedef typename graph_traits <
VertexListGraph >::vertex_descriptor vertex_descriptor;
typedef typename graph_traits <
VertexListGraph >::degree_size_type degree_size_type;
typedef color_traits < default_color_type > Color;
typedef typename adjacency_list_traits < vecS, vecS,
directedS >::edge_descriptor edge_descriptor;
typedef adjacency_list < vecS, vecS, directedS, no_property,
property < edge_capacity_t, degree_size_type,
property < edge_residual_capacity_t, degree_size_type,
property < edge_reverse_t, edge_descriptor > > > > FlowGraph;
template < typename VertexListGraph, typename OutputIterator >
typename graph_traits< VertexListGraph >::degree_size_type edge_connectivity(
VertexListGraph& g, OutputIterator disconnecting_set)
{
typedef typename graph_traits< VertexListGraph >::vertex_descriptor
vertex_descriptor;
typedef typename graph_traits< VertexListGraph >::degree_size_type
degree_size_type;
typedef color_traits< default_color_type > Color;
typedef
typename adjacency_list_traits< vecS, vecS, directedS >::edge_descriptor
edge_descriptor;
typedef adjacency_list< vecS, vecS, directedS, no_property,
property< edge_capacity_t, degree_size_type,
property< edge_residual_capacity_t, degree_size_type,
property< edge_reverse_t, edge_descriptor > > > >
FlowGraph;
vertex_descriptor u, v, p, k;
edge_descriptor e1, e2;
bool inserted;
typename graph_traits < VertexListGraph >::vertex_iterator vi, vi_end;
typename graph_traits< VertexListGraph >::vertex_iterator vi, vi_end;
degree_size_type delta, alpha_star, alpha_S_k;
std::set < vertex_descriptor > S, neighbor_S;
std::vector < vertex_descriptor > S_star, nonneighbor_S;
std::vector < default_color_type > color(num_vertices(g));
std::vector < edge_descriptor > pred(num_vertices(g));
std::set< vertex_descriptor > S, neighbor_S;
std::vector< vertex_descriptor > S_star, nonneighbor_S;
std::vector< default_color_type > color(num_vertices(g));
std::vector< edge_descriptor > pred(num_vertices(g));
FlowGraph flow_g(num_vertices(g));
typename property_map < FlowGraph, edge_capacity_t >::type
cap = get(edge_capacity, flow_g);
typename property_map < FlowGraph, edge_residual_capacity_t >::type
res_cap = get(edge_residual_capacity, flow_g);
typename property_map < FlowGraph, edge_reverse_t >::type
rev_edge = get(edge_reverse, flow_g);
typename property_map< FlowGraph, edge_capacity_t >::type cap
= get(edge_capacity, flow_g);
typename property_map< FlowGraph, edge_residual_capacity_t >::type res_cap
= get(edge_residual_capacity, flow_g);
typename property_map< FlowGraph, edge_reverse_t >::type rev_edge
= get(edge_reverse, flow_g);
typename graph_traits < VertexListGraph >::edge_iterator ei, ei_end;
for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) {
u = source(*ei, g), v = target(*ei, g);
boost::tie(e1, inserted) = add_edge(u, v, flow_g);
cap[e1] = 1;
boost::tie(e2, inserted) = add_edge(v, u, flow_g);
cap[e2] = 1;
rev_edge[e1] = e2;
rev_edge[e2] = e1;
typename graph_traits< VertexListGraph >::edge_iterator ei, ei_end;
for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei)
{
u = source(*ei, g), v = target(*ei, g);
boost::tie(e1, inserted) = add_edge(u, v, flow_g);
cap[e1] = 1;
boost::tie(e2, inserted) = add_edge(v, u, flow_g);
cap[e2] = 1;
rev_edge[e1] = e2;
rev_edge[e2] = e1;
}
boost::tie(p, delta) = min_degree_vertex(g);
@@ -110,75 +110,77 @@ namespace boost
alpha_star = delta;
S.insert(p);
neighbor_S.insert(p);
neighbors(g, S.begin(), S.end(),
std::inserter(neighbor_S, neighbor_S.begin()));
neighbors(
g, S.begin(), S.end(), std::inserter(neighbor_S, neighbor_S.begin()));
std::set_difference(vertices(g).first, vertices(g).second,
neighbor_S.begin(), neighbor_S.end(),
std::back_inserter(nonneighbor_S));
neighbor_S.begin(), neighbor_S.end(),
std::back_inserter(nonneighbor_S));
while (!nonneighbor_S.empty()) {
k = nonneighbor_S.front();
alpha_S_k = edmonds_karp_max_flow
(flow_g, p, k, cap, res_cap, rev_edge, &color[0], &pred[0]);
if (alpha_S_k < alpha_star) {
alpha_star = alpha_S_k;
S_star.clear();
for (boost::tie(vi, vi_end) = vertices(flow_g); vi != vi_end; ++vi)
if (color[*vi] != Color::white())
S_star.push_back(*vi);
}
S.insert(k);
neighbor_S.insert(k);
neighbors(g, k, std::inserter(neighbor_S, neighbor_S.begin()));
nonneighbor_S.clear();
std::set_difference(vertices(g).first, vertices(g).second,
neighbor_S.begin(), neighbor_S.end(),
std::back_inserter(nonneighbor_S));
while (!nonneighbor_S.empty())
{
k = nonneighbor_S.front();
alpha_S_k = edmonds_karp_max_flow(
flow_g, p, k, cap, res_cap, rev_edge, &color[0], &pred[0]);
if (alpha_S_k < alpha_star)
{
alpha_star = alpha_S_k;
S_star.clear();
for (boost::tie(vi, vi_end) = vertices(flow_g); vi != vi_end; ++vi)
if (color[*vi] != Color::white())
S_star.push_back(*vi);
}
S.insert(k);
neighbor_S.insert(k);
neighbors(g, k, std::inserter(neighbor_S, neighbor_S.begin()));
nonneighbor_S.clear();
std::set_difference(vertices(g).first, vertices(g).second,
neighbor_S.begin(), neighbor_S.end(),
std::back_inserter(nonneighbor_S));
}
std::vector < bool > in_S_star(num_vertices(g), false);
typename std::vector < vertex_descriptor >::iterator si;
std::vector< bool > in_S_star(num_vertices(g), false);
typename std::vector< vertex_descriptor >::iterator si;
for (si = S_star.begin(); si != S_star.end(); ++si)
in_S_star[*si] = true;
in_S_star[*si] = true;
degree_size_type c = 0;
for (si = S_star.begin(); si != S_star.end(); ++si) {
typename graph_traits < VertexListGraph >::out_edge_iterator ei, ei_end;
for (boost::tie(ei, ei_end) = out_edges(*si, g); ei != ei_end; ++ei)
if (!in_S_star[target(*ei, g)]) {
*disconnecting_set++ = *ei;
++c;
}
for (si = S_star.begin(); si != S_star.end(); ++si)
{
typename graph_traits< VertexListGraph >::out_edge_iterator ei, ei_end;
for (boost::tie(ei, ei_end) = out_edges(*si, g); ei != ei_end; ++ei)
if (!in_S_star[target(*ei, g)])
{
*disconnecting_set++ = *ei;
++c;
}
}
return c;
}
}
}
int
main()
int main()
{
using namespace boost;
GraphvizGraph g;
read_graphviz("figs/edge-connectivity.dot", g);
using namespace boost;
GraphvizGraph g;
read_graphviz("figs/edge-connectivity.dot", g);
typedef graph_traits < GraphvizGraph >::edge_descriptor edge_descriptor;
typedef graph_traits < GraphvizGraph >::degree_size_type degree_size_type;
std::vector < edge_descriptor > disconnecting_set;
degree_size_type c =
edge_connectivity(g, std::back_inserter(disconnecting_set));
typedef graph_traits< GraphvizGraph >::edge_descriptor edge_descriptor;
typedef graph_traits< GraphvizGraph >::degree_size_type degree_size_type;
std::vector< edge_descriptor > disconnecting_set;
degree_size_type c
= edge_connectivity(g, std::back_inserter(disconnecting_set));
std::cout << "The edge connectivity is " << c << "." << std::endl;
std::cout << "The edge connectivity is " << c << "." << std::endl;
property_map < GraphvizGraph, vertex_attribute_t >::type
attr_map = get(vertex_attribute, g);
property_map< GraphvizGraph, vertex_attribute_t >::type attr_map
= get(vertex_attribute, g);
std::cout << "The disconnecting set is {";
for (std::vector < edge_descriptor >::iterator i =
disconnecting_set.begin(); i != disconnecting_set.end(); ++i)
std::
cout << "(" << attr_map[source(*i, g)]["label"] << "," <<
attr_map[target(*i, g)]["label"] << ") ";
std::cout << "}." << std::endl;
return EXIT_SUCCESS;
std::cout << "The disconnecting set is {";
for (std::vector< edge_descriptor >::iterator i = disconnecting_set.begin();
i != disconnecting_set.end(); ++i)
std::cout << "(" << attr_map[source(*i, g)]["label"] << ","
<< attr_map[target(*i, g)]["label"] << ") ";
std::cout << "}." << std::endl;
return EXIT_SUCCESS;
}

View File

@@ -1,5 +1,5 @@
//=======================================================================
// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee,
// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee,
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
@@ -13,127 +13,134 @@
using namespace boost;
template < typename Graph, typename VertexNamePropertyMap > void
read_graph_file(std::istream & graph_in, std::istream & name_in,
Graph & g, VertexNamePropertyMap name_map)
template < typename Graph, typename VertexNamePropertyMap >
void read_graph_file(std::istream& graph_in, std::istream& name_in, Graph& g,
VertexNamePropertyMap name_map)
{
typedef typename graph_traits < Graph >::vertices_size_type size_type;
size_type n_vertices;
typename graph_traits < Graph >::vertex_descriptor u;
typename property_traits < VertexNamePropertyMap >::value_type name;
typedef typename graph_traits< Graph >::vertices_size_type size_type;
size_type n_vertices;
typename graph_traits< Graph >::vertex_descriptor u;
typename property_traits< VertexNamePropertyMap >::value_type name;
graph_in >> n_vertices; // read in number of vertices
for (size_type i = 0; i < n_vertices; ++i) { // Add n vertices to the graph
u = add_vertex(g);
name_in >> name;
put(name_map, u, name); // ** Attach name property to vertex u **
}
size_type src, targ;
while (graph_in >> src) // Read in edges
if (graph_in >> targ)
add_edge(src, targ, g); // add an edge to the graph
else
break;
graph_in >> n_vertices; // read in number of vertices
for (size_type i = 0; i < n_vertices; ++i)
{ // Add n vertices to the graph
u = add_vertex(g);
name_in >> name;
put(name_map, u, name); // ** Attach name property to vertex u **
}
size_type src, targ;
while (graph_in >> src) // Read in edges
if (graph_in >> targ)
add_edge(src, targ, g); // add an edge to the graph
else
break;
}
template < typename Graph, typename VertexNameMap > void
output_adjacent_vertices(std::ostream & out,
typename graph_traits < Graph >::vertex_descriptor u,
const Graph & g, VertexNameMap name_map)
template < typename Graph, typename VertexNameMap >
void output_adjacent_vertices(std::ostream& out,
typename graph_traits< Graph >::vertex_descriptor u, const Graph& g,
VertexNameMap name_map)
{
typename graph_traits < Graph >::adjacency_iterator vi, vi_end;
out << get(name_map, u) << " -> { ";
for (boost::tie(vi, vi_end) = adjacent_vertices(u, g); vi != vi_end; ++vi)
out << get(name_map, *vi) << " ";
out << "}" << std::endl;
typename graph_traits< Graph >::adjacency_iterator vi, vi_end;
out << get(name_map, u) << " -> { ";
for (boost::tie(vi, vi_end) = adjacent_vertices(u, g); vi != vi_end; ++vi)
out << get(name_map, *vi) << " ";
out << "}" << std::endl;
}
template < typename NameMap > class name_equals_t {
template < typename NameMap > class name_equals_t
{
public:
name_equals_t(const std::string & n, NameMap map)
: m_name(n), m_name_map(map)
{
}
template < typename Vertex > bool operator()(Vertex u) const
{
return get(m_name_map, u) == m_name;
}
name_equals_t(const std::string& n, NameMap map)
: m_name(n), m_name_map(map)
{
}
template < typename Vertex > bool operator()(Vertex u) const
{
return get(m_name_map, u) == m_name;
}
private:
std::string m_name;
NameMap m_name_map;
NameMap m_name_map;
};
// object generator function
template < typename NameMap >
inline name_equals_t < NameMap >
name_equals(const std::string & str, NameMap name)
inline name_equals_t< NameMap > name_equals(
const std::string& str, NameMap name)
{
return name_equals_t < NameMap > (str, name);
return name_equals_t< NameMap >(str, name);
}
int
main(int argc, const char** argv)
int main(int argc, const char** argv)
{
typedef adjacency_list<listS,// Store out-edges of each vertex in a std::list
vecS, // Store vertex set in a std::vector
directedS, // The graph is directed
property < vertex_name_t, std::string > // Add a vertex property
>graph_type;
typedef adjacency_list< listS, // Store out-edges of each vertex in a
// std::list
vecS, // Store vertex set in a std::vector
directedS, // The graph is directed
property< vertex_name_t, std::string > // Add a vertex property
>
graph_type;
graph_type g; // use default constructor to create empty graph
const char* dep_file_name = argc >= 2 ? argv[1] : "makefile-dependencies.dat";
const char* target_file_name = argc >= 3 ? argv[2] : "makefile-target-names.dat";
graph_type g; // use default constructor to create empty graph
const char* dep_file_name
= argc >= 2 ? argv[1] : "makefile-dependencies.dat";
const char* target_file_name
= argc >= 3 ? argv[2] : "makefile-target-names.dat";
std::ifstream file_in(dep_file_name), name_in(target_file_name);
if (!file_in) {
std::cerr << "** Error: could not open file " << dep_file_name
<< std::endl;
return -1;
}
if (!name_in) {
std::cerr << "** Error: could not open file " << target_file_name
<< std::endl;
return -1;
}
std::ifstream file_in(dep_file_name), name_in(target_file_name);
if (!file_in)
{
std::cerr << "** Error: could not open file " << dep_file_name
<< std::endl;
return -1;
}
if (!name_in)
{
std::cerr << "** Error: could not open file " << target_file_name
<< std::endl;
return -1;
}
// Obtain internal property map from the graph
property_map < graph_type, vertex_name_t >::type name_map =
get(vertex_name, g);
read_graph_file(file_in, name_in, g, name_map);
// Obtain internal property map from the graph
property_map< graph_type, vertex_name_t >::type name_map
= get(vertex_name, g);
read_graph_file(file_in, name_in, g, name_map);
graph_traits < graph_type >::vertex_descriptor yow, zag, bar;
// Get vertex name property map from the graph
typedef property_map < graph_type, vertex_name_t >::type name_map_t;
name_map_t name = get(vertex_name, g);
// Get iterators for the vertex set
graph_traits < graph_type >::vertex_iterator i, end;
boost::tie(i, end) = vertices(g);
// Find yow.h
name_equals_t < name_map_t > predicate1("yow.h", name);
yow = *std::find_if(i, end, predicate1);
// Find zag.o
name_equals_t < name_map_t > predicate2("zag.o", name);
zag = *std::find_if(i, end, predicate2);
// Find bar.o
name_equals_t < name_map_t > predicate3("bar.o", name);
bar = *std::find_if(i, end, predicate3);
graph_traits< graph_type >::vertex_descriptor yow, zag, bar;
// Get vertex name property map from the graph
typedef property_map< graph_type, vertex_name_t >::type name_map_t;
name_map_t name = get(vertex_name, g);
// Get iterators for the vertex set
graph_traits< graph_type >::vertex_iterator i, end;
boost::tie(i, end) = vertices(g);
// Find yow.h
name_equals_t< name_map_t > predicate1("yow.h", name);
yow = *std::find_if(i, end, predicate1);
// Find zag.o
name_equals_t< name_map_t > predicate2("zag.o", name);
zag = *std::find_if(i, end, predicate2);
// Find bar.o
name_equals_t< name_map_t > predicate3("bar.o", name);
bar = *std::find_if(i, end, predicate3);
graph_traits < graph_type >::edge_descriptor e1, e2;
bool exists;
graph_traits< graph_type >::edge_descriptor e1, e2;
bool exists;
// Get the edge connecting yow.h to zag.o
boost::tie(e1, exists) = edge(yow, zag, g);
assert(exists == true);
assert(source(e1, g) == yow);
assert(target(e1, g) == zag);
// Get the edge connecting yow.h to zag.o
boost::tie(e1, exists) = edge(yow, zag, g);
assert(exists == true);
assert(source(e1, g) == yow);
assert(target(e1, g) == zag);
// Discover that there is no edge connecting zag.o to bar.o
boost::tie(e2, exists) = edge(zag, bar, g);
assert(exists == false);
// Discover that there is no edge connecting zag.o to bar.o
boost::tie(e2, exists) = edge(zag, bar, g);
assert(exists == false);
assert(num_vertices(g) == 15);
assert(num_edges(g) == 19);
assert(num_vertices(g) == 15);
assert(num_edges(g) == 19);
return EXIT_SUCCESS;
return EXIT_SUCCESS;
}

View File

@@ -1,5 +1,5 @@
//=======================================================================
// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee,
// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee,
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
@@ -13,38 +13,37 @@
using namespace boost;
template < typename T >
std::istream & operator >> (std::istream & in, std::pair < T, T > &p) {
in >> p.first >> p.second;
return in;
}
int
main(int argc, const char** argv)
std::istream& operator>>(std::istream& in, std::pair< T, T >& p)
{
typedef adjacency_list <
listS, // Store out-edges of each vertex in a std::list
vecS, // Store vertex set in a std::vector
directedS // The graph is directed
> graph_type;
std::ifstream file_in(argc >= 2 ? argv[1] : "makefile-dependencies.dat");
typedef graph_traits < graph_type >::vertices_size_type size_type;
size_type n_vertices;
file_in >> n_vertices; // read in number of vertices
graph_type
g(n_vertices); // create graph with n vertices
// Read in edges
graph_traits < graph_type >::vertices_size_type u, v;
while (file_in >> u)
if (file_in >> v)
add_edge(u, v, g);
else
break;
assert(num_vertices(g) == 15);
assert(num_edges(g) == 19);
return 0;
in >> p.first >> p.second;
return in;
}
int main(int argc, const char** argv)
{
typedef adjacency_list< listS, // Store out-edges of each vertex in a
// std::list
vecS, // Store vertex set in a std::vector
directedS // The graph is directed
>
graph_type;
std::ifstream file_in(argc >= 2 ? argv[1] : "makefile-dependencies.dat");
typedef graph_traits< graph_type >::vertices_size_type size_type;
size_type n_vertices;
file_in >> n_vertices; // read in number of vertices
graph_type g(n_vertices); // create graph with n vertices
// Read in edges
graph_traits< graph_type >::vertices_size_type u, v;
while (file_in >> u)
if (file_in >> v)
add_edge(u, v, g);
else
break;
assert(num_vertices(g) == 15);
assert(num_edges(g) == 19);
return 0;
}

View File

@@ -15,7 +15,6 @@
using namespace std;
using namespace boost;
/*
Edge Basics
@@ -23,7 +22,7 @@ using namespace boost;
There is not much to the Edge interface. Basically just two
functions to access the source and target vertex:
source(e)
target(e)
@@ -33,56 +32,52 @@ using namespace boost;
Sample output:
(0,1) (0,2) (0,3) (0,4) (2,0) (2,4) (3,0) (3,1)
(0,1) (0,2) (0,3) (0,4) (2,0) (2,4) (3,0) (3,1)
*/
template < class Graph > struct exercise_edge
{
exercise_edge(Graph& g) : G(g) {}
typedef typename boost::graph_traits< Graph >::edge_descriptor Edge;
typedef typename boost::graph_traits< Graph >::vertex_descriptor Vertex;
void operator()(Edge e) const
{
// begin
// Get the associated vertex type out of the edge using the
// edge_traits class
// Use the source() and target() functions to access the vertices
// that belong to Edge e
Vertex src = source(e, G);
Vertex targ = target(e, G);
template <class Graph>
struct exercise_edge {
exercise_edge(Graph& g) : G(g) {}
// print out the vertex id's just because
cout << "(" << src << "," << targ << ") ";
// end
}
typedef typename boost::graph_traits<Graph>::edge_descriptor Edge;
typedef typename boost::graph_traits<Graph>::vertex_descriptor Vertex;
void operator()(Edge e) const
{
//begin
// Get the associated vertex type out of the edge using the
// edge_traits class
// Use the source() and target() functions to access the vertices
// that belong to Edge e
Vertex src = source(e, G);
Vertex targ = target(e, G);
// print out the vertex id's just because
cout << "(" << src << "," << targ << ") ";
//end
}
Graph& G;
Graph& G;
};
int
main()
int main()
{
typedef adjacency_list<> MyGraph;
typedef adjacency_list<> MyGraph;
typedef pair<int,int> Pair;
Pair edge_array[8] = { Pair(0,1), Pair(0,2), Pair(0,3), Pair(0,4),
Pair(2,0), Pair(3,0), Pair(2,4), Pair(3,1) };
typedef pair< int, int > Pair;
Pair edge_array[8] = { Pair(0, 1), Pair(0, 2), Pair(0, 3), Pair(0, 4),
Pair(2, 0), Pair(3, 0), Pair(2, 4), Pair(3, 1) };
// Construct a graph using the edge_array (passing in pointers
// (iterators) to the beginning and end of the array), and
// specifying the number of vertices as 5
MyGraph G(5);
for (int i=0; i<8; ++i)
add_edge(edge_array[i].first, edge_array[i].second, G);
// Construct a graph using the edge_array (passing in pointers
// (iterators) to the beginning and end of the array), and
// specifying the number of vertices as 5
MyGraph G(5);
for (int i = 0; i < 8; ++i)
add_edge(edge_array[i].first, edge_array[i].second, G);
// Use the STL for_each algorithm to "exercise" all of the edges in
// the graph
for_each(edges(G).first, edges(G).second, exercise_edge<MyGraph>(G));
cout << endl;
return 0;
// Use the STL for_each algorithm to "exercise" all of the edges in
// the graph
for_each(edges(G).first, edges(G).second, exercise_edge< MyGraph >(G));
cout << endl;
return 0;
}

View File

@@ -1 +1 @@
(0,1) (0,2) (0,3) (0,4) (2,0) (2,4) (3,0) (3,1)
(0,1) (0,2) (0,3) (0,4) (2,0) (2,4) (3,0) (3,1)

View File

@@ -32,40 +32,44 @@
g-h: 0
*/
int main(int, char *[])
int main(int, char*[])
{
using namespace boost;
using namespace std;
typedef adjacency_list<vecS, vecS, undirectedS, no_property, size_t, no_property> Graph;
using namespace boost;
using namespace std;
typedef adjacency_list< vecS, vecS, undirectedS, no_property, size_t,
no_property >
Graph;
typedef std::pair<std::size_t, std::size_t> Pair;
Pair edges[14] = { Pair(0,3), //a-d
Pair(0,5), //a-f
Pair(1,2), //b-c
Pair(1,4), //b-e
Pair(1,6), //b-g
Pair(1,9), //b-j
Pair(2,3), //c-d
Pair(2,4), //c-e
Pair(3,5), //d-f
Pair(3,8), //d-i
Pair(4,6), //e-g
Pair(5,6), //f-g
Pair(5,7), //f-h
Pair(6,7) }; //g-h
typedef std::pair< std::size_t, std::size_t > Pair;
Pair edges[14] = { Pair(0, 3), // a-d
Pair(0, 5), // a-f
Pair(1, 2), // b-c
Pair(1, 4), // b-e
Pair(1, 6), // b-g
Pair(1, 9), // b-j
Pair(2, 3), // c-d
Pair(2, 4), // c-e
Pair(3, 5), // d-f
Pair(3, 8), // d-i
Pair(4, 6), // e-g
Pair(5, 6), // f-g
Pair(5, 7), // f-h
Pair(6, 7) }; // g-h
Graph G(10);
Graph G(10);
for (size_t i = 0; i < sizeof(edges)/sizeof(edges[0]); i++)
add_edge(edges[i].first, edges[i].second, G);
for (size_t i = 0; i < sizeof(edges) / sizeof(edges[0]); i++)
add_edge(edges[i].first, edges[i].second, G);
size_t colors = edge_coloring(G, get(edge_bundle, G));
size_t colors = edge_coloring(G, get(edge_bundle, G));
cout << "Colored using " << colors << " colors" << endl;
for (size_t i = 0; i < sizeof(edges)/sizeof(edges[0]); i++) {
cout << " " << (char)('a' + edges[i].first) << "-" << (char)('a' + edges[i].second) << ": " << G[edge(edges[i].first, edges[i].second, G).first] << endl;
}
cout << "Colored using " << colors << " colors" << endl;
for (size_t i = 0; i < sizeof(edges) / sizeof(edges[0]); i++)
{
cout << " " << (char)('a' + edges[i].first) << "-"
<< (char)('a' + edges[i].second) << ": "
<< G[edge(edges[i].first, edges[i].second, G).first] << endl;
}
return 0;
return 0;
}

View File

@@ -7,12 +7,11 @@
// http://www.boost.org/LICENSE_1_0.txt)
//=======================================================================
/*
IMPORTANT!!!
~~~~~~~~~~~~
This example uses interfaces that have been deprecated and removed from Boost.Grpah.
Someone needs to update it, as it does NOT compile.
This example uses interfaces that have been deprecated and removed from
Boost.Grpah. Someone needs to update it, as it does NOT compile.
*/
#include <boost/config.hpp>
@@ -25,40 +24,40 @@
using namespace boost;
int
main()
int main()
{
const int N = 8;
typedef adjacency_list<vecS, vecS, undirectedS> UndirectedGraph;
UndirectedGraph g(N);
const int N = 8;
typedef adjacency_list< vecS, vecS, undirectedS > UndirectedGraph;
UndirectedGraph g(N);
add_edge(0, 1, g);
add_edge(0, 2, g);
add_edge(0, 3, g);
add_edge(1, 2, g);
add_edge(1, 3, g);
add_edge(2, 3, g);
add_edge(3, 4, g);
add_edge(3, 7, g);
add_edge(4, 5, g);
add_edge(4, 6, g);
add_edge(4, 7, g);
add_edge(5, 6, g);
add_edge(5, 7, g);
add_edge(6, 7, g);
add_edge(0, 1, g);
add_edge(0, 2, g);
add_edge(0, 3, g);
add_edge(1, 2, g);
add_edge(1, 3, g);
add_edge(2, 3, g);
add_edge(3, 4, g);
add_edge(3, 7, g);
add_edge(4, 5, g);
add_edge(4, 6, g);
add_edge(4, 7, g);
add_edge(5, 6, g);
add_edge(5, 7, g);
add_edge(6, 7, g);
typedef graph_traits<UndirectedGraph>::edge_descriptor edge_descriptor;
typedef graph_traits<UndirectedGraph>::degree_size_type degree_size_type;
std::vector<edge_descriptor> disconnecting_set;
typedef graph_traits< UndirectedGraph >::edge_descriptor edge_descriptor;
typedef graph_traits< UndirectedGraph >::degree_size_type degree_size_type;
std::vector< edge_descriptor > disconnecting_set;
degree_size_type c = edge_connectivity(g, std::back_inserter(disconnecting_set));
degree_size_type c
= edge_connectivity(g, std::back_inserter(disconnecting_set));
std::cout << "The edge connectivity is " << c << "." << std::endl;
std::cout << "The disconnecting set is {";
std::cout << "The edge connectivity is " << c << "." << std::endl;
std::cout << "The disconnecting set is {";
std::copy(disconnecting_set.begin(), disconnecting_set.end(),
std::ostream_iterator<edge_descriptor>(std::cout, " "));
std::cout << "}." << std::endl;
return 0;
std::copy(disconnecting_set.begin(), disconnecting_set.end(),
std::ostream_iterator< edge_descriptor >(std::cout, " "));
std::cout << "}." << std::endl;
return 0;
}

View File

@@ -24,11 +24,11 @@
Sample output:
0 --> 1
1 --> 2 3 0
2 --> 4 1
3 --> 4 1
4 --> 2 3
0 --> 1
1 --> 2 3 0
2 --> 4 1
3 --> 4 1
4 --> 2 3
*/
@@ -41,79 +41,80 @@
#include <boost/graph/graph_utility.hpp>
#include <boost/graph/adjacency_list.hpp>
class edge_stream_iterator {
class edge_stream_iterator
{
public:
typedef std::input_iterator_tag iterator_category;
typedef std::pair<int,int> value_type;
typedef std::ptrdiff_t difference_type;
typedef const value_type* pointer;
typedef const value_type& reference;
typedef std::input_iterator_tag iterator_category;
typedef std::pair< int, int > value_type;
typedef std::ptrdiff_t difference_type;
typedef const value_type* pointer;
typedef const value_type& reference;
edge_stream_iterator() : m_stream(0), m_end_marker(false) {}
edge_stream_iterator(std::istream& s) : m_stream(&s) { m_read(); }
reference operator*() const { return m_edge; }
edge_stream_iterator& operator++() {
m_read();
return *this;
}
edge_stream_iterator operator++(int) {
edge_stream_iterator tmp = *this;
m_read();
return tmp;
}
protected:
std::istream* m_stream;
value_type m_edge;
bool m_end_marker;
void m_read() {
m_end_marker = (*m_stream) ? true : false;
if (m_end_marker) {
*m_stream >> m_edge.first >> m_edge.second;
edge_stream_iterator() : m_stream(0), m_end_marker(false) {}
edge_stream_iterator(std::istream& s) : m_stream(&s) { m_read(); }
reference operator*() const { return m_edge; }
edge_stream_iterator& operator++()
{
m_read();
return *this;
}
edge_stream_iterator operator++(int)
{
edge_stream_iterator tmp = *this;
m_read();
return tmp;
}
m_end_marker = (*m_stream) ? true : false;
}
friend bool operator==(const edge_stream_iterator& x,
const edge_stream_iterator& y);
protected:
std::istream* m_stream;
value_type m_edge;
bool m_end_marker;
void m_read()
{
m_end_marker = (*m_stream) ? true : false;
if (m_end_marker)
{
*m_stream >> m_edge.first >> m_edge.second;
}
m_end_marker = (*m_stream) ? true : false;
}
friend bool operator==(
const edge_stream_iterator& x, const edge_stream_iterator& y);
};
bool operator==(const edge_stream_iterator& x,
const edge_stream_iterator& y)
bool operator==(const edge_stream_iterator& x, const edge_stream_iterator& y)
{
return (x.m_stream == y.m_stream && x.m_end_marker == y.m_end_marker)
|| (x.m_end_marker == false && y.m_end_marker == false);
return (x.m_stream == y.m_stream && x.m_end_marker == y.m_end_marker)
|| (x.m_end_marker == false && y.m_end_marker == false);
}
bool operator!=(const edge_stream_iterator& x,
const edge_stream_iterator& y)
bool operator!=(const edge_stream_iterator& x, const edge_stream_iterator& y)
{
return !(x == y);
return !(x == y);
}
int
main(int argc, const char** argv)
int main(int argc, const char** argv)
{
typedef boost::adjacency_list<> IteratorConstructibleGraph;
typedef boost::graph_traits<IteratorConstructibleGraph> Traits;
Traits::vertices_size_type size_V;
Traits::edges_size_type size_E;
typedef boost::adjacency_list<> IteratorConstructibleGraph;
typedef boost::graph_traits< IteratorConstructibleGraph > Traits;
Traits::vertices_size_type size_V;
Traits::edges_size_type size_E;
std::ifstream f(argc >= 2 ? argv[1] : "edge_iterator_constructor.dat");
f >> size_V >> size_E;
std::ifstream f(argc >= 2 ? argv[1] : "edge_iterator_constructor.dat");
f >> size_V >> size_E;
edge_stream_iterator edge_iter(f), end;
edge_stream_iterator edge_iter(f), end;
#if defined(BOOST_MSVC) && BOOST_MSVC <= 1300
// VC++ can't handle the iterator constructor
IteratorConstructibleGraph G(size_V);
while (edge_iter != end) {
int i, j;
boost::tie(i, j) = *edge_iter++;
boost::add_edge(i, j, G);
}
// VC++ can't handle the iterator constructor
IteratorConstructibleGraph G(size_V);
while (edge_iter != end)
{
int i, j;
boost::tie(i, j) = *edge_iter++;
boost::add_edge(i, j, G);
}
#else
IteratorConstructibleGraph G(edge_iter, end, size_V);
IteratorConstructibleGraph G(edge_iter, end, size_V);
#endif
boost::print_graph(G);
boost::print_graph(G);
return 0;
return 0;
}

View File

@@ -9,45 +9,45 @@
//
// Sample output:
//
// 0 --(8, 10)--> 1
// 0 --(8, 10)--> 1
//
// 1 --(12, 20)--> 4 --(12, 40)--> 3
// <--(8,10)-- 0 <--(16,20)-- 2
// 2 --(16, 20)--> 1
// <--(16,20)-- 5
// 3 --(12, 40)--> 6
// <--(12,40)-- 1
// 4 --(12, 20)--> 7
// <--(12,20)-- 1
// 5 --(16, 20)--> 2
// <--(16,20)-- 6
// 6 --(16, 20)--> 5 --(8, 10)--> 8
// <--(12,20)-- 7 <--(12,40)-- 3
// 7 --(12, 20)--> 6
// <--(12,20)-- 4
// 8
// <--(8,10)-- 6
// 1 --(12, 20)--> 4 --(12, 40)--> 3
// <--(8,10)-- 0 <--(16,20)-- 2
// 2 --(16, 20)--> 1
// <--(16,20)-- 5
// 3 --(12, 40)--> 6
// <--(12,40)-- 1
// 4 --(12, 20)--> 7
// <--(12,20)-- 1
// 5 --(16, 20)--> 2
// <--(16,20)-- 6
// 6 --(16, 20)--> 5 --(8, 10)--> 8
// <--(12,20)-- 7 <--(12,40)-- 3
// 7 --(12, 20)--> 6
// <--(12,20)-- 4
// 8
// <--(8,10)-- 6
//
//
// 0 --(8, 1)--> 1
// 0 --(8, 1)--> 1
//
// 1 --(12, 2)--> 4 --(12, 3)--> 3
// <--(8,1)-- 0 <--(16,4)-- 2
// 2 --(16, 4)--> 1
// <--(16,7)-- 5
// 3 --(12, 5)--> 6
// <--(12,3)-- 1
// 4 --(12, 6)--> 7
// <--(12,2)-- 1
// 5 --(16, 7)--> 2
// <--(16,8)-- 6
// 6 --(16, 8)--> 5
// <--(12,10)-- 7 <--(12,5)-- 3
// 7 --(12, 10)--> 6
// <--(12,6)-- 4
// 8
// 1 --(12, 2)--> 4 --(12, 3)--> 3
// <--(8,1)-- 0 <--(16,4)-- 2
// 2 --(16, 4)--> 1
// <--(16,7)-- 5
// 3 --(12, 5)--> 6
// <--(12,3)-- 1
// 4 --(12, 6)--> 7
// <--(12,2)-- 1
// 5 --(16, 7)--> 2
// <--(16,8)-- 6
// 6 --(16, 8)--> 5
// <--(12,10)-- 7 <--(12,5)-- 3
// 7 --(12, 10)--> 6
// <--(12,6)-- 4
// 8
//
#include <boost/config.hpp>
#include <iostream>
@@ -55,109 +55,111 @@
#include <boost/property_map/property_map.hpp>
#include <boost/graph/adjacency_list.hpp>
using namespace boost;
using namespace std;
enum edge_myflow_t { edge_myflow };
enum edge_mycapacity_t { edge_mycapacity };
namespace boost {
BOOST_INSTALL_PROPERTY(edge, myflow);
BOOST_INSTALL_PROPERTY(edge, mycapacity);
}
template <class Graph>
void print_network(const Graph& G)
enum edge_myflow_t
{
typedef typename boost::graph_traits<Graph>::vertex_iterator Viter;
typedef typename boost::graph_traits<Graph>::out_edge_iterator OutEdgeIter;
typedef typename boost::graph_traits<Graph>::in_edge_iterator InEdgeIter;
typename property_map<Graph, edge_mycapacity_t>::const_type
capacity = get(edge_mycapacity, G);
typename property_map<Graph, edge_myflow_t>::const_type
flow = get(edge_myflow, G);
Viter ui, uiend;
boost::tie(ui, uiend) = vertices(G);
for (; ui != uiend; ++ui) {
OutEdgeIter out, out_end;
cout << *ui << "\t";
boost::tie(out, out_end) = out_edges(*ui, G);
for(; out != out_end; ++out)
cout << "--(" << capacity[*out] << ", " << flow[*out] << ")--> "
<< target(*out,G) << "\t";
InEdgeIter in, in_end;
cout << endl << "\t";
boost::tie(in, in_end) = in_edges(*ui, G);
for(; in != in_end; ++in)
cout << "<--(" << capacity[*in] << "," << flow[*in] << ")-- "
<< source(*in,G) << "\t";
cout << endl;
}
}
int main(int , char* [])
edge_myflow
};
enum edge_mycapacity_t
{
typedef property<edge_mycapacity_t, int> Cap;
typedef property<edge_myflow_t, int, Cap> Flow;
typedef adjacency_list<vecS, vecS, bidirectionalS,
no_property, Flow> Graph;
edge_mycapacity
};
const int num_vertices = 9;
Graph G(num_vertices);
/* 2<----5
/ ^
/ \
V \
0 ---->1---->3----->6--->8
\ ^
\ /
V /
4----->7
*/
add_edge(0, 1, Flow(10, Cap(8)), G);
add_edge(1, 4, Flow(20, Cap(12)), G);
add_edge(4, 7, Flow(20, Cap(12)), G);
add_edge(7, 6, Flow(20, Cap(12)), G);
add_edge(1, 3, Flow(40, Cap(12)), G);
add_edge(3, 6, Flow(40, Cap(12)), G);
add_edge(6, 5, Flow(20, Cap(16)), G);
add_edge(5, 2, Flow(20, Cap(16)), G);
add_edge(2, 1, Flow(20, Cap(16)), G);
add_edge(6, 8, Flow(10, Cap(8)), G);
print_network(G);
property_map<Graph, edge_myflow_t>::type
flow = get(edge_myflow, G);
boost::graph_traits<Graph>::vertex_iterator v, v_end;
boost::graph_traits<Graph>::out_edge_iterator e, e_end;
int f = 0;
for (boost::tie(v, v_end) = vertices(G); v != v_end; ++v)
for (boost::tie(e, e_end) = out_edges(*v, G); e != e_end; ++e)
flow[*e] = ++f;
cout << endl << endl;
remove_edge(6, 8, G);
print_network(G);
return 0;
namespace boost
{
BOOST_INSTALL_PROPERTY(edge, myflow);
BOOST_INSTALL_PROPERTY(edge, mycapacity);
}
template < class Graph > void print_network(const Graph& G)
{
typedef typename boost::graph_traits< Graph >::vertex_iterator Viter;
typedef
typename boost::graph_traits< Graph >::out_edge_iterator OutEdgeIter;
typedef typename boost::graph_traits< Graph >::in_edge_iterator InEdgeIter;
typename property_map< Graph, edge_mycapacity_t >::const_type capacity
= get(edge_mycapacity, G);
typename property_map< Graph, edge_myflow_t >::const_type flow
= get(edge_myflow, G);
Viter ui, uiend;
boost::tie(ui, uiend) = vertices(G);
for (; ui != uiend; ++ui)
{
OutEdgeIter out, out_end;
cout << *ui << "\t";
boost::tie(out, out_end) = out_edges(*ui, G);
for (; out != out_end; ++out)
cout << "--(" << capacity[*out] << ", " << flow[*out] << ")--> "
<< target(*out, G) << "\t";
InEdgeIter in, in_end;
cout << endl << "\t";
boost::tie(in, in_end) = in_edges(*ui, G);
for (; in != in_end; ++in)
cout << "<--(" << capacity[*in] << "," << flow[*in] << ")-- "
<< source(*in, G) << "\t";
cout << endl;
}
}
int main(int, char*[])
{
typedef property< edge_mycapacity_t, int > Cap;
typedef property< edge_myflow_t, int, Cap > Flow;
typedef adjacency_list< vecS, vecS, bidirectionalS, no_property, Flow >
Graph;
const int num_vertices = 9;
Graph G(num_vertices);
/* 2<----5
/ ^
/ \
V \
0 ---->1---->3----->6--->8
\ ^
\ /
V /
4----->7
*/
add_edge(0, 1, Flow(10, Cap(8)), G);
add_edge(1, 4, Flow(20, Cap(12)), G);
add_edge(4, 7, Flow(20, Cap(12)), G);
add_edge(7, 6, Flow(20, Cap(12)), G);
add_edge(1, 3, Flow(40, Cap(12)), G);
add_edge(3, 6, Flow(40, Cap(12)), G);
add_edge(6, 5, Flow(20, Cap(16)), G);
add_edge(5, 2, Flow(20, Cap(16)), G);
add_edge(2, 1, Flow(20, Cap(16)), G);
add_edge(6, 8, Flow(10, Cap(8)), G);
print_network(G);
property_map< Graph, edge_myflow_t >::type flow = get(edge_myflow, G);
boost::graph_traits< Graph >::vertex_iterator v, v_end;
boost::graph_traits< Graph >::out_edge_iterator e, e_end;
int f = 0;
for (boost::tie(v, v_end) = vertices(G); v != v_end; ++v)
for (boost::tie(e, e_end) = out_edges(*v, G); e != e_end; ++e)
flow[*e] = ++f;
cout << endl << endl;
remove_edge(6, 8, G);
print_network(G);
return 0;
}

View File

@@ -1,38 +1,38 @@
0 --(8, 10)--> 1
1 --(12, 20)--> 4 --(12, 40)--> 3
<--(8,10)-- 0 <--(16,20)-- 2
2 --(16, 20)--> 1
<--(16,20)-- 5
3 --(12, 40)--> 6
<--(12,40)-- 1
4 --(12, 20)--> 7
<--(12,20)-- 1
5 --(16, 20)--> 2
<--(16,20)-- 6
6 --(16, 20)--> 5 --(8, 10)--> 8
<--(12,20)-- 7 <--(12,40)-- 3
7 --(12, 20)--> 6
<--(12,20)-- 4
8
<--(8,10)-- 6
0 --(8, 10)--> 1
1 --(12, 20)--> 4 --(12, 40)--> 3
<--(8,10)-- 0 <--(16,20)-- 2
2 --(16, 20)--> 1
<--(16,20)-- 5
3 --(12, 40)--> 6
<--(12,40)-- 1
4 --(12, 20)--> 7
<--(12,20)-- 1
5 --(16, 20)--> 2
<--(16,20)-- 6
6 --(16, 20)--> 5 --(8, 10)--> 8
<--(12,20)-- 7 <--(12,40)-- 3
7 --(12, 20)--> 6
<--(12,20)-- 4
8
<--(8,10)-- 6
0 --(8, 1)--> 1
1 --(12, 2)--> 4 --(12, 3)--> 3
<--(8,1)-- 0 <--(16,4)-- 2
2 --(16, 4)--> 1
<--(16,7)-- 5
3 --(12, 5)--> 6
<--(12,3)-- 1
4 --(12, 6)--> 7
<--(12,2)-- 1
5 --(16, 7)--> 2
<--(16,8)-- 6
6 --(16, 8)--> 5
<--(12,10)-- 7 <--(12,5)-- 3
7 --(12, 10)--> 6
<--(12,6)-- 4
8
0 --(8, 1)--> 1
1 --(12, 2)--> 4 --(12, 3)--> 3
<--(8,1)-- 0 <--(16,4)-- 2
2 --(16, 4)--> 1
<--(16,7)-- 5
3 --(12, 5)--> 6
<--(12,3)-- 1
4 --(12, 6)--> 7
<--(12,2)-- 1
5 --(16, 7)--> 2
<--(16,8)-- 6
6 --(16, 8)--> 5
<--(12,10)-- 7 <--(12,5)-- 3
7 --(12, 10)--> 6
<--(12,6)-- 4
8

View File

@@ -1,5 +1,5 @@
//=======================================================================
// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee,
// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee,
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
@@ -47,49 +47,50 @@
// f 7 6 0
// f 7 5 0
int
main()
int main()
{
using namespace boost;
using namespace boost;
typedef adjacency_list_traits < vecS, vecS, directedS > Traits;
typedef adjacency_list < listS, vecS, directedS,
property < vertex_name_t, std::string >,
property < edge_capacity_t, long,
property < edge_residual_capacity_t, long,
property < edge_reverse_t, Traits::edge_descriptor > > > > Graph;
typedef adjacency_list_traits< vecS, vecS, directedS > Traits;
typedef adjacency_list< listS, vecS, directedS,
property< vertex_name_t, std::string >,
property< edge_capacity_t, long,
property< edge_residual_capacity_t, long,
property< edge_reverse_t, Traits::edge_descriptor > > > >
Graph;
Graph g;
Graph g;
property_map < Graph, edge_capacity_t >::type
capacity = get(edge_capacity, g);
property_map < Graph, edge_reverse_t >::type rev = get(edge_reverse, g);
property_map < Graph, edge_residual_capacity_t >::type
residual_capacity = get(edge_residual_capacity, g);
property_map< Graph, edge_capacity_t >::type capacity
= get(edge_capacity, g);
property_map< Graph, edge_reverse_t >::type rev = get(edge_reverse, g);
property_map< Graph, edge_residual_capacity_t >::type residual_capacity
= get(edge_residual_capacity, g);
Traits::vertex_descriptor s, t;
read_dimacs_max_flow(g, capacity, rev, s, t);
Traits::vertex_descriptor s, t;
read_dimacs_max_flow(g, capacity, rev, s, t);
#if defined(BOOST_MSVC) && BOOST_MSVC <= 1300
std::vector<default_color_type> color(num_vertices(g));
std::vector<Traits::edge_descriptor> pred(num_vertices(g));
long flow = edmonds_karp_max_flow
(g, s, t, capacity, residual_capacity, rev, &color[0], &pred[0]);
std::vector< default_color_type > color(num_vertices(g));
std::vector< Traits::edge_descriptor > pred(num_vertices(g));
long flow = edmonds_karp_max_flow(
g, s, t, capacity, residual_capacity, rev, &color[0], &pred[0]);
#else
long flow = edmonds_karp_max_flow(g, s, t);
long flow = edmonds_karp_max_flow(g, s, t);
#endif
std::cout << "c The total flow:" << std::endl;
std::cout << "s " << flow << std::endl << std::endl;
std::cout << "c The total flow:" << std::endl;
std::cout << "s " << flow << std::endl << std::endl;
std::cout << "c flow values:" << std::endl;
graph_traits < Graph >::vertex_iterator u_iter, u_end;
graph_traits < Graph >::out_edge_iterator ei, e_end;
for (boost::tie(u_iter, u_end) = vertices(g); u_iter != u_end; ++u_iter)
for (boost::tie(ei, e_end) = out_edges(*u_iter, g); ei != e_end; ++ei)
if (capacity[*ei] > 0)
std::cout << "f " << *u_iter << " " << target(*ei, g) << " "
<< (capacity[*ei] - residual_capacity[*ei]) << std::endl;
std::cout << "c flow values:" << std::endl;
graph_traits< Graph >::vertex_iterator u_iter, u_end;
graph_traits< Graph >::out_edge_iterator ei, e_end;
for (boost::tie(u_iter, u_end) = vertices(g); u_iter != u_end; ++u_iter)
for (boost::tie(ei, e_end) = out_edges(*u_iter, g); ei != e_end; ++ei)
if (capacity[*ei] > 0)
std::cout << "f " << *u_iter << " " << target(*ei, g) << " "
<< (capacity[*ei] - residual_capacity[*ei])
<< std::endl;
return EXIT_SUCCESS;
return EXIT_SUCCESS;
}

View File

@@ -13,103 +13,111 @@
//
// Sample output:
//
// 0 --(10, 8)--> 1
// 0 --(10, 8)--> 1
//
// 1 --(20, 12)--> 4 --(40, 12)--> 3
// <--(10,8)-- 0 <--(20,16)-- 2
// 2 --(20, 16)--> 1
// <--(20,16)-- 5
// 3 --(40, 12)--> 6
// <--(40,12)-- 1
// 4 --(20, 12)--> 7
// <--(20,12)-- 1
// 5 --(20, 16)--> 2
// <--(20,16)-- 6
// 6 --(20, 16)--> 5 --(10, 8)--> 8
// <--(20,12)-- 7 <--(40,12)-- 3
// 7 --(20, 12)--> 6
// <--(20,12)-- 4
// 8
// <--(10,8)-- 6
// 1 --(20, 12)--> 4 --(40, 12)--> 3
// <--(10,8)-- 0 <--(20,16)-- 2
// 2 --(20, 16)--> 1
// <--(20,16)-- 5
// 3 --(40, 12)--> 6
// <--(40,12)-- 1
// 4 --(20, 12)--> 7
// <--(20,12)-- 1
// 5 --(20, 16)--> 2
// <--(20,16)-- 6
// 6 --(20, 16)--> 5 --(10, 8)--> 8
// <--(20,12)-- 7 <--(40,12)-- 3
// 7 --(20, 12)--> 6
// <--(20,12)-- 4
// 8
// <--(10,8)-- 6
#include <boost/config.hpp>
#include <iostream>
#include <boost/graph/adjacency_list.hpp>
#include <boost/property_map/property_map.hpp>
template <class Graph, class Capacity, class Flow>
template < class Graph, class Capacity, class Flow >
void print_network(Graph& G, Capacity capacity, Flow flow)
{
typedef typename boost::graph_traits<Graph>::vertex_iterator Viter;
typedef typename boost::graph_traits<Graph>::out_edge_iterator OutEdgeIter;
typedef typename boost::graph_traits<Graph>::in_edge_iterator InEdgeIter;
typedef typename boost::graph_traits< Graph >::vertex_iterator Viter;
typedef
typename boost::graph_traits< Graph >::out_edge_iterator OutEdgeIter;
typedef typename boost::graph_traits< Graph >::in_edge_iterator InEdgeIter;
Viter ui, uiend;
for (boost::tie(ui, uiend) = boost::vertices(G); ui != uiend; ++ui) {
OutEdgeIter out, out_end;
std::cout << *ui << "\t";
Viter ui, uiend;
for (boost::tie(ui, uiend) = boost::vertices(G); ui != uiend; ++ui)
{
OutEdgeIter out, out_end;
std::cout << *ui << "\t";
for(boost::tie(out, out_end) = boost::out_edges(*ui, G); out != out_end; ++out)
std::cout << "--(" << boost::get(capacity, *out) << ", "
<< boost::get(flow, *out) << ")--> " << boost::target(*out,G) << "\t";
std::cout << std::endl << "\t";
for (boost::tie(out, out_end) = boost::out_edges(*ui, G);
out != out_end; ++out)
std::cout << "--(" << boost::get(capacity, *out) << ", "
<< boost::get(flow, *out) << ")--> "
<< boost::target(*out, G) << "\t";
std::cout << std::endl << "\t";
InEdgeIter in, in_end;
for(boost::tie(in, in_end) = boost::in_edges(*ui, G); in != in_end; ++in)
std::cout << "<--(" << boost::get(capacity, *in) << "," << boost::get(flow, *in) << ")-- "
<< boost::source(*in, G) << "\t";
std::cout << std::endl;
}
InEdgeIter in, in_end;
for (boost::tie(in, in_end) = boost::in_edges(*ui, G); in != in_end;
++in)
std::cout << "<--(" << boost::get(capacity, *in) << ","
<< boost::get(flow, *in) << ")-- "
<< boost::source(*in, G) << "\t";
std::cout << std::endl;
}
}
int main(int, char*[])
{
int main(int , char* []) {
typedef boost::adjacency_list< boost::vecS, boost::vecS,
boost::bidirectionalS, boost::no_property,
boost::property< boost::edge_index_t, std::size_t > >
Graph;
typedef boost::adjacency_list<boost::vecS, boost::vecS,
boost::bidirectionalS, boost::no_property,
boost::property<boost::edge_index_t, std::size_t> > Graph;
const int num_vertices = 9;
Graph G(num_vertices);
const int num_vertices = 9;
Graph G(num_vertices);
/* 2<----5
/ ^
/ \
V \
0 ---->1---->3----->6--->8
\ ^
\ /
V /
4----->7
*/
/* 2<----5
/ ^
/ \
V \
0 ---->1---->3----->6--->8
\ ^
\ /
V /
4----->7
*/
int capacity[] = { 10, 20, 20, 20, 40, 40, 20, 20, 20, 10 };
int flow[] = { 8, 12, 12, 12, 12, 12, 16, 16, 16, 8 };
int capacity[] = { 10, 20, 20, 20, 40, 40, 20, 20, 20, 10 };
int flow[] = { 8, 12, 12, 12, 12, 12, 16, 16, 16, 8 };
// insert edges into the graph, and assign each edge an ID number
// to index into the property arrays
boost::add_edge(0, 1, 0, G);
// insert edges into the graph, and assign each edge an ID number
// to index into the property arrays
boost::add_edge(0, 1, 0, G);
boost::add_edge(1, 4, 1, G);
boost::add_edge(4, 7, 2, G);
boost::add_edge(7, 6, 3, G);
boost::add_edge(1, 4, 1, G);
boost::add_edge(4, 7, 2, G);
boost::add_edge(7, 6, 3, G);
boost::add_edge(1, 3, 4, G);
boost::add_edge(3, 6, 5, G);
boost::add_edge(1, 3, 4, G);
boost::add_edge(3, 6, 5, G);
boost::add_edge(6, 5, 6, G);
boost::add_edge(5, 2, 7, G);
boost::add_edge(2, 1, 8, G);
boost::add_edge(6, 5, 6, G);
boost::add_edge(5, 2, 7, G);
boost::add_edge(2, 1, 8, G);
boost::add_edge(6, 8, 9, G);
boost::add_edge(6, 8, 9, G);
typedef boost::property_map< Graph, boost::edge_index_t >::type
EdgeIndexMap;
EdgeIndexMap edge_id = boost::get(boost::edge_index, G);
typedef boost::property_map<Graph, boost::edge_index_t>::type EdgeIndexMap;
EdgeIndexMap edge_id = boost::get(boost::edge_index, G);
typedef boost::iterator_property_map< int*, EdgeIndexMap, int, int& >
IterMap;
typedef boost::iterator_property_map<int*, EdgeIndexMap, int, int&> IterMap;
print_network(G, IterMap(capacity, edge_id), IterMap(flow, edge_id));
print_network(G, IterMap(capacity, edge_id), IterMap(flow, edge_id));
return 0;
return 0;
}

View File

@@ -1,18 +1,18 @@
0 --(10, 8)--> 1
1 --(20, 12)--> 4 --(40, 12)--> 3
<--(10,8)-- 0 <--(20,16)-- 2
2 --(20, 16)--> 1
<--(20,16)-- 5
3 --(40, 12)--> 6
<--(40,12)-- 1
4 --(20, 12)--> 7
<--(20,12)-- 1
5 --(20, 16)--> 2
<--(20,16)-- 6
6 --(20, 16)--> 5 --(10, 8)--> 8
<--(20,12)-- 7 <--(40,12)-- 3
7 --(20, 12)--> 6
<--(20,12)-- 4
8
<--(10,8)-- 6
0 --(10, 8)--> 1
1 --(20, 12)--> 4 --(40, 12)--> 3
<--(10,8)-- 0 <--(20,16)-- 2
2 --(20, 16)--> 1
<--(20,16)-- 5
3 --(40, 12)--> 6
<--(40,12)-- 1
4 --(20, 12)--> 7
<--(20,12)-- 1
5 --(20, 16)--> 2
<--(20,16)-- 6
6 --(20, 16)--> 5 --(10, 8)--> 8
<--(20,12)-- 7 <--(40,12)-- 3
7 --(20, 12)--> 6
<--(20,12)-- 4
8
<--(10,8)-- 6

View File

@@ -53,42 +53,41 @@ using namespace boost;
*/
template <class EdgeIter, class Graph, class Name>
void who_owes_who(EdgeIter first, EdgeIter last, const Graph& G,
Name name)
template < class EdgeIter, class Graph, class Name >
void who_owes_who(EdgeIter first, EdgeIter last, const Graph& G, Name name)
{
while (first != last) {
while (first != last)
{
cout << name[source(*first,G)] << " owes "
<< name[target(*first,G)] << " some money" << endl;
++first;
}
cout << name[source(*first, G)] << " owes " << name[target(*first, G)]
<< " some money" << endl;
++first;
}
}
int
main(int, char*[])
int main(int, char*[])
{
/* The property will be "names" attached to the vertices */
/* The property will be "names" attached to the vertices */
string* names = new string[5];
names[0] = "Jeremy";
names[1] = "Rich";
names[2] = "Andrew";
names[3] = "Jeff";
names[4] = "Kinis";
typedef adjacency_list<> MyGraphType;
string* names = new string[5];
names[0] = "Jeremy";
names[1] = "Rich";
names[2] = "Andrew";
names[3] = "Jeff";
names[4] = "Kinis";
typedef pair<int,int> Pair;
Pair edge_array[11] = { Pair(0,1), Pair(0,2), Pair(0,3), Pair(0,4),
Pair(2,0), Pair(3,0), Pair(2,4), Pair(3,1),
Pair(3,4), Pair(4,0), Pair(4,1) };
typedef adjacency_list<> MyGraphType;
typedef pair< int, int > Pair;
Pair edge_array[11] = { Pair(0, 1), Pair(0, 2), Pair(0, 3), Pair(0, 4),
Pair(2, 0), Pair(3, 0), Pair(2, 4), Pair(3, 1), Pair(3, 4), Pair(4, 0),
Pair(4, 1) };
MyGraphType G(5);
for (int i=0; i<11; ++i)
add_edge(edge_array[i].first, edge_array[i].second, G);
for (int i = 0; i < 11; ++i)
add_edge(edge_array[i].first, edge_array[i].second, G);
who_owes_who(edges(G).first, edges(G).second, G, names);
who_owes_who(edges(G).first, edges(G).second, G, names);
return 0;
return 0;
}

View File

@@ -1,5 +1,5 @@
//=======================================================================
// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee,
// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee,
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
@@ -12,41 +12,50 @@
#include <boost/graph/adjacency_list.hpp>
#include <boost/tuple/tuple.hpp>
enum family
{ Jeanie, Debbie, Rick, John, Amanda, Margaret, Benjamin, N };
int
main()
{
using namespace boost;
const char *name[] = { "Jeanie", "Debbie", "Rick", "John", "Amanda",
"Margaret", "Benjamin"
};
Jeanie,
Debbie,
Rick,
John,
Amanda,
Margaret,
Benjamin,
N
};
int main()
{
using namespace boost;
const char* name[] = { "Jeanie", "Debbie", "Rick", "John", "Amanda",
"Margaret", "Benjamin" };
adjacency_list <> g(N);
add_edge(Jeanie, Debbie, g);
add_edge(Jeanie, Rick, g);
add_edge(Jeanie, John, g);
add_edge(Debbie, Amanda, g);
add_edge(Rick, Margaret, g);
add_edge(John, Benjamin, g);
adjacency_list<> g(N);
add_edge(Jeanie, Debbie, g);
add_edge(Jeanie, Rick, g);
add_edge(Jeanie, John, g);
add_edge(Debbie, Amanda, g);
add_edge(Rick, Margaret, g);
add_edge(John, Benjamin, g);
graph_traits < adjacency_list <> >::vertex_iterator i, end;
graph_traits < adjacency_list <> >::adjacency_iterator ai, a_end;
property_map < adjacency_list <>, vertex_index_t >::type
index_map = get(vertex_index, g);
graph_traits< adjacency_list<> >::vertex_iterator i, end;
graph_traits< adjacency_list<> >::adjacency_iterator ai, a_end;
property_map< adjacency_list<>, vertex_index_t >::type index_map
= get(vertex_index, g);
for (boost::tie(i, end) = vertices(g); i != end; ++i) {
std::cout << name[get(index_map, *i)];
boost::tie(ai, a_end) = adjacent_vertices(*i, g);
if (ai == a_end)
std::cout << " has no children";
else
std::cout << " is the parent of ";
for (; ai != a_end; ++ai) {
std::cout << name[get(index_map, *ai)];
if (boost::next(ai) != a_end)
std::cout << ", ";
for (boost::tie(i, end) = vertices(g); i != end; ++i)
{
std::cout << name[get(index_map, *i)];
boost::tie(ai, a_end) = adjacent_vertices(*i, g);
if (ai == a_end)
std::cout << " has no children";
else
std::cout << " is the parent of ";
for (; ai != a_end; ++ai)
{
std::cout << name[get(index_map, *ai)];
if (boost::next(ai) != a_end)
std::cout << ", ";
}
std::cout << std::endl;
}
std::cout << std::endl;
}
return EXIT_SUCCESS;
return EXIT_SUCCESS;
}

View File

@@ -1,7 +1,7 @@
Jeanie is the parent of Debbie Rick John
Debbie is the parent of Amanda
Rick is the parent of Margaret
John is the parent of Benjamin
Jeanie is the parent of Debbie Rick John
Debbie is the parent of Amanda
Rick is the parent of Margaret
John is the parent of Benjamin
Amanda has no children
Margaret has no children
Benjamin has no children

View File

@@ -24,57 +24,63 @@ namespace random_ns = boost;
using namespace boost;
int
main()
int main()
{
typedef indirect_cmp<float*,std::less<float> > ICmp;
int i;
random_ns::mt19937 gen;
for (int N = 2; N < 200; ++N) {
uniform_int<> distrib(0, N-1);
boost::variate_generator<random_ns::mt19937&, uniform_int<> > rand_gen(gen, distrib);
for (int t = 0; t < 10; ++t) {
std::vector<float> v, w(N);
typedef indirect_cmp< float*, std::less< float > > ICmp;
int i;
random_ns::mt19937 gen;
for (int N = 2; N < 200; ++N)
{
uniform_int<> distrib(0, N - 1);
boost::variate_generator< random_ns::mt19937&, uniform_int<> > rand_gen(
gen, distrib);
for (int t = 0; t < 10; ++t)
{
std::vector< float > v, w(N);
ICmp cmp(&w[0], std::less<float>());
fibonacci_heap<int, ICmp> Q(N, cmp);
ICmp cmp(&w[0], std::less< float >());
fibonacci_heap< int, ICmp > Q(N, cmp);
for (int c = 0; c < w.size(); ++c)
w[c] = c;
for (int c = 0; c < w.size(); ++c)
w[c] = c;
#ifndef BOOST_NO_CXX98_RANDOM_SHUFFLE
std::random_shuffle(w.begin(), w.end());
std::random_shuffle(w.begin(), w.end());
#else
std::shuffle(w.begin(), w.end(), gen);
std::shuffle(w.begin(), w.end(), gen);
#endif
for (i = 0; i < N; ++i)
Q.push(i);
for (i = 0; i < N; ++i)
Q.push(i);
for (i = 0; i < N; ++i) {
int u = rand_gen();
float r = rand_gen(); r /= 2.0;
w[u] = w[u] - r;
Q.update(u);
}
for (i = 0; i < N; ++i)
{
int u = rand_gen();
float r = rand_gen();
r /= 2.0;
w[u] = w[u] - r;
Q.update(u);
}
for (i = 0; i < N; ++i) {
v.push_back(w[Q.top()]);
Q.pop();
}
std::sort(w.begin(), w.end());
for (i = 0; i < N; ++i)
{
v.push_back(w[Q.top()]);
Q.pop();
}
std::sort(w.begin(), w.end());
if (! std::equal(v.begin(), v.end(), w.begin())) {
std::cout << std::endl << "heap sorted: ";
std::copy(v.begin(), v.end(),
std::ostream_iterator<float>(std::cout," "));
std::cout << std::endl << "correct: ";
std::copy(w.begin(), w.end(),
std::ostream_iterator<float>(std::cout," "));
std::cout << std::endl;
return -1;
}
if (!std::equal(v.begin(), v.end(), w.begin()))
{
std::cout << std::endl << "heap sorted: ";
std::copy(v.begin(), v.end(),
std::ostream_iterator< float >(std::cout, " "));
std::cout << std::endl << "correct: ";
std::copy(w.begin(), w.end(),
std::ostream_iterator< float >(std::cout, " "));
std::cout << std::endl;
return -1;
}
}
}
}
std::cout << "fibonacci heap passed test" << std::endl;
return 0;
std::cout << "fibonacci heap passed test" << std::endl;
return 0;
}

View File

@@ -32,17 +32,17 @@ digraph G {
N15
H1
RT1 -> N1[label="3"]
RT1 -> N3[label="1"]
RT1 -> N1[label="3"]
RT1 -> N3[label="1"]
RT2 -> N2[label="3"]
RT2 -> N3[label="1"]
RT2 -> N2[label="3"]
RT2 -> N3[label="1"]
RT3 -> RT6[label="8"]
RT3 -> N3[label="1"]
RT3 -> N4[label="2"]
RT3 -> N3[label="1"]
RT3 -> N4[label="2"]
RT4 -> N3[label="1"]
RT4 -> N3[label="1"]
RT4 -> RT5[label="8"]
RT5 -> RT4[label="8"]
@@ -57,14 +57,14 @@ digraph G {
RT6 -> RT10[label="7"]
RT7 -> RT5[label="6"]
RT7 -> N6[label="1"]
RT7 -> N6[label="1"]
RT7 -> N12[label="2"]
RT7 -> N15[label="9"]
RT8 -> N6[label="1"]
RT8 -> N7[label="4"]
RT8 -> N6[label="1"]
RT8 -> N7[label="4"]
RT9 -> N9[label="1"]
RT9 -> N9[label="1"]
RT9 -> N11[label="3"]
RT10 -> RT6[label="5"]
@@ -84,13 +84,13 @@ digraph G {
N3 -> RT4[label="0"]
N6 -> RT7[label="0"]
N6 -> RT8[label="0"]
N6 -> RT10[label="0"]
N6 -> RT8[label="0"]
N6 -> RT10[label="0"]
N8 -> RT10[label="0"]
N8 -> RT11[label="0"]
N8 -> RT10[label="0"]
N8 -> RT11[label="0"]
N9 -> RT9[label="0"]
N9 -> RT11[label="0"]
N9 -> RT12[label="0"]
N9 -> RT11[label="0"]
N9 -> RT12[label="0"]
}

View File

@@ -16,9 +16,9 @@ digraph SCC {
"www.boost.org" -> "www.yahoogroups.com"
"www.boost.org" -> "sourceforge.net"
"www.boost.org" -> "anubis.dkuug.dk"
"www.yahoogroups.com" -> "weather.yahoo.com"
"www.yahoogroups.com" -> "weather.yahoo.com"
"www.yahoogroups.com" -> "www.boost.org"
"weather.yahoo.com" -> "nytimes.com"
"weather.yahoo.com" -> "nytimes.com"
"weather.yahoo.com" -> "www.yahoogroups.com"
"nytimes.com" -> "www.boston.com"
"www.boston.com" -> "nytimes.com"

View File

@@ -31,12 +31,12 @@ graph G {
Kearny -- Novar[label="8", weight="11"]
Novar -- Huntsville[label="5", weight="5"]
Huntsville -- Bracebridge[label="30", weight="30"]
Huntsville -- "Bent River"[label="30", weight="30"]
Rosseau -- "Bent River"[label="8", weight="8"]
Rosseau -- "Horseshoe Lake"[label="8", weight="8"]
Mactier -- "Horseshoe Lake"[label="14", weight="14"]
"Parry Sound" -- "Horseshoe Lake"[label="10", weight="10"]
"Parry Sound" -- Dunchurch[label="20", weight="20"]
Mactier -- "Glen Orchard"[label="9", weight="9"]
"Glen Orchard" -- Bracebridge[label="15", weight="15"]
Huntsville -- "Bent River"[label="30", weight="30"]
Rosseau -- "Bent River"[label="8", weight="8"]
Rosseau -- "Horseshoe Lake"[label="8", weight="8"]
Mactier -- "Horseshoe Lake"[label="14", weight="14"]
"Parry Sound" -- "Horseshoe Lake"[label="10", weight="10"]
"Parry Sound" -- Dunchurch[label="20", weight="20"]
Mactier -- "Glen Orchard"[label="9", weight="9"]
"Glen Orchard" -- Bracebridge[label="15", weight="15"]
}

View File

@@ -44,146 +44,155 @@
using namespace std;
using namespace boost;
enum files_e { dax_h, yow_h, boz_h, zow_h, foo_cpp,
foo_o, bar_cpp, bar_o, libfoobar_a,
zig_cpp, zig_o, zag_cpp, zag_o,
libzigzag_a, killerapp, N };
const char* name[] = { "dax.h", "yow.h", "boz.h", "zow.h", "foo.cpp",
"foo.o", "bar.cpp", "bar.o", "libfoobar.a",
"zig.cpp", "zig.o", "zag.cpp", "zag.o",
"libzigzag.a", "killerapp" };
struct print_visitor : public bfs_visitor<> {
template <class Vertex, class Graph>
void discover_vertex(Vertex v, Graph&) {
cout << name[v] << " ";
}
enum files_e
{
dax_h,
yow_h,
boz_h,
zow_h,
foo_cpp,
foo_o,
bar_cpp,
bar_o,
libfoobar_a,
zig_cpp,
zig_o,
zag_cpp,
zag_o,
libzigzag_a,
killerapp,
N
};
const char* name[] = { "dax.h", "yow.h", "boz.h", "zow.h", "foo.cpp", "foo.o",
"bar.cpp", "bar.o", "libfoobar.a", "zig.cpp", "zig.o", "zag.cpp", "zag.o",
"libzigzag.a", "killerapp" };
struct print_visitor : public bfs_visitor<>
{
template < class Vertex, class Graph >
void discover_vertex(Vertex v, Graph&)
{
cout << name[v] << " ";
}
};
struct cycle_detector : public dfs_visitor<>
{
cycle_detector(bool& has_cycle)
: m_has_cycle(has_cycle) { }
cycle_detector(bool& has_cycle) : m_has_cycle(has_cycle) {}
template < class Edge, class Graph > void back_edge(Edge, Graph&)
{
m_has_cycle = true;
}
template <class Edge, class Graph>
void back_edge(Edge, Graph&) { m_has_cycle = true; }
protected:
bool& m_has_cycle;
bool& m_has_cycle;
};
int main(int,char*[])
int main(int, char*[])
{
typedef pair<int,int> Edge;
Edge used_by[] = {
Edge(dax_h, foo_cpp), Edge(dax_h, bar_cpp), Edge(dax_h, yow_h),
Edge(yow_h, bar_cpp), Edge(yow_h, zag_cpp),
Edge(boz_h, bar_cpp), Edge(boz_h, zig_cpp), Edge(boz_h, zag_cpp),
Edge(zow_h, foo_cpp),
Edge(foo_cpp, foo_o),
Edge(foo_o, libfoobar_a),
Edge(bar_cpp, bar_o),
Edge(bar_o, libfoobar_a),
Edge(libfoobar_a, libzigzag_a),
Edge(zig_cpp, zig_o),
Edge(zig_o, libzigzag_a),
Edge(zag_cpp, zag_o),
Edge(zag_o, libzigzag_a),
Edge(libzigzag_a, killerapp)
};
const std::size_t nedges = sizeof(used_by)/sizeof(Edge);
typedef pair< int, int > Edge;
Edge used_by[] = { Edge(dax_h, foo_cpp), Edge(dax_h, bar_cpp),
Edge(dax_h, yow_h), Edge(yow_h, bar_cpp), Edge(yow_h, zag_cpp),
Edge(boz_h, bar_cpp), Edge(boz_h, zig_cpp), Edge(boz_h, zag_cpp),
Edge(zow_h, foo_cpp), Edge(foo_cpp, foo_o), Edge(foo_o, libfoobar_a),
Edge(bar_cpp, bar_o), Edge(bar_o, libfoobar_a),
Edge(libfoobar_a, libzigzag_a), Edge(zig_cpp, zig_o),
Edge(zig_o, libzigzag_a), Edge(zag_cpp, zag_o),
Edge(zag_o, libzigzag_a), Edge(libzigzag_a, killerapp) };
const std::size_t nedges = sizeof(used_by) / sizeof(Edge);
typedef adjacency_list<vecS, vecS, bidirectionalS> Graph;
typedef adjacency_list< vecS, vecS, bidirectionalS > Graph;
#if defined(BOOST_MSVC) && BOOST_MSVC <= 1300
// VC++ can't handle the iterator constructor
Graph g(N);
for (std::size_t j = 0; j < nedges; ++j) {
graph_traits<Graph>::edge_descriptor e; bool inserted;
boost::tie(e, inserted) = add_edge(used_by[j].first, used_by[j].second, g);
}
#else
Graph g(used_by, used_by + nedges, N);
#endif
typedef graph_traits<Graph>::vertex_descriptor Vertex;
// Determine ordering for a full recompilation
// and the order with files that can be compiled in parallel
{
typedef list<Vertex> MakeOrder;
MakeOrder::iterator i;
MakeOrder make_order;
topological_sort(g, std::front_inserter(make_order));
cout << "make ordering: ";
for (i = make_order.begin();
i != make_order.end(); ++i)
cout << name[*i] << " ";
cout << endl << endl;
// Parallel compilation ordering
std::vector<int> time(N, 0);
for (i = make_order.begin(); i != make_order.end(); ++i) {
// Walk through the in_edges an calculate the maximum time.
if (in_degree (*i, g) > 0) {
Graph::in_edge_iterator j, j_end;
int maxdist=0;
// Through the order from topological sort, we are sure that every
// time we are using here is already initialized.
for (boost::tie(j, j_end) = in_edges(*i, g); j != j_end; ++j)
maxdist=(std::max)(time[source(*j, g)], maxdist);
time[*i]=maxdist+1;
}
}
cout << "parallel make ordering, " << endl
<< "vertices with same group number can be made in parallel" << endl;
// VC++ can't handle the iterator constructor
Graph g(N);
for (std::size_t j = 0; j < nedges; ++j)
{
graph_traits<Graph>::vertex_iterator i, iend;
for (boost::tie(i,iend) = vertices(g); i != iend; ++i)
cout << "time_slot[" << name[*i] << "] = " << time[*i] << endl;
graph_traits< Graph >::edge_descriptor e;
bool inserted;
boost::tie(e, inserted)
= add_edge(used_by[j].first, used_by[j].second, g);
}
#else
Graph g(used_by, used_by + nedges, N);
#endif
typedef graph_traits< Graph >::vertex_descriptor Vertex;
// Determine ordering for a full recompilation
// and the order with files that can be compiled in parallel
{
typedef list< Vertex > MakeOrder;
MakeOrder::iterator i;
MakeOrder make_order;
topological_sort(g, std::front_inserter(make_order));
cout << "make ordering: ";
for (i = make_order.begin(); i != make_order.end(); ++i)
cout << name[*i] << " ";
cout << endl << endl;
// Parallel compilation ordering
std::vector< int > time(N, 0);
for (i = make_order.begin(); i != make_order.end(); ++i)
{
// Walk through the in_edges an calculate the maximum time.
if (in_degree(*i, g) > 0)
{
Graph::in_edge_iterator j, j_end;
int maxdist = 0;
// Through the order from topological sort, we are sure that
// every time we are using here is already initialized.
for (boost::tie(j, j_end) = in_edges(*i, g); j != j_end; ++j)
maxdist = (std::max)(time[source(*j, g)], maxdist);
time[*i] = maxdist + 1;
}
}
cout << "parallel make ordering, " << endl
<< "vertices with same group number can be made in parallel"
<< endl;
{
graph_traits< Graph >::vertex_iterator i, iend;
for (boost::tie(i, iend) = vertices(g); i != iend; ++i)
cout << "time_slot[" << name[*i] << "] = " << time[*i] << endl;
}
}
cout << endl;
// if I change yow.h what files need to be re-made?
{
cout << "A change to yow.h will cause what to be re-made?" << endl;
print_visitor vis;
breadth_first_search(g, vertex(yow_h, g), visitor(vis));
cout << endl;
}
cout << endl;
// are there any cycles in the graph?
{
bool has_cycle = false;
cycle_detector vis(has_cycle);
depth_first_search(g, visitor(vis));
cout << "The graph has a cycle? " << has_cycle << endl;
}
cout << endl;
// add a dependency going from bar.cpp to dax.h
{
cout << "adding edge bar_cpp -> dax_h" << endl;
add_edge(bar_cpp, dax_h, g);
}
cout << endl;
// are there any cycles in the graph?
{
bool has_cycle = false;
cycle_detector vis(has_cycle);
depth_first_search(g, visitor(vis));
cout << "The graph has a cycle now? " << has_cycle << endl;
}
}
cout << endl;
// if I change yow.h what files need to be re-made?
{
cout << "A change to yow.h will cause what to be re-made?" << endl;
print_visitor vis;
breadth_first_search(g, vertex(yow_h, g), visitor(vis));
cout << endl;
}
cout << endl;
// are there any cycles in the graph?
{
bool has_cycle = false;
cycle_detector vis(has_cycle);
depth_first_search(g, visitor(vis));
cout << "The graph has a cycle? " << has_cycle << endl;
}
cout << endl;
// add a dependency going from bar.cpp to dax.h
{
cout << "adding edge bar_cpp -> dax_h" << endl;
add_edge(bar_cpp, dax_h, g);
}
cout << endl;
// are there any cycles in the graph?
{
bool has_cycle = false;
cycle_detector vis(has_cycle);
depth_first_search(g, visitor(vis));
cout << "The graph has a cycle now? " << has_cycle << endl;
}
return 0;
return 0;
}

View File

@@ -1,6 +1,6 @@
make ordering: zow.h boz.h zig.cpp zig.o dax.h yow.h zag.cpp zag.o bar.cpp bar.o foo.cpp foo.o libfoobar.a libzigzag.a killerapp
make ordering: zow.h boz.h zig.cpp zig.o dax.h yow.h zag.cpp zag.o bar.cpp bar.o foo.cpp foo.o libfoobar.a libzigzag.a killerapp
parallel make ordering,
parallel make ordering,
vertices with same group number can be made in parallel
time_slot[dax.h] = 0
time_slot[yow.h] = 1
@@ -19,7 +19,7 @@ time_slot[libzigzag.a] = 5
time_slot[killerapp] = 6
A change to yow.h will cause what to be re-made?
yow.h bar.cpp zag.cpp bar.o zag.o libfoobar.a libzigzag.a killerapp
yow.h bar.cpp zag.cpp bar.o zag.o libfoobar.a libzigzag.a killerapp
The graph has a cycle? 0

View File

@@ -1,5 +1,5 @@
//=======================================================================
// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee,
// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee,
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
@@ -12,52 +12,63 @@
#include <boost/graph/filtered_graph.hpp>
#include <boost/graph/graph_utility.hpp>
template <typename Graph>
struct non_zero_degree {
non_zero_degree() { } // has to have a default constructor!
template < typename Graph > struct non_zero_degree
{
non_zero_degree() {} // has to have a default constructor!
non_zero_degree(const Graph& g) : g(&g) { }
non_zero_degree(const Graph& g) : g(&g) {}
bool operator()(typename boost::graph_traits<Graph>::vertex_descriptor v) const
{
return degree(v, *g) != 0;
}
const Graph* g;
bool operator()(
typename boost::graph_traits< Graph >::vertex_descriptor v) const
{
return degree(v, *g) != 0;
}
const Graph* g;
};
int
main()
int main()
{
using namespace boost;
typedef adjacency_list < vecS, vecS, bidirectionalS,
property < vertex_name_t, char > > graph_t;
using namespace boost;
typedef adjacency_list< vecS, vecS, bidirectionalS,
property< vertex_name_t, char > >
graph_t;
enum { a, b, c, d, e, f, g, N };
graph_t G(N);
property_map < graph_t, vertex_name_t >::type
name_map = get(vertex_name, G);
char name = 'a';
graph_traits < graph_t >::vertex_iterator v, v_end;
for (boost::tie(v, v_end) = vertices(G); v != v_end; ++v, ++name)
name_map[*v] = name;
enum
{
a,
b,
c,
d,
e,
f,
g,
N
};
graph_t G(N);
property_map< graph_t, vertex_name_t >::type name_map = get(vertex_name, G);
char name = 'a';
graph_traits< graph_t >::vertex_iterator v, v_end;
for (boost::tie(v, v_end) = vertices(G); v != v_end; ++v, ++name)
name_map[*v] = name;
typedef std::pair < int, int >E;
E edges[] = { E(a, c), E(a, d), E(b, a), E(b, d), E(c, f),
E(d, c), E(d, e), E(d, f), E(e, b), E(e, g), E(f, e), E(f, g)
};
for (int i = 0; i < 12; ++i)
add_edge(edges[i].first, edges[i].second, G);
typedef std::pair< int, int > E;
E edges[] = { E(a, c), E(a, d), E(b, a), E(b, d), E(c, f), E(d, c), E(d, e),
E(d, f), E(e, b), E(e, g), E(f, e), E(f, g) };
for (int i = 0; i < 12; ++i)
add_edge(edges[i].first, edges[i].second, G);
print_graph(G, name_map);
std::cout << std::endl;
print_graph(G, name_map);
std::cout << std::endl;
clear_vertex(b, G);
clear_vertex(d, G);
clear_vertex(b, G);
clear_vertex(d, G);
graph_t G_copy;
copy_graph(make_filtered_graph(G, keep_all(), non_zero_degree<graph_t>(G)), G_copy);
graph_t G_copy;
copy_graph(
make_filtered_graph(G, keep_all(), non_zero_degree< graph_t >(G)),
G_copy);
print_graph(G_copy, get(vertex_name, G_copy));
print_graph(G_copy, get(vertex_name, G_copy));
return 0;
return 0;
}

View File

@@ -7,16 +7,16 @@
// http://www.boost.org/LICENSE_1_0.txt)
//=======================================================================
/*
/*
Sample output:
filtered edge set: (A,B) (C,D) (D,B)
filtered edge set: (A,B) (C,D) (D,B)
filtered out-edges:
A --> B
B -->
C --> D
D --> B
E -->
A --> B
B -->
C --> D
D --> B
E -->
*/
#include <boost/config.hpp>
@@ -25,45 +25,53 @@
#include <boost/graph/filtered_graph.hpp>
#include <boost/graph/graph_utility.hpp>
template <typename EdgeWeightMap>
struct positive_edge_weight {
positive_edge_weight() { }
positive_edge_weight(EdgeWeightMap weight) : m_weight(weight) { }
template <typename Edge>
bool operator()(const Edge& e) const {
return 0 < boost::get(m_weight, e);
}
EdgeWeightMap m_weight;
template < typename EdgeWeightMap > struct positive_edge_weight
{
positive_edge_weight() {}
positive_edge_weight(EdgeWeightMap weight) : m_weight(weight) {}
template < typename Edge > bool operator()(const Edge& e) const
{
return 0 < boost::get(m_weight, e);
}
EdgeWeightMap m_weight;
};
int main()
{
using namespace boost;
typedef adjacency_list<vecS, vecS, directedS,
no_property, property<edge_weight_t, int> > Graph;
typedef property_map<Graph, edge_weight_t>::type EdgeWeightMap;
using namespace boost;
enum { A, B, C, D, E, N };
const char* name = "ABCDE";
Graph g(N);
add_edge(A, B, 2, g);
add_edge(A, C, 0, g);
add_edge(C, D, 1, g);
add_edge(C, E, 0, g);
add_edge(D, B, 3, g);
add_edge(E, C, 0, g);
positive_edge_weight<EdgeWeightMap> filter(get(edge_weight, g));
filtered_graph<Graph, positive_edge_weight<EdgeWeightMap> >
fg(g, filter);
typedef adjacency_list< vecS, vecS, directedS, no_property,
property< edge_weight_t, int > >
Graph;
typedef property_map< Graph, edge_weight_t >::type EdgeWeightMap;
std::cout << "filtered edge set: ";
print_edges(fg, name);
enum
{
A,
B,
C,
D,
E,
N
};
const char* name = "ABCDE";
Graph g(N);
add_edge(A, B, 2, g);
add_edge(A, C, 0, g);
add_edge(C, D, 1, g);
add_edge(C, E, 0, g);
add_edge(D, B, 3, g);
add_edge(E, C, 0, g);
std::cout << "filtered out-edges:" << std::endl;
print_graph(fg, name);
return 0;
positive_edge_weight< EdgeWeightMap > filter(get(edge_weight, g));
filtered_graph< Graph, positive_edge_weight< EdgeWeightMap > > fg(
g, filter);
std::cout << "filtered edge set: ";
print_edges(fg, name);
std::cout << "filtered out-edges:" << std::endl;
print_graph(fg, name);
return 0;
}

View File

@@ -1,7 +1,7 @@
filtered edge set: (A,B) (C,D) (D,B)
filtered edge set: (A,B) (C,D) (D,B)
filtered out-edges:
A --> B
B -->
C --> D
D --> B
E -->
A --> B
B -->
C --> D
D --> B
E -->

View File

@@ -7,16 +7,16 @@
// http://www.boost.org/LICENSE_1_0.txt)
//=======================================================================
/*
/*
Sample output:
filtered edge set: (A,B) (C,D) (D,B)
filtered edge set: (A,B) (C,D) (D,B)
filtered out-edges:
A --> B
B -->
C --> D
D --> B
E -->
A --> B
B -->
C --> D
D --> B
E -->
*/
#include <boost/config.hpp>
@@ -25,55 +25,64 @@
#include <boost/graph/filtered_graph.hpp>
#include <boost/graph/graph_utility.hpp>
template <typename EdgeWeightMap>
struct positive_edge_weight {
positive_edge_weight() { }
positive_edge_weight(EdgeWeightMap weight) : m_weight(weight) { }
template <typename Edge>
bool operator()(const Edge& e) const {
return 0 < boost::get(m_weight, e);
}
EdgeWeightMap m_weight;
template < typename EdgeWeightMap > struct positive_edge_weight
{
positive_edge_weight() {}
positive_edge_weight(EdgeWeightMap weight) : m_weight(weight) {}
template < typename Edge > bool operator()(const Edge& e) const
{
return 0 < boost::get(m_weight, e);
}
EdgeWeightMap m_weight;
};
int main()
{
using namespace boost;
typedef adjacency_list<multisetS, vecS, directedS,
no_property, property<edge_weight_t, int> > Graph;
typedef property_map<Graph, edge_weight_t>::type EdgeWeightMap;
using namespace boost;
enum { A, B, C, D, E, N };
const char* name = "ABCDE";
Graph g(N);
add_edge(A, B, 2, g);
add_edge(A, C, 0, g);
add_edge(C, D, 1, g);
add_edge(C, D, 0, g);
add_edge(C, D, 3, g);
add_edge(C, E, 0, g);
add_edge(D, B, 3, g);
add_edge(E, C, 0, g);
typedef adjacency_list< multisetS, vecS, directedS, no_property,
property< edge_weight_t, int > >
Graph;
typedef property_map< Graph, edge_weight_t >::type EdgeWeightMap;
EdgeWeightMap weight = get(edge_weight, g);
enum
{
A,
B,
C,
D,
E,
N
};
const char* name = "ABCDE";
Graph g(N);
add_edge(A, B, 2, g);
add_edge(A, C, 0, g);
add_edge(C, D, 1, g);
add_edge(C, D, 0, g);
add_edge(C, D, 3, g);
add_edge(C, E, 0, g);
add_edge(D, B, 3, g);
add_edge(E, C, 0, g);
std::cout << "unfiltered edge_range(C,D)\n";
graph_traits<Graph>::out_edge_iterator f, l;
for (boost::tie(f, l) = edge_range(C, D, g); f != l; ++f)
std::cout << name[source(*f, g)] << " --" << weight[*f]
<< "-> " << name[target(*f, g)] << "\n";
EdgeWeightMap weight = get(edge_weight, g);
positive_edge_weight<EdgeWeightMap> filter(weight);
typedef filtered_graph<Graph, positive_edge_weight<EdgeWeightMap> > FGraph;
FGraph fg(g, filter);
std::cout << "unfiltered edge_range(C,D)\n";
graph_traits< Graph >::out_edge_iterator f, l;
for (boost::tie(f, l) = edge_range(C, D, g); f != l; ++f)
std::cout << name[source(*f, g)] << " --" << weight[*f] << "-> "
<< name[target(*f, g)] << "\n";
std::cout << "filtered edge_range(C,D)\n";
graph_traits<FGraph>::out_edge_iterator first, last;
for (boost::tie(first, last) = edge_range(C, D, fg); first != last; ++first)
std::cout << name[source(*first, fg)] << " --" << weight[*first]
<< "-> " << name[target(*first, fg)] << "\n";
return 0;
positive_edge_weight< EdgeWeightMap > filter(weight);
typedef filtered_graph< Graph, positive_edge_weight< EdgeWeightMap > >
FGraph;
FGraph fg(g, filter);
std::cout << "filtered edge_range(C,D)\n";
graph_traits< FGraph >::out_edge_iterator first, last;
for (boost::tie(first, last) = edge_range(C, D, fg); first != last; ++first)
std::cout << name[source(*first, fg)] << " --" << weight[*first]
<< "-> " << name[target(*first, fg)] << "\n";
return 0;
}

View File

@@ -7,15 +7,15 @@
// http://www.boost.org/LICENSE_1_0.txt)
//=======================================================================
/*
/*
Sample output:
filtered out-edges:
A -->
B -->
C --> E
D --> E
E -->
A -->
B -->
C --> E
D --> E
E -->
*/
#include <boost/config.hpp>
@@ -24,36 +24,45 @@
#include <boost/graph/filtered_graph.hpp>
#include <boost/graph/graph_utility.hpp>
struct constant_target {
constant_target() { }
constant_target(int t) : target(t) { }
bool operator()(const std::pair<int,int>& e) const {
return e.second == target;
}
int target;
struct constant_target
{
constant_target() {}
constant_target(int t) : target(t) {}
bool operator()(const std::pair< int, int >& e) const
{
return e.second == target;
}
int target;
};
int main()
{
using namespace boost;
enum { A, B, C, D, E, N };
const char* name = "ABCDE";
typedef std::vector < std::list < int > > Graph;
Graph g(N);
g[A].push_back(B);
g[A].push_back(C);
g[C].push_back(D);
g[C].push_back(E);
g[D].push_back(E);
g[E].push_back(C);
using namespace boost;
constant_target filter(E);
filtered_graph<Graph, constant_target> fg(g, filter);
enum
{
A,
B,
C,
D,
E,
N
};
const char* name = "ABCDE";
typedef std::vector< std::list< int > > Graph;
Graph g(N);
g[A].push_back(B);
g[A].push_back(C);
g[C].push_back(D);
g[C].push_back(E);
g[D].push_back(E);
g[E].push_back(C);
std::cout << "filtered out-edges:" << std::endl;
print_graph(fg, name);
return 0;
constant_target filter(E);
filtered_graph< Graph, constant_target > fg(g, filter);
std::cout << "filtered out-edges:" << std::endl;
print_graph(fg, name);
return 0;
}

View File

@@ -23,114 +23,136 @@ using namespace boost;
void usage()
{
std::cerr << "Usage: fr_layout [options] <width> <height>\n"
<< "Arguments:\n"
<< "\t<width>\tWidth of the display area (floating point)\n"
<< "\t<Height>\tHeight of the display area (floating point)\n\n"
<< "Options:\n"
<< "\t--iterations n\tNumber of iterations to execute.\n"
<< "\t\t\tThe default value is 100.\n"
<< "Input:\n"
<< " Input is read from standard input as a list of edges, one per line.\n"
<< " Each edge contains two string labels (the endpoints) separated by a space.\n\n"
<< "Output:\n"
<< " Vertices and their positions are written to standard output with the label,\n x-position, and y-position of a vertex on each line, separated by spaces.\n";
std::cerr << "Usage: fr_layout [options] <width> <height>\n"
<< "Arguments:\n"
<< "\t<width>\tWidth of the display area (floating point)\n"
<< "\t<Height>\tHeight of the display area (floating point)\n\n"
<< "Options:\n"
<< "\t--iterations n\tNumber of iterations to execute.\n"
<< "\t\t\tThe default value is 100.\n"
<< "Input:\n"
<< " Input is read from standard input as a list of edges, one "
"per line.\n"
<< " Each edge contains two string labels (the endpoints) "
"separated by a space.\n\n"
<< "Output:\n"
<< " Vertices and their positions are written to standard "
"output with the label,\n x-position, and y-position of a "
"vertex on each line, separated by spaces.\n";
}
typedef boost::rectangle_topology<> topology_type;
typedef topology_type::point_type point_type;
typedef adjacency_list<listS, vecS, undirectedS,
property<vertex_name_t, std::string> > Graph;
typedef adjacency_list< listS, vecS, undirectedS,
property< vertex_name_t, std::string > >
Graph;
typedef graph_traits<Graph>::vertex_descriptor Vertex;
typedef graph_traits< Graph >::vertex_descriptor Vertex;
typedef std::map<std::string, Vertex> NameToVertex;
typedef std::map< std::string, Vertex > NameToVertex;
Vertex get_vertex(const std::string& name, Graph& g, NameToVertex& names)
{
NameToVertex::iterator i = names.find(name);
if (i == names.end())
i = names.insert(std::make_pair(name, add_vertex(name, g))).first;
return i->second;
NameToVertex::iterator i = names.find(name);
if (i == names.end())
i = names.insert(std::make_pair(name, add_vertex(name, g))).first;
return i->second;
}
class progress_cooling : public linear_cooling<double>
class progress_cooling : public linear_cooling< double >
{
typedef linear_cooling<double> inherited;
typedef linear_cooling< double > inherited;
public:
explicit progress_cooling(std::size_t iterations) : inherited(iterations)
{
display.reset(new progress_display(iterations + 1, std::cerr));
}
public:
explicit progress_cooling(std::size_t iterations) : inherited(iterations)
{
display.reset(new progress_display(iterations + 1, std::cerr));
}
double operator()()
{
++(*display);
return inherited::operator()();
}
double operator()()
{
++(*display);
return inherited::operator()();
}
private:
shared_ptr<boost::progress_display> display;
private:
shared_ptr< boost::progress_display > display;
};
int main(int argc, char* argv[])
{
int iterations = 100;
int iterations = 100;
if (argc < 3) { usage(); return -1; }
double width = 0;
double height = 0;
for (int arg_idx = 1; arg_idx < argc; ++arg_idx) {
std::string arg = argv[arg_idx];
if (arg == "--iterations") {
++arg_idx;
if (arg_idx >= argc) { usage(); return -1; }
iterations = lexical_cast<int>(argv[arg_idx]);
} else {
if (width == 0.0) width = lexical_cast<double>(arg);
else if (height == 0.0) height = lexical_cast<double>(arg);
else {
if (argc < 3)
{
usage();
return -1;
}
}
}
if (width == 0.0 || height == 0.0) {
usage();
return -1;
}
double width = 0;
double height = 0;
Graph g;
NameToVertex names;
for (int arg_idx = 1; arg_idx < argc; ++arg_idx)
{
std::string arg = argv[arg_idx];
if (arg == "--iterations")
{
++arg_idx;
if (arg_idx >= argc)
{
usage();
return -1;
}
iterations = lexical_cast< int >(argv[arg_idx]);
}
else
{
if (width == 0.0)
width = lexical_cast< double >(arg);
else if (height == 0.0)
height = lexical_cast< double >(arg);
else
{
usage();
return -1;
}
}
}
std::string source, target;
while (std::cin >> source >> target) {
add_edge(get_vertex(source, g, names), get_vertex(target, g, names), g);
}
typedef std::vector<point_type> PositionVec;
PositionVec position_vec(num_vertices(g));
typedef iterator_property_map<PositionVec::iterator,
property_map<Graph, vertex_index_t>::type>
PositionMap;
PositionMap position(position_vec.begin(), get(vertex_index, g));
if (width == 0.0 || height == 0.0)
{
usage();
return -1;
}
minstd_rand gen;
topology_type topo(gen, -width/2, -height/2, width/2, height/2);
random_graph_layout(g, position, topo);
fruchterman_reingold_force_directed_layout
(g, position, topo,
cooling(progress_cooling(iterations)));
Graph g;
NameToVertex names;
graph_traits<Graph>::vertex_iterator vi, vi_end;
for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) {
std::cout << get(vertex_name, g, *vi) << '\t'
<< position[*vi][0] << '\t' << position[*vi][1] << std::endl;
}
return 0;
std::string source, target;
while (std::cin >> source >> target)
{
add_edge(get_vertex(source, g, names), get_vertex(target, g, names), g);
}
typedef std::vector< point_type > PositionVec;
PositionVec position_vec(num_vertices(g));
typedef iterator_property_map< PositionVec::iterator,
property_map< Graph, vertex_index_t >::type >
PositionMap;
PositionMap position(position_vec.begin(), get(vertex_index, g));
minstd_rand gen;
topology_type topo(gen, -width / 2, -height / 2, width / 2, height / 2);
random_graph_layout(g, position, topo);
fruchterman_reingold_force_directed_layout(
g, position, topo, cooling(progress_cooling(iterations)));
graph_traits< Graph >::vertex_iterator vi, vi_end;
for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
{
std::cout << get(vertex_name, g, *vi) << '\t' << position[*vi][0]
<< '\t' << position[*vi][1] << std::endl;
}
return 0;
}

View File

@@ -20,133 +20,145 @@
/*
Sample output:
0 --c--> 1 --j--> 1 --c--> 2 --x--> 2
1 --c--> 2 --d--> 3
2 --t--> 4
3 --h--> 4
4
0 --c--> 1 --j--> 1 --c--> 2 --x--> 2
1 --c--> 2 --d--> 3
2 --t--> 4
3 --h--> 4
4
merging vertex 1 into vertex 0
0 --c--> 0 --j--> 0 --c--> 1 --x--> 1 --d--> 2
1 --t--> 3
2 --h--> 3
3
0 --c--> 0 --j--> 0 --c--> 1 --x--> 1 --d--> 2
1 --t--> 3
2 --h--> 3
3
*/
// merge_vertex(u,v,g):
// incoming/outgoing edges for v become incoming/outgoing edges for u
// v is deleted
template <class Graph, class GetEdgeProperties>
void merge_vertex
(typename boost::graph_traits<Graph>::vertex_descriptor u,
typename boost::graph_traits<Graph>::vertex_descriptor v,
Graph& g, GetEdgeProperties getp)
template < class Graph, class GetEdgeProperties >
void merge_vertex(typename boost::graph_traits< Graph >::vertex_descriptor u,
typename boost::graph_traits< Graph >::vertex_descriptor v, Graph& g,
GetEdgeProperties getp)
{
typedef boost::graph_traits<Graph> Traits;
typename Traits::edge_descriptor e;
typename Traits::out_edge_iterator out_i, out_end;
for (boost::tie(out_i, out_end) = out_edges(v, g); out_i != out_end; ++out_i) {
e = *out_i;
typename Traits::vertex_descriptor targ = target(e, g);
add_edge(u, targ, getp(e), g);
}
typename Traits::in_edge_iterator in_i, in_end;
for (boost::tie(in_i, in_end) = in_edges(v, g); in_i != in_end; ++in_i) {
e = *in_i;
typename Traits::vertex_descriptor src = source(e, g);
add_edge(src, u, getp(e), g);
}
clear_vertex(v, g);
remove_vertex(v, g);
typedef boost::graph_traits< Graph > Traits;
typename Traits::edge_descriptor e;
typename Traits::out_edge_iterator out_i, out_end;
for (boost::tie(out_i, out_end) = out_edges(v, g); out_i != out_end;
++out_i)
{
e = *out_i;
typename Traits::vertex_descriptor targ = target(e, g);
add_edge(u, targ, getp(e), g);
}
typename Traits::in_edge_iterator in_i, in_end;
for (boost::tie(in_i, in_end) = in_edges(v, g); in_i != in_end; ++in_i)
{
e = *in_i;
typename Traits::vertex_descriptor src = source(e, g);
add_edge(src, u, getp(e), g);
}
clear_vertex(v, g);
remove_vertex(v, g);
}
template <class StoredEdge>
struct order_by_name
template < class StoredEdge > struct order_by_name
{
typedef StoredEdge first_argument_type;
typedef StoredEdge second_argument_type;
typedef bool result_type;
bool operator()(const StoredEdge& e1, const StoredEdge& e2) const
{
// Using std::pair operator< as an easy way to get lexicographical
// compare over tuples.
return std::make_pair(e1.get_target(), boost::get(boost::edge_name, e1))
< std::make_pair(e2.get_target(), boost::get(boost::edge_name, e2));
}
};
struct ordered_set_by_nameS
{
typedef StoredEdge first_argument_type;
typedef StoredEdge second_argument_type;
typedef bool result_type;
bool operator()(const StoredEdge& e1, const StoredEdge& e2) const {
// Using std::pair operator< as an easy way to get lexicographical
// compare over tuples.
return std::make_pair(e1.get_target(), boost::get(boost::edge_name, e1))
< std::make_pair(e2.get_target(), boost::get(boost::edge_name, e2));
}
};
struct ordered_set_by_nameS { };
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
namespace boost {
template <class ValueType>
struct container_gen<ordered_set_by_nameS, ValueType> {
typedef std::set<ValueType, order_by_name<ValueType> > type;
};
template <>
struct parallel_edge_traits<ordered_set_by_nameS> {
namespace boost
{
template < class ValueType >
struct container_gen< ordered_set_by_nameS, ValueType >
{
typedef std::set< ValueType, order_by_name< ValueType > > type;
};
template <> struct parallel_edge_traits< ordered_set_by_nameS >
{
typedef allow_parallel_edge_tag type;
};
};
}
#endif
template <class Graph>
struct get_edge_name {
get_edge_name(const Graph& g_) : g(g_) { }
template < class Graph > struct get_edge_name
{
get_edge_name(const Graph& g_) : g(g_) {}
template <class Edge>
boost::property<boost::edge_name_t, char> operator()(Edge e) const {
return boost::property<boost::edge_name_t, char>(boost::get(boost::edge_name, g, e));
}
const Graph& g;
template < class Edge >
boost::property< boost::edge_name_t, char > operator()(Edge e) const
{
return boost::property< boost::edge_name_t, char >(
boost::get(boost::edge_name, g, e));
}
const Graph& g;
};
int
main()
int main()
{
#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
std::cout << "This program requires partial specialization." << std::endl;
std::cout << "This program requires partial specialization." << std::endl;
#else
using namespace boost;
typedef property<edge_name_t, char> EdgeProperty;
typedef adjacency_list<ordered_set_by_nameS, vecS, bidirectionalS,
no_property, EdgeProperty> graph_type;
using namespace boost;
typedef property< edge_name_t, char > EdgeProperty;
typedef adjacency_list< ordered_set_by_nameS, vecS, bidirectionalS,
no_property, EdgeProperty >
graph_type;
graph_type g;
graph_type g;
add_edge(0, 1, EdgeProperty('j'), g);
add_edge(0, 2, EdgeProperty('c'), g);
add_edge(0, 2, EdgeProperty('x'), g);
add_edge(1, 3, EdgeProperty('d'), g);
add_edge(1, 2, EdgeProperty('c'), g);
add_edge(1, 3, EdgeProperty('d'), g);
add_edge(2, 4, EdgeProperty('t'), g);
add_edge(3, 4, EdgeProperty('h'), g);
add_edge(0, 1, EdgeProperty('c'), g);
property_map<graph_type, vertex_index_t>::type id = get(vertex_index, g);
property_map<graph_type, edge_name_t>::type name = get(edge_name, g);
add_edge(0, 1, EdgeProperty('j'), g);
add_edge(0, 2, EdgeProperty('c'), g);
add_edge(0, 2, EdgeProperty('x'), g);
add_edge(1, 3, EdgeProperty('d'), g);
add_edge(1, 2, EdgeProperty('c'), g);
add_edge(1, 3, EdgeProperty('d'), g);
add_edge(2, 4, EdgeProperty('t'), g);
add_edge(3, 4, EdgeProperty('h'), g);
add_edge(0, 1, EdgeProperty('c'), g);
graph_traits<graph_type>::vertex_iterator i, end;
graph_traits<graph_type>::out_edge_iterator ei, edge_end;
property_map< graph_type, vertex_index_t >::type id = get(vertex_index, g);
property_map< graph_type, edge_name_t >::type name = get(edge_name, g);
for (boost::tie(i, end) = vertices(g); i != end; ++i) {
std::cout << id[*i] << " ";
for (boost::tie(ei, edge_end) = out_edges(*i, g); ei != edge_end; ++ei)
std::cout << " --" << name[*ei] << "--> " << id[target(*ei, g)] << " ";
graph_traits< graph_type >::vertex_iterator i, end;
graph_traits< graph_type >::out_edge_iterator ei, edge_end;
for (boost::tie(i, end) = vertices(g); i != end; ++i)
{
std::cout << id[*i] << " ";
for (boost::tie(ei, edge_end) = out_edges(*i, g); ei != edge_end; ++ei)
std::cout << " --" << name[*ei] << "--> " << id[target(*ei, g)]
<< " ";
std::cout << std::endl;
}
std::cout << std::endl;
}
std::cout << std::endl;
std::cout << "merging vertex 1 into vertex 0" << std::endl << std::endl;
merge_vertex(0, 1, g, get_edge_name<graph_type>(g));
for (boost::tie(i, end) = vertices(g); i != end; ++i) {
std::cout << id[*i] << " ";
for (boost::tie(ei, edge_end) = out_edges(*i, g); ei != edge_end; ++ei)
std::cout << " --" << name[*ei] << "--> " << id[target(*ei, g)] << " ";
std::cout << "merging vertex 1 into vertex 0" << std::endl << std::endl;
merge_vertex(0, 1, g, get_edge_name< graph_type >(g));
for (boost::tie(i, end) = vertices(g); i != end; ++i)
{
std::cout << id[*i] << " ";
for (boost::tie(ei, edge_end) = out_edges(*i, g); ei != edge_end; ++ei)
std::cout << " --" << name[*ei] << "--> " << id[target(*ei, g)]
<< " ";
std::cout << std::endl;
}
std::cout << std::endl;
}
std::cout << std::endl;
#endif
return 0;
#endif
return 0;
}

View File

@@ -1,13 +1,13 @@
0 --c--> 1 --j--> 1 --c--> 2 --x--> 2
1 --c--> 2 --d--> 3
2 --t--> 4
3 --h--> 4
4
0 --c--> 1 --j--> 1 --c--> 2 --x--> 2
1 --c--> 2 --d--> 3
2 --t--> 4
3 --h--> 4
4
merging vertex 1 into vertex 0
0 --c--> 0 --j--> 0 --c--> 1 --x--> 1 --d--> 2
1 --t--> 3
2 --h--> 3
3
0 --c--> 0 --j--> 0 --c--> 1 --x--> 1 --d--> 2
1 --t--> 3
2 --h--> 3
3

View File

@@ -37,7 +37,7 @@
3 vertices at distance 14,
1 vertices at distance 15.
So the diameter is 15, and the girth is 9.
*/
#include <boost/config.hpp>
@@ -49,112 +49,114 @@
#include <boost/graph/breadth_first_search.hpp>
#include <boost/graph/graph_utility.hpp>
typedef boost::graph_traits<Graph*> Traits;
typedef boost::graph_traits< Graph* > Traits;
typedef Traits::vertex_descriptor vertex_descriptor;
typedef Traits::edge_descriptor edge_descriptor;
typedef Traits::vertex_iterator vertex_iterator;
std::vector<std::size_t> distance_list;
std::vector< std::size_t > distance_list;
typedef boost::v_property<long> dist_t;
boost::property_map<Graph*, dist_t>::type d_map;
typedef boost::v_property< long > dist_t;
boost::property_map< Graph*, dist_t >::type d_map;
typedef boost::u_property<vertex_descriptor> pred_t;
boost::property_map<Graph*, pred_t>::type p_map;
typedef boost::u_property< vertex_descriptor > pred_t;
boost::property_map< Graph*, pred_t >::type p_map;
typedef boost::w_property<long> color_t;
boost::property_map<Graph*, color_t>::type c_map;
typedef boost::w_property< long > color_t;
boost::property_map< Graph*, color_t >::type c_map;
class diameter_and_girth_visitor : public boost::bfs_visitor<>
{
public:
diameter_and_girth_visitor(std::size_t& k_, std::size_t& girth_)
: k(k_), girth(girth_) { }
diameter_and_girth_visitor(std::size_t& k_, std::size_t& girth_)
: k(k_), girth(girth_)
{
}
void tree_edge(edge_descriptor e, Graph* g)
{
vertex_descriptor u = source(e, g), v = target(e, g);
k = d_map[u] + 1;
d_map[v] = k;
++distance_list[k];
p_map[v] = u;
}
void non_tree_edge(edge_descriptor e, Graph* g)
{
vertex_descriptor u = source(e, g), v = target(e, g);
k = d_map[u] + 1;
if (d_map[v] + k < girth && v != p_map[u])
girth = d_map[v] + k;
}
void tree_edge(edge_descriptor e, Graph* g) {
vertex_descriptor u = source(e, g), v = target(e, g);
k = d_map[u] + 1;
d_map[v] = k;
++distance_list[k];
p_map[v] = u;
}
void non_tree_edge(edge_descriptor e, Graph* g) {
vertex_descriptor u = source(e, g), v = target(e, g);
k = d_map[u] + 1;
if (d_map[v] + k < girth && v != p_map[u])
girth = d_map[v]+ k;
}
private:
std::size_t& k;
std::size_t& girth;
std::size_t& k;
std::size_t& girth;
};
int
main()
int main()
{
std::cout <<
"This program explores the girth and diameter of Ramanujan graphs."
<< std::endl;
std::cout <<
"The bipartite graphs have q^3-q vertices, and the non-bipartite"
<< std::endl;
std::cout <<
"graphs have half that number. Each vertex has degree p+1."
<< std::endl;
std::cout << "Both p and q should be odd prime numbers;" << std::endl;
std::cout << " or you can try p = 2 with q = 17 or 43." << std::endl;
std::cout
<< "This program explores the girth and diameter of Ramanujan graphs."
<< std::endl;
std::cout
<< "The bipartite graphs have q^3-q vertices, and the non-bipartite"
<< std::endl;
std::cout << "graphs have half that number. Each vertex has degree p+1."
<< std::endl;
std::cout << "Both p and q should be odd prime numbers;" << std::endl;
std::cout << " or you can try p = 2 with q = 17 or 43." << std::endl;
while (1) {
while (1)
{
std::cout << std::endl
<< "Choose a branching factor, p: ";
long p = 0, q = 0;
std::cin >> p;
if (p == 0)
break;
std::cout << "Ok, now choose the cube root of graph size, q: ";
std::cin >> q;
if (q == 0)
break;
std::cout << std::endl << "Choose a branching factor, p: ";
long p = 0, q = 0;
std::cin >> p;
if (p == 0)
break;
std::cout << "Ok, now choose the cube root of graph size, q: ";
std::cin >> q;
if (q == 0)
break;
Graph* g;
g = raman(p, q, 0L, 0L);
if (g == 0) {
std::cerr << " Sorry, I couldn't make that graph (error code "
<< panic_code << ")" << std::endl;
continue;
}
distance_list.clear();
distance_list.resize(boost::num_vertices(g), 0);
Graph* g;
g = raman(p, q, 0L, 0L);
if (g == 0)
{
std::cerr << " Sorry, I couldn't make that graph (error code "
<< panic_code << ")" << std::endl;
continue;
}
distance_list.clear();
distance_list.resize(boost::num_vertices(g), 0);
// obtain property maps
d_map = get(dist_t(), g);
p_map = get(pred_t(), g);
c_map = get(color_t(), g);
// obtain property maps
d_map = get(dist_t(), g);
p_map = get(pred_t(), g);
c_map = get(color_t(), g);
vertex_iterator i, end;
for (boost::tie(i, end) = boost::vertices(g); i != end; ++i)
d_map[*i] = 0;
vertex_iterator i, end;
for (boost::tie(i, end) = boost::vertices(g); i != end; ++i)
d_map[*i] = 0;
std::size_t k = 0;
std::size_t girth = (std::numeric_limits<std::size_t>::max)();
diameter_and_girth_visitor vis(k, girth);
std::size_t k = 0;
std::size_t girth = (std::numeric_limits< std::size_t >::max)();
diameter_and_girth_visitor vis(k, girth);
vertex_descriptor s = *boost::vertices(g).first;
vertex_descriptor s = *boost::vertices(g).first;
boost::breadth_first_search(g, s, visitor(vis).color_map(c_map));
boost::breadth_first_search(g, s, visitor(vis).color_map(c_map));
std::cout << "Starting at any given vertex, there are" << std::endl;
std::cout << "Starting at any given vertex, there are" << std::endl;
for (long d = 1; distance_list[d] != 0; ++d)
std::cout << distance_list[d] << " vertices at distance " << d
<< (distance_list[d+1] != 0 ? "," : ".") << std::endl;
for (long d = 1; distance_list[d] != 0; ++d)
std::cout << distance_list[d] << " vertices at distance " << d
<< (distance_list[d + 1] != 0 ? "," : ".") << std::endl;
std::cout << "So the diameter is " << k - 1
<< ", and the girth is " << girth
<< "." << std::endl;
} // end while
std::cout << "So the diameter is " << k - 1 << ", and the girth is "
<< girth << "." << std::endl;
} // end while
return 0;
return 0;
}

View File

@@ -1,5 +1,5 @@
//=======================================================================
// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee,
// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee,
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
@@ -10,95 +10,89 @@
using namespace boost;
template < typename Graph > void
generic_foo(Graph & g)
template < typename Graph > void generic_foo(Graph& g)
{
// Access descriptor types
typedef typename graph_traits < Graph >::vertex_descriptor Vertex;
typedef typename graph_traits < Graph >::edge_descriptor Edge;
// Access category types
typedef typename graph_traits < Graph >::directed_category Dir;
typedef typename graph_traits < Graph >::edge_parallel_category Par;
// Access iterator types...
// Access size types...
// Now do something useful...
// Access descriptor types
typedef typename graph_traits< Graph >::vertex_descriptor Vertex;
typedef typename graph_traits< Graph >::edge_descriptor Edge;
// Access category types
typedef typename graph_traits< Graph >::directed_category Dir;
typedef typename graph_traits< Graph >::edge_parallel_category Par;
// Access iterator types...
// Access size types...
// Now do something useful...
}
template < typename Graph > void
generic_bar(Graph & g)
template < typename Graph > void generic_bar(Graph& g)
{
// Declare some vertex and edge descriptor variables
typename graph_traits < Graph >::vertex_descriptor u = vertex(0,g), v = vertex(1,g);
typename graph_traits < Graph >::edge_descriptor e1, e2;
// Set u and e1 to valid descriptors...
v = u; // Make v a handle to the same vertex as u.
e2 = e1; // Make e2 a handle to the same edge as e1.
assert(u == v); // Do u and v identify the same vertex? Yes
assert(!(u != v)); // Do u and v identify different vertices? No
assert(e1 == e2); // Do e1 and e2 identify the same edge? Yes
assert(!(e1 != e2)); // Do e1 and e2 identify different edges? No
// Declare some vertex and edge descriptor variables
typename graph_traits< Graph >::vertex_descriptor u = vertex(0, g),
v = vertex(1, g);
typename graph_traits< Graph >::edge_descriptor e1, e2;
// Set u and e1 to valid descriptors...
v = u; // Make v a handle to the same vertex as u.
e2 = e1; // Make e2 a handle to the same edge as e1.
assert(u == v); // Do u and v identify the same vertex? Yes
assert(!(u != v)); // Do u and v identify different vertices? No
assert(e1 == e2); // Do e1 and e2 identify the same edge? Yes
assert(!(e1 != e2)); // Do e1 and e2 identify different edges? No
}
// This version of foo gets called when g is directed
template < typename Graph > void
foo_dispatch(Graph & g, boost::directed_tag)
template < typename Graph > void foo_dispatch(Graph& g, boost::directed_tag)
{
//...
//...
}
// This version of foo gets called when g is undirected
template < typename Graph > void
foo_dispatch(Graph & g, boost::undirected_tag)
template < typename Graph > void foo_dispatch(Graph& g, boost::undirected_tag)
{
//...
//...
}
template < typename Graph > void
foo(Graph & g)
template < typename Graph > void foo(Graph& g)
{
typedef typename boost::graph_traits < Graph >::directed_category Cat;
foo_dispatch(g, Cat());
typedef typename boost::graph_traits< Graph >::directed_category Cat;
foo_dispatch(g, Cat());
}
template < typename Digraph > void
foo(Digraph & digraph,
typename graph_traits < Digraph >::vertex_descriptor u,
typename graph_traits < Digraph >::vertex_descriptor v)
template < typename Digraph >
void foo(Digraph& digraph,
typename graph_traits< Digraph >::vertex_descriptor u,
typename graph_traits< Digraph >::vertex_descriptor v)
{
typedef typename graph_traits < Digraph >::edge_descriptor edge_t;
std::pair<edge_t, bool> e1, e2;
e1 = edge(u, v, digraph);
e2 = edge(v, u, digraph);
assert(e1.first != e2.first);
typedef typename graph_traits< Digraph >::edge_descriptor edge_t;
std::pair< edge_t, bool > e1, e2;
e1 = edge(u, v, digraph);
e2 = edge(v, u, digraph);
assert(e1.first != e2.first);
}
template < typename Undigraph > void
bar(Undigraph & undigraph,
typename graph_traits < Undigraph >::vertex_descriptor u,
typename graph_traits < Undigraph >::vertex_descriptor v)
template < typename Undigraph >
void bar(Undigraph& undigraph,
typename graph_traits< Undigraph >::vertex_descriptor u,
typename graph_traits< Undigraph >::vertex_descriptor v)
{
typedef typename graph_traits < Undigraph >::edge_descriptor edge_t;
std::pair<edge_t, bool> e1, e2;
e1 = edge(u, v, undigraph);
e2 = edge(v, u, undigraph);
assert(e1.first == e2.first);
typedef typename graph_traits< Undigraph >::edge_descriptor edge_t;
std::pair< edge_t, bool > e1, e2;
e1 = edge(u, v, undigraph);
e2 = edge(v, u, undigraph);
assert(e1.first == e2.first);
}
int
main()
int main()
{
boost::adjacency_list < vecS, vecS, directedS > g(2);
add_edge(0, 1, g);
add_edge(1, 0, g);
generic_foo(g);
generic_bar(g);
foo(g);
foo(g, vertex(0, g), vertex(1, g));
boost::adjacency_list< vecS, vecS, directedS > g(2);
add_edge(0, 1, g);
add_edge(1, 0, g);
generic_foo(g);
generic_bar(g);
foo(g);
foo(g, vertex(0, g), vertex(1, g));
boost::adjacency_list < vecS, vecS, undirectedS > ug(2);
add_edge(0, 1, g);
bar(ug, vertex(0, g), vertex(1, g));
boost::adjacency_list< vecS, vecS, undirectedS > ug(2);
add_edge(0, 1, g);
bar(ug, vertex(0, g), vertex(1, g));
return 0;
return 0;
}

View File

@@ -1,5 +1,5 @@
//=======================================================================
// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee,
// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee,
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
@@ -12,23 +12,23 @@
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/property_iter_range.hpp>
int
main()
int main()
{
using namespace boost;
typedef adjacency_list < listS, vecS, directedS,
property < vertex_name_t, std::string > >graph_t;
graph_t g(3);
using namespace boost;
typedef adjacency_list< listS, vecS, directedS,
property< vertex_name_t, std::string > >
graph_t;
graph_t g(3);
const char *vertex_names[] = { "Kubrick", "Clark", "Hal" };
int i = 0;
graph_property_iter_range < graph_t, vertex_name_t >::iterator v, v_end;
for (boost::tie(v, v_end) = get_property_iter_range(g, vertex_name);
v != v_end; ++v, ++i)
*v = vertex_names[i];
const char* vertex_names[] = { "Kubrick", "Clark", "Hal" };
int i = 0;
graph_property_iter_range< graph_t, vertex_name_t >::iterator v, v_end;
for (boost::tie(v, v_end) = get_property_iter_range(g, vertex_name);
v != v_end; ++v, ++i)
*v = vertex_names[i];
boost::tie(v, v_end) = get_property_iter_range(g, vertex_name);
std::copy(v, v_end, std::ostream_iterator < std::string > (std::cout, " "));
std::cout << std::endl;
return 0;
boost::tie(v, v_end) = get_property_iter_range(g, vertex_name);
std::copy(v, v_end, std::ostream_iterator< std::string >(std::cout, " "));
std::cout << std::endl;
return 0;
}

View File

@@ -9,8 +9,6 @@
// Author: Ronald Garcia
#include <boost/graph/graphviz.hpp>
#include <boost/graph/adjacency_list.hpp>
#include <boost/foreach.hpp>
@@ -20,61 +18,64 @@
using namespace boost;
using namespace std;
//
// Create a custom graph properties
// (see the documentation for adjacency list)
struct graph_identifier_t { typedef graph_property_tag kind; };
struct vertex_label_t { typedef vertex_property_tag kind; };
struct graph_identifier_t
{
typedef graph_property_tag kind;
};
struct vertex_label_t
{
typedef vertex_property_tag kind;
};
int main() {
int main()
{
// Vertex properties
typedef property < vertex_name_t, string,
property < vertex_label_t, string,
property < vertex_root_t, int > > > vertex_p;
// Edge properties
typedef property < edge_name_t, string > edge_p;
// Graph properties
typedef property < graph_name_t, string,
property < graph_identifier_t, string > > graph_p;
// adjacency_list-based type
typedef adjacency_list < vecS, vecS, directedS,
vertex_p, edge_p, graph_p > graph_t;
// Vertex properties
typedef property< vertex_name_t, string,
property< vertex_label_t, string, property< vertex_root_t, int > > >
vertex_p;
// Edge properties
typedef property< edge_name_t, string > edge_p;
// Graph properties
typedef property< graph_name_t, string,
property< graph_identifier_t, string > >
graph_p;
// adjacency_list-based type
typedef adjacency_list< vecS, vecS, directedS, vertex_p, edge_p, graph_p >
graph_t;
// Construct an empty graph and prepare the dynamic_property_maps.
graph_t graph(0);
dynamic_properties dp;
// Construct an empty graph and prepare the dynamic_property_maps.
graph_t graph(0);
dynamic_properties dp;
property_map<graph_t, vertex_name_t>::type vname =
get(vertex_name, graph);
dp.property("node_id",vname);
property_map< graph_t, vertex_name_t >::type vname
= get(vertex_name, graph);
dp.property("node_id", vname);
property_map<graph_t, vertex_label_t>::type vlabel =
get(vertex_label_t(), graph);
dp.property("label",vlabel);
property_map< graph_t, vertex_label_t >::type vlabel
= get(vertex_label_t(), graph);
dp.property("label", vlabel);
property_map<graph_t, vertex_root_t>::type root =
get(vertex_root, graph);
dp.property("root",root);
property_map< graph_t, vertex_root_t >::type root = get(vertex_root, graph);
dp.property("root", root);
property_map<graph_t, edge_name_t>::type elabel =
get(edge_name, graph);
dp.property("label",elabel);
property_map< graph_t, edge_name_t >::type elabel = get(edge_name, graph);
dp.property("label", elabel);
// Use ref_property_map to turn a graph property into a property map
ref_property_map<graph_t*,string>
gname(get_property(graph,graph_name));
dp.property("name",gname);
// Use ref_property_map to turn a graph property into a property map
ref_property_map< graph_t*, string > gname(get_property(graph, graph_name));
dp.property("name", gname);
// Use ref_property_map to turn a graph property into a property map
ref_property_map<graph_t*,string>
gid(get_property(graph,graph_identifier_t()));
dp.property("identifier",gid);
// Sample graph as an istream;
// Use ref_property_map to turn a graph property into a property map
ref_property_map< graph_t*, string > gid(
get_property(graph, graph_identifier_t()));
dp.property("identifier", gid);
// Sample graph as an istream;
const char* dot =
"digraph \
const char* dot = "digraph \
{ \
graph [name=\"GRAPH\", identifier=\"CX2A1Z\"] \
\
@@ -85,22 +86,23 @@ const char* dot =
b -> c [label=\"EDGE_2\"] \
}";
istringstream gvgraph(dot);
istringstream gvgraph(dot);
bool status = read_graphviz(gvgraph, graph, dp, "node_id");
if (!status)
{
cerr << "read_graphviz() failed." << endl;
return -1;
}
bool status = read_graphviz(gvgraph,graph,dp,"node_id");
if (!status) {
cerr << "read_graphviz() failed." << endl;
return -1;
}
cout << "graph " << get("name", dp, &graph) << " ("
<< get("identifier", dp, &graph) << ")\n\n";
cout << "graph " << get("name",dp,&graph) <<
" (" << get("identifier",dp,&graph) << ")\n\n";
BOOST_FOREACH (graph_t::vertex_descriptor v, vertices(graph))
{
cout << "vertex " << get("node_id", dp, v) << " ("
<< get("label", dp, v) << ")\n";
}
BOOST_FOREACH( graph_t::vertex_descriptor v, vertices(graph) ) {
cout << "vertex " << get("node_id",dp,v) <<
" (" << get("label",dp,v) << ")\n";
}
return 0;
return 0;
}

View File

@@ -17,138 +17,149 @@
using namespace boost;
using namespace std;
typedef property<vertex_color_t, default_color_type,
property<vertex_distance_t,int,
property<vertex_degree_t,int,
property<vertex_in_degree_t, int,
property<vertex_out_degree_t,int> > > > > VertexProperty;
typedef property<edge_weight_t,int> EdgeProperty;
typedef adjacency_list<vecS, vecS, bidirectionalS,
VertexProperty, EdgeProperty> Graph;
typedef property< vertex_color_t, default_color_type,
property< vertex_distance_t, int,
property< vertex_degree_t, int,
property< vertex_in_degree_t, int,
property< vertex_out_degree_t, int > > > > >
VertexProperty;
typedef property< edge_weight_t, int > EdgeProperty;
typedef adjacency_list< vecS, vecS, bidirectionalS, VertexProperty,
EdgeProperty >
Graph;
template <class Graph>
void print(Graph& g) {
typename Graph::vertex_iterator i, end;
typename Graph::out_edge_iterator ei, edge_end;
for(boost::tie(i,end) = vertices(g); i != end; ++i) {
cout << *i << " --> ";
for (boost::tie(ei,edge_end) = out_edges(*i, g); ei != edge_end; ++ei)
cout << target(*ei, g) << " ";
cout << endl;
}
template < class Graph > void print(Graph& g)
{
typename Graph::vertex_iterator i, end;
typename Graph::out_edge_iterator ei, edge_end;
for (boost::tie(i, end) = vertices(g); i != end; ++i)
{
cout << *i << " --> ";
for (boost::tie(ei, edge_end) = out_edges(*i, g); ei != edge_end; ++ei)
cout << target(*ei, g) << " ";
cout << endl;
}
}
std::size_t myrand(std::size_t N) {
std::size_t ret = rand() % N;
// cout << "N = " << N << " rand = " << ret << endl;
return ret;
std::size_t myrand(std::size_t N)
{
std::size_t ret = rand() % N;
// cout << "N = " << N << " rand = " << ret << endl;
return ret;
}
template <class Graph>
bool check_edge(Graph& g, std::size_t a, std::size_t b) {
typename Graph::adjacency_iterator vi, viend, found;
boost::tie(vi, viend) = adjacent_vertices(vertex(a,g), g);
template < class Graph > bool check_edge(Graph& g, std::size_t a, std::size_t b)
{
typename Graph::adjacency_iterator vi, viend, found;
boost::tie(vi, viend) = adjacent_vertices(vertex(a, g), g);
found = find(vi, viend, vertex(b, g));
if ( found == viend )
return false;
found = find(vi, viend, vertex(b, g));
if (found == viend)
return false;
return true;
return true;
}
int main(int, char*[])
{
std::size_t N = 5;
std::size_t N = 5;
Graph g(N);
int i;
Graph g(N);
int i;
bool is_failed = false;
bool is_failed = false;
for (i=0; i<6; ++i) {
std::size_t a = myrand(N), b = myrand(N);
while ( a == b ) b = myrand(N);
cout << "edge edge (" << a << "," << b <<")" << endl;
//add edges
add_edge(a, b, g);
is_failed = is_failed || (! check_edge(g, a, b) );
}
if ( is_failed )
cerr << " Failed."<< endl;
else
cerr << " Passed."<< endl;
print(g);
//remove_edge
for (i = 0; i<2; ++i) {
std::size_t a = myrand(N), b = myrand(N);
while ( a == b ) b = myrand(N);
cout << "remove edge (" << a << "," << b <<")" << endl;
remove_edge(a, b, g);
is_failed = is_failed || check_edge(g, a, b);
}
if ( is_failed )
cerr << " Failed."<< endl;
else
cerr << " Passed."<< endl;
for (i = 0; i < 6; ++i)
{
std::size_t a = myrand(N), b = myrand(N);
while (a == b)
b = myrand(N);
cout << "edge edge (" << a << "," << b << ")" << endl;
// add edges
add_edge(a, b, g);
is_failed = is_failed || (!check_edge(g, a, b));
}
print(g);
//add_vertex
is_failed = false;
std::size_t old_N = N;
std::size_t vid = add_vertex(g);
std::size_t vidp1 = add_vertex(g);
N = num_vertices(g);
if ( (N - 2) != old_N )
cerr << " Failed."<< endl;
else
cerr << " Passed."<< endl;
is_failed = false;
for (i=0; i<2; ++i) {
std::size_t a = myrand(N), b = myrand(N);
while ( a == vid ) a = myrand(N);
while ( b == vidp1 ) b = myrand(N);
cout << "add edge (" << vid << "," << a <<")" << endl;
cout << "add edge (" << vid << "," << vidp1 <<")" << endl;
add_edge(vid, a, g);
add_edge(b, vidp1, g);
is_failed = is_failed || ! check_edge(g, vid, a);
is_failed = is_failed || ! check_edge(g, b, vidp1);
}
if ( is_failed )
cerr << " Failed."<< endl;
else
cerr << " Passed."<< endl;
print(g);
// clear_vertex
std::size_t c = myrand(N);
is_failed = false;
clear_vertex(c, g);
if (is_failed)
cerr << " Failed." << endl;
else
cerr << " Passed." << endl;
if ( out_degree(c, g) != 0 )
is_failed = true;
print(g);
cout << "Removing vertex " << c << endl;
remove_vertex(c, g);
old_N = N;
N = num_vertices(g);
if ( (N + 1) != old_N )
is_failed = true;
if ( is_failed )
cerr << " Failed."<< endl;
else
cerr << " Passed."<< endl;
print(g);
return 0;
// remove_edge
for (i = 0; i < 2; ++i)
{
std::size_t a = myrand(N), b = myrand(N);
while (a == b)
b = myrand(N);
cout << "remove edge (" << a << "," << b << ")" << endl;
remove_edge(a, b, g);
is_failed = is_failed || check_edge(g, a, b);
}
if (is_failed)
cerr << " Failed." << endl;
else
cerr << " Passed." << endl;
print(g);
// add_vertex
is_failed = false;
std::size_t old_N = N;
std::size_t vid = add_vertex(g);
std::size_t vidp1 = add_vertex(g);
N = num_vertices(g);
if ((N - 2) != old_N)
cerr << " Failed." << endl;
else
cerr << " Passed." << endl;
is_failed = false;
for (i = 0; i < 2; ++i)
{
std::size_t a = myrand(N), b = myrand(N);
while (a == vid)
a = myrand(N);
while (b == vidp1)
b = myrand(N);
cout << "add edge (" << vid << "," << a << ")" << endl;
cout << "add edge (" << vid << "," << vidp1 << ")" << endl;
add_edge(vid, a, g);
add_edge(b, vidp1, g);
is_failed = is_failed || !check_edge(g, vid, a);
is_failed = is_failed || !check_edge(g, b, vidp1);
}
if (is_failed)
cerr << " Failed." << endl;
else
cerr << " Passed." << endl;
print(g);
// clear_vertex
std::size_t c = myrand(N);
is_failed = false;
clear_vertex(c, g);
if (out_degree(c, g) != 0)
is_failed = true;
cout << "Removing vertex " << c << endl;
remove_vertex(c, g);
old_N = N;
N = num_vertices(g);
if ((N + 1) != old_N)
is_failed = true;
if (is_failed)
cerr << " Failed." << endl;
else
cerr << " Passed." << endl;
print(g);
return 0;
}

View File

@@ -12,55 +12,54 @@
#include <boost/cstdlib.hpp>
#include <iostream>
class tree_printer {
class tree_printer
{
public:
template <typename Node, typename Tree>
void preorder(Node, Tree&) {
std::cout << "(";
}
template <typename Node, typename Tree>
void inorder(Node n, Tree& t)
{
std::cout << get(boost::vertex_name, t)[n];
}
template <typename Node, typename Tree>
void postorder(Node, Tree&) {
std::cout << ")";
}
template < typename Node, typename Tree > void preorder(Node, Tree&)
{
std::cout << "(";
}
template < typename Node, typename Tree > void inorder(Node n, Tree& t)
{
std::cout << get(boost::vertex_name, t)[n];
}
template < typename Node, typename Tree > void postorder(Node, Tree&)
{
std::cout << ")";
}
};
int main()
{
using namespace boost;
typedef adjacency_list<vecS, vecS, directedS,
property<vertex_name_t, std::string> > graph_t;
typedef graph_traits<graph_t>::vertex_descriptor vertex_t;
using namespace boost;
typedef adjacency_list< vecS, vecS, directedS,
property< vertex_name_t, std::string > >
graph_t;
typedef graph_traits< graph_t >::vertex_descriptor vertex_t;
graph_t g;
graph_t g;
vertex_t a = add_vertex(g),
b = add_vertex(g),
c = add_vertex(g);
vertex_t a = add_vertex(g), b = add_vertex(g), c = add_vertex(g);
add_edge(a, b, g);
add_edge(a, c, g);
typedef property_map<graph_t, vertex_name_t>::type vertex_name_map_t;
vertex_name_map_t name = get(vertex_name, g);
name[a] = "A";
name[b] = "B";
name[c] = "C";
add_edge(a, b, g);
add_edge(a, c, g);
typedef iterator_property_map<std::vector<vertex_t>::iterator,
property_map<graph_t, vertex_index_t>::type> parent_map_t;
std::vector<vertex_t> parent(num_vertices(g));
typedef graph_as_tree<graph_t, parent_map_t> tree_t;
tree_t t(g, a, make_iterator_property_map(parent.begin(),
get(vertex_index, g)));
typedef property_map< graph_t, vertex_name_t >::type vertex_name_map_t;
vertex_name_map_t name = get(vertex_name, g);
name[a] = "A";
name[b] = "B";
name[c] = "C";
tree_printer vis;
traverse_tree(a, t, vis);
return exit_success;
typedef iterator_property_map< std::vector< vertex_t >::iterator,
property_map< graph_t, vertex_index_t >::type >
parent_map_t;
std::vector< vertex_t > parent(num_vertices(g));
typedef graph_as_tree< graph_t, parent_map_t > tree_t;
tree_t t(
g, a, make_iterator_property_map(parent.begin(), get(vertex_index, g)));
tree_printer vis;
traverse_tree(a, t, vis);
return exit_success;
}

View File

@@ -1,4 +1,4 @@
// (C) Copyright Jeremy Siek 2004
// (C) Copyright Jeremy Siek 2004
// 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)
@@ -9,27 +9,26 @@
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/subgraph.hpp>
int
main()
int main()
{
using namespace boost;
using std::string;
using namespace boost;
using std::string;
typedef adjacency_list<vecS, vecS, directedS,no_property,
property<edge_index_t, int>,
property<graph_name_t, string> > graph_t;
typedef adjacency_list< vecS, vecS, directedS, no_property,
property< edge_index_t, int >, property< graph_name_t, string > >
graph_t;
graph_t g;
get_property(g, graph_name) = "graph";
graph_t g;
get_property(g, graph_name) = "graph";
std::cout << "name: " << get_property(g, graph_name) << std::endl;
std::cout << "name: " << get_property(g, graph_name) << std::endl;
typedef subgraph<graph_t> subgraph_t;
typedef subgraph< graph_t > subgraph_t;
subgraph_t sg;
get_property(sg, graph_name) = "subgraph";
subgraph_t sg;
get_property(sg, graph_name) = "subgraph";
std::cout << "name: " << get_property(sg, graph_name) << std::endl;
return exit_success;
std::cout << "name: " << get_property(sg, graph_name) << std::endl;
return exit_success;
}

Some files were not shown because too many files have changed in this diff Show More