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:
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
207
example/bfs.cpp
207
example/bfs.cpp
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -8,5 +8,5 @@ n 5
|
||||
# the edges
|
||||
e
|
||||
1 2
|
||||
0 1
|
||||
2 0
|
||||
0 1
|
||||
2 0
|
||||
|
||||
299
example/dave.cpp
299
example/dave.cpp
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
123
example/dfs.cpp
123
example/dfs.cpp
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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"]
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"]
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 -->
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user