Bundled Properties
The recommended way to attach data to vertices and edges.
Define your structs
struct City {
std::string name;
};
struct Road {
double km;
};
using Graph = adjacency_list<vecS, vecS, directedS, City, Road>;
The third and fourth template parameters of adjacency_list are the vertex
and edge bundles. Every vertex now carries a City and every edge carries a
Road.
Access the data
Direct access on a single vertex or edge:
g[v].name = "Paris";
auto e = add_edge(0, 1, Road{460}, g).first;
std::cout << g[e].km;
Property map for use with algorithms:
auto weight_map = get(&Road::km, g); // property map over all edges
double w = get(weight_map, e); // read one edge
Pass a bundled property map to an algorithm
Algorithms accept bundled property maps the same way they accept any other property map. Here is Dijkstra with a bundled edge weight, using the positional overload:
auto weight_map = get(&Road::km, g);
std::vector<Vertex> pred(num_vertices(g));
std::vector<double> dist(num_vertices(g));
auto pred_map = make_iterator_property_map(pred.begin(), get(vertex_index, g));
auto dist_map = make_iterator_property_map(dist.begin(), get(vertex_index, g));
dijkstra_shortest_paths(g, source,
pred_map,
dist_map,
weight_map,
get(vertex_index, g),
std::less<double>(),
std::plus<double>(),
(std::numeric_limits<double>::max)(),
double(0),
make_dijkstra_visitor(null_visitor()));
Complete example
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/dijkstra_shortest_paths.hpp>
#include <boost/property_map/property_map.hpp>
#include <iostream>
#include <limits>
#include <string>
#include <vector>
struct City {
std::string name;
};
struct Road {
double km;
};
using namespace boost;
using Graph = adjacency_list<vecS, vecS, directedS, City, Road>;
using Vertex = graph_traits<Graph>::vertex_descriptor;
int main() {
// Build a small graph with bundled properties
Graph g(4);
g[0].name = "Paris";
g[1].name = "Lyon";
g[2].name = "Marseille";
g[3].name = "Nice";
add_edge(0, 1, Road{460}, g);
add_edge(1, 2, Road{310}, g);
add_edge(0, 2, Road{775}, g);
add_edge(2, 3, Road{200}, g);
// Direct access via operator[]
std::cout << "Source city: " << g[0].name << "\n";
// Property map access via get(&Struct::member, g)
auto weight_map = get(&Road::km, g);
// Prepare predecessor and distance maps
std::vector<Vertex> pred(num_vertices(g));
std::vector<double> dist(num_vertices(g));
auto pred_map = make_iterator_property_map(pred.begin(), get(vertex_index, g));
auto dist_map = make_iterator_property_map(dist.begin(), get(vertex_index, g));
// Run Dijkstra using the positional overload with bundled weight map
Vertex source = 0;
dijkstra_shortest_paths(g, source,
pred_map,
dist_map,
weight_map,
get(vertex_index, g),
std::less<double>(),
std::plus<double>(),
(std::numeric_limits<double>::max)(),
double(0),
make_dijkstra_visitor(null_visitor()));
// Print shortest distances from source
std::cout << "Shortest distances from " << g[source].name << ":\n";
for (auto v : make_iterator_range(vertices(g))) {
std::cout << " " << g[v].name << ": " << dist[v] << " km\n";
}
}
Source city: Paris
Shortest distances from Paris:
Paris: 0 km
Lyon: 460 km
Marseille: 770 km
Nice: 970 km
Graph-level bundles
The sixth template parameter of adjacency_list attaches a bundle to the graph
object itself (not to any vertex or edge). Access it with graph_bundle:
struct Country {
std::string name;
bool use_metric;
};
using Map = adjacency_list<listS, vecS, bidirectionalS,
City, Road, Country>;
Map m;
m[graph_bundle].name = "France";
m[graph_bundle].use_metric = true;
| There is currently no support for creating property maps from graph-level bundled properties. |
Type traits
To extract the bundle type from a graph type at compile time:
using VBundle = vertex_bundle_type<Graph>::type; // City
using EBundle = edge_bundle_type<Graph>::type; // Road
If the graph has no vertex bundle, vertex_bundle_type<Graph>::type is
no_vertex_bundle. Same pattern for edges with no_edge_bundle.
You can also access the entire vertex or edge bundle as a property map:
auto city_map = get(vertex_bundle, g); // Lvalue property map over City
auto road_map = get(edge_bundle, g); // Lvalue property map over Road
The return type of get(&Road::km, g) is
property_map<Graph, double Road::*>::type (or const_type for a const graph).