Introduction to Generic ProgrammingThe Design of the Boost Graph Library
Putting the Boost Graph Library to Work
Generic Programming andthe Boost Graph Library
Jeremy Siek
Department of Electrical, Computer, and Energy EngineeringUniversity of Colorado at Boulder
BoostCon 2010
Jeremy Siek Generic Programming and the Boost Graph Library
Introduction to Generic ProgrammingThe Design of the Boost Graph Library
Putting the Boost Graph Library to Work
Outline
Introduction to Generic Programming
The Design of the Boost Graph Library
Putting the Boost Graph Library to Work
Please, stop me and ask questions at any time!
Jeremy Siek Generic Programming and the Boost Graph Library
Introduction to Generic ProgrammingThe Design of the Boost Graph Library
Putting the Boost Graph Library to Work
Generic Programming
I Generic programming is a methodology for developingsoftware libraries that are highly reusable and efficient.
I Main idea: when implementing algorithms, make minimalassumptions about data representations of the inputs.
I e.g. the Standard Template Library
Alexander Stepanov
Algorithms
Data Structures
Iterators
David Musser
Jeremy Siek Generic Programming and the Boost Graph Library
Introduction to Generic ProgrammingThe Design of the Boost Graph Library
Putting the Boost Graph Library to Work
The object-oriented approach
struct vector {void merge(const vector& a, const vector& b) { ... }void reverse() { ... }void sort() { ... }...};struct list {
void merge(const list& a, const list& b) { ... }void reverse() { ... }void sort() { ... }...};
I If we have M algorithms and N data structures, then we haveO(M × N) code to write!
Jeremy Siek Generic Programming and the Boost Graph Library
Introduction to Generic ProgrammingThe Design of the Boost Graph Library
Putting the Boost Graph Library to Work
The generic programming approach
template<class InputIter1, class InputIter2, class OutputIter>OutputIter merge(InputIter1 first1, InputIter1 last1,
InputIter2 first2, InputIter2 last2, OutputIter result);
template<class BidirectionalIter>void reverse(BidirectionalIter first, BidirectionalIter last);
template<class RandomAccessIter>void sort(RandomAccessIter first, RandomAccessIter last);
struct vector {struct iterator;iterator begin();iterator end();};
struct list {struct iterator;iterator begin();iterator end();};
I We write O(M + N) code, leaving more time for skiing!
Jeremy Siek Generic Programming and the Boost Graph Library
Introduction to Generic ProgrammingThe Design of the Boost Graph Library
Putting the Boost Graph Library to Work
Efficiency
I Function templates are just as efficient as normal functions.
I The compiler stamps out specialized versions of the template.
template<class T>const T& min(const T& x,
const T& y){ return y < x ? y : x; }
min(1, 2);min(1.0, 2.0);
=⇒
const int& min(const int& x,const int& y)
{ return y < x ? y : x; }
const float& min(const float& x,const float& y)
{ return y < x ? y : x; }
I The cost: longer compile times.
Jeremy Siek Generic Programming and the Boost Graph Library
Introduction to Generic ProgrammingThe Design of the Boost Graph Library
Putting the Boost Graph Library to Work
Templates and Type Requirements
I Which types can be used with a given template?
1 int main() {2 vector<int> v;3 sort(v.begin(), v.end()); // ok45 list<int> l;6 sort(l.begin(), l.end()); // error!7 }
stl algo.h: In function ’void std::sort( RandomAccessIterator,RandomAccessIterator)
[with RandomAccessIterator = std:: List iterator<int>]’:sort−error.cpp:6: instantiated from herestl algo.h:2570: error: no match for ’operator−’ in ’ last − first’
Jeremy Siek Generic Programming and the Boost Graph Library
Introduction to Generic ProgrammingThe Design of the Boost Graph Library
Putting the Boost Graph Library to Work
Type Requirements and Concepts
I The requirements of a template are expressed in terms of“concepts”.
I A concept is set of requirements.
I When a particular type satisfies the requirements of aconcept, we say that the type models the concept.(Think “implements”.)
template <class Iter>void sort(Iter first, Iter last);
Requirements on types:
I Iter is a model of Random Access Iterator.
I Iter’s value type is a model of Less Than Comparable.
Jeremy Siek Generic Programming and the Boost Graph Library
Introduction to Generic ProgrammingThe Design of the Boost Graph Library
Putting the Boost Graph Library to Work
Concepts
concept Random Access Iterator
A Random Access Iterator is an iterator that provides both increment and
decrement (just like a Bidirectional Iterator), and that also can move forward
and backward in arbitrary-sized steps in constant-time.
Refinement of Bidirectional Iterator and Less Than Comparable
Valid expressions:
Expression Return type
i += n X&i + n X&i -= n X&i - n Xi[n] Convertible to value typei[n] = t Convertible to value type
Jeremy Siek Generic Programming and the Boost Graph Library
Introduction to Generic ProgrammingThe Design of the Boost Graph Library
Putting the Boost Graph Library to Work
Concepts
In general, a concept may include the following kinds ofrequirements:
I valid expressions
I associated types, and requirements on those associated types
I refinements
I efficiency guarantees for operations
I semantic requirements for operations (pre andpost-conditions, invariants, etc.)
Jeremy Siek Generic Programming and the Boost Graph Library
Introduction to Generic ProgrammingThe Design of the Boost Graph Library
Putting the Boost Graph Library to Work
Concepts and Models
I vector<int>::iterator is a model of Random Access Iterator.
I list<int>::iterator is not.
1 int main() {2 vector<int> v;3 sort(v.begin(), v.end()); // ok45 list<int> l;6 sort(l.begin(), l.end()); // error!7 }
Jeremy Siek Generic Programming and the Boost Graph Library
Introduction to Generic ProgrammingThe Design of the Boost Graph Library
Putting the Boost Graph Library to Work
The Iterator Concept Hierarchy
Output IteratorInput Iterator
Forward Iterator
Bidirectional Iterator
Random Access Iterator
I Where do concepts come from?
I Is it better to use few or many requirements in a template?
I When is it time to define a new concept?
Jeremy Siek Generic Programming and the Boost Graph Library
Introduction to Generic ProgrammingThe Design of the Boost Graph Library
Putting the Boost Graph Library to Work
Associated Types
template <class Iter>void sort(Iter first, Iter last);
Requirements on types:
I Iter is a model of Random Access Iterator.
I Iter’s value type is a model of Less Than Comparable.
An associated type is a helper type that is involved in theoperations of a concept.
A model must specify particular types to play the roles of theassociated types in the concept.
Jeremy Siek Generic Programming and the Boost Graph Library
Introduction to Generic ProgrammingThe Design of the Boost Graph Library
Putting the Boost Graph Library to Work
Example of Associated Types
concept Input Iterator
An Input Iterator is an iterator that may be dereferenced to refer to some
object, and that may be incremented to obtain the next iterator in a sequence.
Associated types: value type, difference type
Valid expressions:Expression Return type
*i Convertible to value type
++i X&
template<class T> struct list iterator { // models Input Iteratortypedef T value type;typedef ptrdiff t difference type;T& operator∗() const { return current−>data; }list iterator& operator++() { current = current−>next; return ∗this; }};
Jeremy Siek Generic Programming and the Boost Graph Library
Introduction to Generic ProgrammingThe Design of the Boost Graph Library
Putting the Boost Graph Library to Work
Accessing Associated Types in Templates
template<typename InputIterator1, typename InputIterator2>void iter swap(InputIterator1 a, InputIterator2 b){
typedef typename InputIterator1::value type T;T tmp = ∗a;∗a = ∗b;∗b = tmp;}
I Problem: only class types may have nested typedefs. We’dlike iter swap to also work with built-in types like pointers.
I Solution: add a level of indirection using a traits class.
Jeremy Siek Generic Programming and the Boost Graph Library
Introduction to Generic ProgrammingThe Design of the Boost Graph Library
Putting the Boost Graph Library to Work
Accessing Associated Types in Templates
// ‘‘Default’’ version for class typestemplate<class Iter> struct iterator traits {
typedef typename Iter::value type value type;typedef typename Iter::difference type difference type;};// Partial specialization for pointer types.template<class T> struct iterator traits<T∗> {
typedef T value type;typedef ptrdiff t difference type;};
template<typename InputIterator1, typename InputIterator2>void iter swap(InputIterator1 a, InputIterator2 b) {
typedef typename iterator traits<InputIterator1>::value type T;T tmp = ∗a; ∗a = ∗b; ∗b = tmp;}
Jeremy Siek Generic Programming and the Boost Graph Library
Introduction to Generic ProgrammingThe Design of the Boost Graph Library
Putting the Boost Graph Library to Work
Generic Programming Recap
I Decouple algorithms from data structures using iterators,reducing the amount of code from O(M × N) to O(M + N).
I Create concepts to describe and organize the typerequirements for templates.
I Create traits classes to access the associated types of aconcept.
I A type that satisfies the requirements for a concept is said tomodel the concept.
I Minimize the requirements on a template to maximize thepotential for reuse.
I Any other questions at this point?
Jeremy Siek Generic Programming and the Boost Graph Library
Introduction to Generic ProgrammingThe Design of the Boost Graph Library
Putting the Boost Graph Library to Work
Graphs (aka. Networks)
I An abstraction is a simplified model of some problem thatallows us to focus on the important parts and ignore theirrelevant parts.
I The graph abstraction is commonly used to solve problems inareas such as Internet packet routing, telephone networkdesign, software build systems, molecular biology, and so on.
I A graph is a collection of vertices and edges, where each edgeconnects two vertices. In a directed graph, each edge pointsfrom a source vertex to a target vertex.
Boulder
Vail Aspen
Mary Jane
2 hours
1.5 hours
1.5 hours
2 hours
3 hours
Jeremy Siek Generic Programming and the Boost Graph Library
Introduction to Generic ProgrammingThe Design of the Boost Graph Library
Putting the Boost Graph Library to Work
Graph Data Structures
I Edge list{(Boulder,Vail), (Boulder,Mary Jane), (Vail, Mary Jane), (Vail, Aspen),
(Mary Jane, Aspen) }I Adjacency list
Boulder: {Vail, Mary Jane}Vail: {Boulder, Mary Jane, Aspen}Mary Jane: {Boulder, Vail, Aspen}Aspen: {Vail, Mary Jane}
I Adjacency matrixBoulder Vail Mary Jane Aspen
Boulder X XVail X X X
Mary Jane X X XAspen X X
I Nodes with pointers, application specific structures, etc.
Jeremy Siek Generic Programming and the Boost Graph Library
Introduction to Generic ProgrammingThe Design of the Boost Graph Library
Putting the Boost Graph Library to Work
Graph Algorithms
I Problem: how can I find my way out of a maze?
I Solution: depth-first search, that is, mark where you’ve beenand backtrack when you hit a dead end.
I Trivia: what’s the difference between a maze and a labyrinth?
DFS(G ,u)if u is the exit
return Successmark[u]← BLACKfor each v ∈ Adjacent(u)
if mark[v ] = WHITEif DFS(G , v) = Success
return Successreturn Failure
To create a generic implementation,what should the type requirements be?
Jeremy Siek Generic Programming and the Boost Graph Library
Introduction to Generic ProgrammingThe Design of the Boost Graph Library
Putting the Boost Graph Library to Work
Requirements for a generic Depth-First Search
I Need some way to refer to vertices.
I Need to access the vertices adjacent to a given vertex.
I Need to mark a vertex with color (black or white).
I Need a way to carry out custom actions during the search,such as checking for success and terminating.
What concepts should we create/use?What requirements should they include?
Jeremy Siek Generic Programming and the Boost Graph Library
Introduction to Generic ProgrammingThe Design of the Boost Graph Library
Putting the Boost Graph Library to Work
The Adjacency Graph concept
concept Adjacency Graph
The Adjacency Graph concept defines the interface for accessing adjacent
vertices within a graph.
Associated types: vertex descriptor, adjacency iterator
(accessed through graph traits). The adjacency iterator must model
Multi-Pass Input Iterator and its value type must be vertex descriptor.
Valid expressions:Expression Return type
adjacent vertices(v,g) pair<adjacency iterator>
where g is a graph and v is a vertex descriptor.
Jeremy Siek Generic Programming and the Boost Graph Library
Introduction to Generic ProgrammingThe Design of the Boost Graph Library
Putting the Boost Graph Library to Work
Requirements for a generic Depth-First Search
I Need some way to refer to vertices.
I Need to access the vertices adjacent to a given vertex.
I Need to mark a vertex with color (black or white).
I Need a way to carry out custom actions during the search,such as checking for success and terminating.
What concepts should we create/use?What requirements should they include?
Jeremy Siek Generic Programming and the Boost Graph Library
Introduction to Generic ProgrammingThe Design of the Boost Graph Library
Putting the Boost Graph Library to Work
The Property Map concepts
concept Readable Property Map
Refinement of Copy ConstructibleAssociated types: key type, value type, and reference (accessedthrough property traits). reference is convertible to value type.Valid expressions:
Expression Return type
get(pmap, k) reference
concept Writable Property Map
Refinement of Copy ConstructibleAssociated types: same as Readable Property MapValid expressions:
Expression Return type
put(pmap, k, v) void
Jeremy Siek Generic Programming and the Boost Graph Library
Introduction to Generic ProgrammingThe Design of the Boost Graph Library
Putting the Boost Graph Library to Work
Requirements for a generic Depth-First Search
I Need some way to refer to vertices.
I Need to access the vertices adjacent to a given vertex.
I Need to mark a vertex with color (black or white).
I Need a way to carry out custom actions during thesearch, such as checking for success and terminating.
What concepts should we create/use?What requirements should they include?
Jeremy Siek Generic Programming and the Boost Graph Library
Introduction to Generic ProgrammingThe Design of the Boost Graph Library
Putting the Boost Graph Library to Work
Depth-First Search, in Depth
We can extract more information during a depth-first search byusing a more discerning color scheme:
I White for a vertex that is not yet visited.
I Gray for a vertex that has been visited but there are verticesreachable from it that are not yet visited.
I Black for a visited vertex for which all vertices reachable fromit have also been visited.
For example, during the search, if we run into a vertex that isalready gray, then we have detected a cycle.
Jeremy Siek Generic Programming and the Boost Graph Library
Introduction to Generic ProgrammingThe Design of the Boost Graph Library
Putting the Boost Graph Library to Work
Depth-First Search, in Depth
Tree EdgeBack EdgeForward EdgeCross Edge
Jeremy Siek Generic Programming and the Boost Graph Library
Introduction to Generic ProgrammingThe Design of the Boost Graph Library
Putting the Boost Graph Library to Work
The Depth-First Search Visitor Concept
concept DFS Visitor
Valid expressions:Expression When
vis.initialize vertex(v,g) Before starting the search.vis.discover vertex(v,g) First time the vertex is encountered.vis.examine edge(e,g) After the source vertex is discovered but be-
fore the target is.vis.tree edge(e,g) When the edge is added to the DFS-tree.vis.back edge(e,g) When the target vertex is an ancestor of the
source vertex in the DFS-tree.vis.forward or cross edge(e,g) When the source and target are not de-
scended from each other in the DFS-tree.
where g is a graph, v is a vertex descriptor, and e is an
edge descriptor.
Jeremy Siek Generic Programming and the Boost Graph Library
Introduction to Generic ProgrammingThe Design of the Boost Graph Library
Putting the Boost Graph Library to Work
We need access to the out-edges...
concept Incidence Graph
The Incidence Graph concept defines the interface for accessing out-edges of a
vertex within a graph.
Associated types: vertex descriptor, edge descriptor, out edge iterator
(accessed through graph traits). The out edge iterator must model
Multi-Pass Input Iterator and its value type must be edge descriptor.
Valid expressions:Expression Return type
out edges(v,g) pair<out edge iterator>
source(e,g) vertex descriptor
target(e,g) vertex descriptor
where g is a graph, v is a vertex descriptor, and e is anedge descriptor.
Jeremy Siek Generic Programming and the Boost Graph Library
Introduction to Generic ProgrammingThe Design of the Boost Graph Library
Putting the Boost Graph Library to Work
Depth-First Search Function Template
template<class Graph, class Map, class Visitor>void depth first visit(const Graph& G,
typename graph traits<Graph>::vertex descriptor u,Map color,Visitor vis);
Requirements on types:
I Graph is a model of Incidence Graph
I Map is a model of Readable and Writable Property Map.Map’s key type is the Graph’s vertex descriptor and the Map’svalue type is bool.
I Visitor is a model of DFS Visitor. Visitor’s vertex and edgetypes are the same as the Graph’s.
Jeremy Siek Generic Programming and the Boost Graph Library
Introduction to Generic ProgrammingThe Design of the Boost Graph Library
Putting the Boost Graph Library to Work
Quiz Time
I How can you use this generic depth first visit to record a paththat will find the way out of a maze?
I How can you use this generic depth first visit to detect a cyclein the dependencies of a makefile?
Jeremy Siek Generic Programming and the Boost Graph Library
Introduction to Generic ProgrammingThe Design of the Boost Graph Library
Putting the Boost Graph Library to Work
Depth-First Search Function Template
template<class Graph, class Map, class Visitor>void depth first visit(const Graph& G,
typename graph traits<Graph>::vertex descriptor u,Map color, Visitor vis)
{typedef typename graph traits<Graph>::vertex descriptor vertex;typedef typename graph traits<Graph>::edge descriptor edge;put(color, u, gray); vis.discover vertex(u, G);for (edge e : out edges(u, G)) { // new for−loop in C++0x!
vertex v = target(e, G); vis.examine edge(e, G);if (get(color, v) == white) {
vis.tree edge(e, G);depth first visit(G, v, color, vis);} else if (get(color, v) == gray) vis.back edge(e, G);else vis.forward or cross edge(e, G);}put(color, u, black);}
Jeremy Siek Generic Programming and the Boost Graph Library
Introduction to Generic ProgrammingThe Design of the Boost Graph Library
Putting the Boost Graph Library to Work
Algorithms in the Boost Graph Library
I Breadth-First Search
I Shortests Paths: Dijkstra’s, Bellman-Ford, Johnson’sAll-Pairs, Floyd-Warshall All-Pairs
I Minimum Spanning Tree: Kruskal’s, Prim’s
I Connected components, strongly connected components,biconnected components
I Max flow: Edmunds-Karp, Push relabel
I Sparse Matrix Ordering: Cuthill-McKee, King, MinimumDegree
I Topological Sort
I Transitive Closure
I Isomorphism
I ...
Jeremy Siek Generic Programming and the Boost Graph Library
Introduction to Generic ProgrammingThe Design of the Boost Graph Library
Putting the Boost Graph Library to Work
Graph Classes in the Boost Graph Library
Graphs:
I adjacency list: a swiss-army knife providing many variations onthe traditional adjacency list.
I adjacency matrix: the traditional adjacency matrixrepresentation.
Graph Adaptors:
I reverse graph
I filtered graph
I edge list
I Vector as Graph
I Matrix as Graph
I Leda Graph
I Stanford GraphBase
Jeremy Siek Generic Programming and the Boost Graph Library
Introduction to Generic ProgrammingThe Design of the Boost Graph Library
Putting the Boost Graph Library to Work
Scheduling your day with topological sort
pick up kids from school
get cash at ATM
buy groceries (and snacks)
drop off kids at soccer practice
pick up kids from soccer
cook dinner
eat dinner
A topological ordering is a total or-dering on vertices, call it <, suchthat if u → v then u < v .
Jeremy Siek Generic Programming and the Boost Graph Library
Introduction to Generic ProgrammingThe Design of the Boost Graph Library
Putting the Boost Graph Library to Work
Topological Sort
template <typename VertexListGraph, typename OutputIterator,typename P, typename T, typename R>
void topological sort(VertexListGraph& g, OutputIterator result,const bgl named params<P, T, R>& params = /∗all defaults∗/);
Parameters
IN: VertexListGraph& gA directed acylic graph (DAG). The graph type must be amodel of Vertex List Graph. If the graph is not a DAG then anot a dag exception will be thrown and the user should discardthe contents of result range.
OUT: OutputIterator resultThe vertex descriptors of the graph will be output to the resultoutput iterator in reverse topological order. The iterator typemust model Output Iterator.
Jeremy Siek Generic Programming and the Boost Graph Library
Introduction to Generic ProgrammingThe Design of the Boost Graph Library
Putting the Boost Graph Library to Work
Topological Sort (cont’d)
Named Parameters
UTIL/OUT: color map(ColorMap color)This is used to keep track of progress through the graph. The typeColorMap must be a model of Read/Write Property Map and its keytype must be the graph’s vertex descriptor type and the value typeof the color map must model Color Value.Default: an iterator property map created from a std::vector ofdefault color type of size num vertices(g) and using the i map forthe index map.
IN: vertex index map(VertexIndexMap i map)This maps each vertex to an integer in the range [0, n) where n isthe number of vertices in the graph. This parameter is onlynecessary when the default color property map is used. The typeVertexIndexMap must be a model of Readable Property Map. Thevalue type of the map must be an integer type. The vertex descriptortype of the graph needs to be usable as the key type of the map.Default: get(vertex index, g)
Jeremy Siek Generic Programming and the Boost Graph Library
Introduction to Generic ProgrammingThe Design of the Boost Graph Library
Putting the Boost Graph Library to Work
Putting topological sort to work
#include <deque>#include <iostream>#include <boost/graph/topological sort.hpp>#include <boost/graph/adjacency list.hpp>using namespace boost;using namespace std;
int main() {// Create labels for each of the tasks// Create the graph// Perform the topological sort and output the results}
Jeremy Siek Generic Programming and the Boost Graph Library
Introduction to Generic ProgrammingThe Design of the Boost Graph Library
Putting the Boost Graph Library to Work
Create labels for each of the tasks
const char ∗tasks[] = {”pick up kids from school”,”buy groceries (and snacks)”,”get cash at ATM”,”drop off kids at soccer practice”,”cook dinner”,”pick up kids from soccer”,”eat dinner”};const int num tasks = sizeof(tasks) / sizeof(char ∗);
Jeremy Siek Generic Programming and the Boost Graph Library
Introduction to Generic ProgrammingThe Design of the Boost Graph Library
Putting the Boost Graph Library to Work
Create the graph
// Using the adjacency list template with default parametersadjacency list<> g(num tasks);
// Add edges between vertices// With this variant of adjacency list, vertex descriptor == intadd edge(0, 3, g);add edge(1, 3, g); add edge(1, 4, g);add edge(2, 1, g);add edge(3, 5, g);add edge(4, 6, g);add edge(5, 6, g);
Jeremy Siek Generic Programming and the Boost Graph Library
Introduction to Generic ProgrammingThe Design of the Boost Graph Library
Putting the Boost Graph Library to Work
Perform the topological sort and output the results
// The front insertion reverses the reversed ordering// produced by topological sort.deque<int> topo order;topological sort(g, front inserter(topo order));
for (int v : topo order)cout << tasks[v] << endl;
Jeremy Siek Generic Programming and the Boost Graph Library
Introduction to Generic ProgrammingThe Design of the Boost Graph Library
Putting the Boost Graph Library to Work
The topological ordering of your schedule
pick up kids from school
get cash at ATM
buy groceries (and snacks)
drop off kids at soccer practice
pick up kids from soccer
cook dinner
eat dinner
1. get cash at ATM2. buy groceries (and snacks)3. cook dinner4. pick up kids from school5. drop off kids at soccer practice6. pick up kids from soccer7. eat dinner
Jeremy Siek Generic Programming and the Boost Graph Library
Introduction to Generic ProgrammingThe Design of the Boost Graph Library
Putting the Boost Graph Library to Work
Challenge question
I How can you implement topological sort using the genericdepth first search?
I Hint: remember, topological sort computes the reversetopological ordering.
Jeremy Siek Generic Programming and the Boost Graph Library
Introduction to Generic ProgrammingThe Design of the Boost Graph Library
Putting the Boost Graph Library to Work
Topological Sort Implementation using DFS
template <typename OutputIterator>struct topo sort visitor : public dfs visitor<> {
topo sort visitor(OutputIterator iter) : out iter(iter) { }
template <typename Vertex, typename Graph>void finish vertex(const Vertex& u, Graph&) { ∗out iter++ = u; }
OutputIterator out iter;};
template <typename VertexListGraph, typename OutputIterator>void topological sort(VertexListGraph& g, OutputIterator result) {
typedef topo sort visitor<OutputIterator> TopoVisitor;depth first search(g, visitor(TopoVisitor(result)));}
Jeremy Siek Generic Programming and the Boost Graph Library
Introduction to Generic ProgrammingThe Design of the Boost Graph Library
Putting the Boost Graph Library to Work
Six degrees of Kevin Bacon
Steve Martin
Patrick Stewart
Prince of Egypt
Kevin Bacon
Novocaine
Sean Astin
White Water Summer
Elisabeth Shue
Hollow Man
Carrie Fisher
Soapdish
Peter Crumbie
My Dog Skip
Sean ConneryRising Sun
Harrison Ford
Steve AltesHollow Man
Random Hearts
Star Wars
Val Kilmer
The Saint
Marilyn Monroe
Eli Wallach
The MisfitsMystic River
An actor’s Bacon number is the shortest path to Kevin Baconthrough a trail of actors who appear together in the same movie.
Jeremy Siek Generic Programming and the Boost Graph Library
Introduction to Generic ProgrammingThe Design of the Boost Graph Library
Putting the Boost Graph Library to Work
Breadth-First Search
A breadth-first search visits all of the vertices in a graph reachablefrom the starting vertex, with vertices closer to the starting vertexvisited before vertices that are farther away. The BFS-tree givesthe shortest path from the source to every reachable vertex.
0123
Jeremy Siek Generic Programming and the Boost Graph Library
Introduction to Generic ProgrammingThe Design of the Boost Graph Library
Putting the Boost Graph Library to Work
Attaching data to vertices and edges
#include <string>#include <boost/graph/adjacency list.hpp>using namespace std; using namespace boost;
struct actor {string name;};struct movie {
string name;};typedef adjacency list<vecS, vecS, undirectedS, actor, movie> graph;typedef graph traits<graph>::vertex descriptor vertex;typedef graph traits<graph>::edge descriptor edge;
Jeremy Siek Generic Programming and the Boost Graph Library
Introduction to Generic ProgrammingThe Design of the Boost Graph Library
Putting the Boost Graph Library to Work
Enable serialization to and from an archive
#include <string>#include <boost/graph/adjacency list.hpp>using namespace std; using namespace boost;
struct actor {string name;template<class Archive>void serialize(Archive & ar, const unsigned int version){ ar & name; }
};struct movie {
string name;template<class Archive>void serialize(Archive & ar, const unsigned int version){ ar & name; }
};
Jeremy Siek Generic Programming and the Boost Graph Library
Introduction to Generic ProgrammingThe Design of the Boost Graph Library
Putting the Boost Graph Library to Work
The Bacon number program
#include <iostream>#include <fstream>#include <boost/archive/text iarchive.hpp>
int main() {ifstream ifs(”./kevin−bacon.dat”);archive::text iarchive ia(ifs);graph g;ia >> g;vector<int> bnum(num vertices(g));// Find Kevin Bacon and perform breadth−first searchfor (vertex v : vertices(g))
cout<<”bacon number(”<< g[v].name <<”)= ”<< bnum[v] <<”\n”;}
Jeremy Siek Generic Programming and the Boost Graph Library
Introduction to Generic ProgrammingThe Design of the Boost Graph Library
Putting the Boost Graph Library to Work
Find Kevin Bacon and perform breadth-first search
struct bacon number recorder : public default bfs visitor {bacon number recorder(vector<int>& distances) : d(distances) { }void tree edge(edge e, const graph& g) const {
vertex u = source(e, g), v = target(e, g);d[v] = d[u] + 1;}vector<int>& d;};// Find Kevin Bacon, the sourcevertex src;for (v : vertices(g))
if (g[v].name == ”Kevin Bacon”) { src = v; break; }// Perform breadth−first searchbreadth first search(g, src, visitor(bacon number recorder(bnum)));
Jeremy Siek Generic Programming and the Boost Graph Library
Introduction to Generic ProgrammingThe Design of the Boost Graph Library
Putting the Boost Graph Library to Work
Quiz time
I Suppose you want to report the shortest path that links anactor to Kevin Bacon. How can you use breadth first searchto compute this?
Jeremy Siek Generic Programming and the Boost Graph Library
Introduction to Generic ProgrammingThe Design of the Boost Graph Library
Putting the Boost Graph Library to Work
A Knight’s Tour and Implicit Graphs
Can the Knight make a tour around the chess board, touchingeach square exactly once?
Jeremy Siek Generic Programming and the Boost Graph Library
Introduction to Generic ProgrammingThe Design of the Boost Graph Library
Putting the Boost Graph Library to Work
A Knight’s Tour
Find a Hamiltonian path through the Knight’s Graph.
Jeremy Siek Generic Programming and the Boost Graph Library
Introduction to Generic ProgrammingThe Design of the Boost Graph Library
Putting the Boost Graph Library to Work
Hamiltonian Path via Backtracking Search
template<typename Graph, typename TimePropertyMap>bool backtracking search
(Graph& g, typename graph traits<Graph>::vertex descriptor u,TimePropertyMap time stamp, int n) {
put(time stamp, u, n);if (n == num vertices(g) − 1) return true;bool result = false;for (v : adjacent vertices(u, g))
if (get(time stamp, v) == −1) {result = backtracking search(g, v, time stamp, n + 1);if (result == true) break;}
if (result == false)put(time stamp, u, −1);
return result;}
Jeremy Siek Generic Programming and the Boost Graph Library
Introduction to Generic ProgrammingThe Design of the Boost Graph Library
Putting the Boost Graph Library to Work
Brainstorm
I How do we create a Knight’s graph that we can use with thebacktracking search function template?
Jeremy Siek Generic Programming and the Boost Graph Library
Introduction to Generic ProgrammingThe Design of the Boost Graph Library
Putting the Boost Graph Library to Work
Adjacency Iterator for Knight’s Graph
typedef pair<int,int> point;point knight jumps[8] = { point(2, −1), point(1, −2), point(−1, −2),
point(−2, −1), point(−2, 1), point(−1, 2), point(1, 2), point(2, 1) };
struct knight adjacency iterator {knight adjacency iterator(int ii, point p, const knights graph & g)
: m pos(p), m g(&g), m i(ii) { valid position(); }point operator∗() const { return m pos + knight jumps[m i]; }void operator++() { ++m i; valid position(); }bool operator==(const knight adjacency iterator & x) const{ return m i == x.m i; }
protected:point m pos;const knights graph∗ m g;int m i;};
Jeremy Siek Generic Programming and the Boost Graph Library
Introduction to Generic ProgrammingThe Design of the Boost Graph Library
Putting the Boost Graph Library to Work
An Implicit Knight’s Graph
struct knights graph {typedef point vertex descriptor;typedef pair<vertex descriptor> edge descriptor;typedef knight adjacency iterator adjacency iterator;knights graph(int n): m board size(n) { }int m board size;};int num vertices(const knights graph& g){ return g.m board size ∗ g.m board size; }
const pair<knights graph::adjacency iterator>adjacent vertices(knights graph::vertex descriptor v,
const knights graph & g) {typedef knights graph::adjacency iterator Iter;return make pair(Iter(0, v, g), Iter(8, v, g));}
Jeremy Siek Generic Programming and the Boost Graph Library
Introduction to Generic ProgrammingThe Design of the Boost Graph Library
Putting the Boost Graph Library to Work
A property map for recording the time stamps
struct board map {typedef int value type;typedef point key type;typedef read write property map tag category;board map(int n) : m board(new int[n]), m size(n){ fill(m board, m board + n ∗ n, −1); }
int ∗m board;int m size;};int get(const board map& ba, point p) {
return ba.m board[p.first ∗ ba.m size + p.second];}void put(const board map& ba, point p, int v) {
ba.m board[p.first ∗ ba.m size + p.second] = v;}
Jeremy Siek Generic Programming and the Boost Graph Library
Introduction to Generic ProgrammingThe Design of the Boost Graph Library
Putting the Boost Graph Library to Work
Searching for a Knight’s Tour
const int N = 8;knights graph g(N);board map chessboard(N);
bool ret = backtracking search(g, point(0, 0), chessboard, 0);
for (int i = 0; i < N; ++i) {for (int j = 0; j < N; ++j)
cout << get(chessboard, point(i, j)) << ”\t”;cout << endl;}
Jeremy Siek Generic Programming and the Boost Graph Library
Introduction to Generic ProgrammingThe Design of the Boost Graph Library
Putting the Boost Graph Library to Work
A Knight’s Tour
0 23 8 61 38 25 44 599 62 1 24 43 60 37 2622 7 10 39 20 41 58 4563 2 21 42 57 46 27 366 11 4 19 40 35 56 473 16 13 30 49 28 53 3412 5 18 15 32 51 48 5517 14 31 50 29 54 33 52
Jeremy Siek Generic Programming and the Boost Graph Library
Introduction to Generic ProgrammingThe Design of the Boost Graph Library
Putting the Boost Graph Library to Work
Conclusion
I Hope you enjoyed this whirlwind tour of the Boost GraphLibrary!
I Generic programming can be applied to many more domainsthan sequences (as in the STL). Let’s do it and create morereusable libraries!
I Generic libraries have a steep learning curve, but don’t giveup! Once you’ve mastered one, it becomes a powerful tool.
I Interested in adding algorithms or data structures to the BGL?Contribute to Boost!
Jeremy Siek Generic Programming and the Boost Graph Library
Top Related