graph/example/kevin_bacon.cpp
2000-12-09 19:22:30 +00:00

140 lines
4.4 KiB
C++

//=======================================================================
// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
//
// This file is part of the Boost Graph Library
//
// You should have received a copy of the License Agreement for the
// Boost Graph Library along with the software; see the file LICENSE.
// If not, contact Office of Research, University of Notre Dame, Notre
// Dame, IN 46556.
//
// Permission to modify the code and to distribute modified code is
// granted, provided the text of this NOTICE is retained, a notice that
// the code was modified is included with the above COPYRIGHT NOTICE and
// with the COPYRIGHT NOTICE in the LICENSE file, and that the LICENSE
// file is distributed with the modified code.
//
// LICENSOR MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED.
// By way of example, but not limitation, Licensor MAKES NO
// REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY
// PARTICULAR PURPOSE OR THAT THE USE OF THE LICENSED SOFTWARE COMPONENTS
// OR DOCUMENTATION WILL NOT INFRINGE ANY PATENTS, COPYRIGHTS, TRADEMARKS
// OR OTHER RIGHTS.
//=======================================================================
#include <boost/config.hpp>
#include <iostream>
#include <fstream>
#include <string>
#include <boost/pending/stringtok.hpp>
#include <boost/utility.hpp>
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/visitors.hpp>
#include <boost/graph/dijkstra_shortest_paths.hpp>
#include <map>
int
main()
{
using namespace boost;
using namespace std;
using boost::stringtok;
using boost::tie;
ifstream datafile("./kevin_bacon.dat");
if (!datafile) {
cerr << "No ./kevin_bacon.dat file" << endl;
return -1;
}
typedef adjacency_list<vecS, vecS, undirectedS,
property<vertex_name_t, string>,
property<edge_name_t, string, property<edge_weight_t, int> >
> Graph;
typedef graph_traits<Graph>::vertex_descriptor Vertex;
typedef graph_traits<Graph>::edge_descriptor Edge;
typedef map<string, Vertex> NameVertexMap;
NameVertexMap actors;
Graph g;
property_map<Graph, vertex_name_t>::type actor_name = get(vertex_name, g);
property_map<Graph, vertex_index_t>::type vertex_id = get(vertex_index, g);
property_map<Graph, edge_name_t>::type connecting_movie = get(edge_name, g);
property_map<Graph, edge_weight_t>::type weight = get(edge_weight, g);
string line;
while (getline(datafile,line)) {
list<string> line_toks;
stringtok(line_toks, line, "|");
NameVertexMap::iterator pos;
bool inserted;
Vertex u, v;
list<string>::iterator i = line_toks.begin();
tie(pos, inserted) = actors.insert(make_pair(*i, Vertex()));
if (inserted) {
u = add_vertex(g);
put(actor_name, u, *i);
pos->second = u;
} else
u = pos->second;
++i;
string movie_name = *i++;
tie(pos, inserted) = actors.insert(make_pair(*i, Vertex()));
if (inserted) {
v = add_vertex(g);
put(actor_name, v, *i);
pos->second = v;
} else
v = pos->second;
Edge e;
tie(e, inserted) = add_edge(u, v, g);
if (inserted) {
put(connecting_movie, e, movie_name);
put(weight, e, 1);
}
}
{
graph_traits<Graph>::edge_iterator i, end;
for (tie(i, end) = edges(g); i != end; ++i)
cout << get(actor_name, source(*i, g)) << " was in "
<< get(connecting_movie, *i) << " with "
<< get(actor_name, target(*i, g)) << endl;
}
{
// Use Dijkstra's shortest paths algorithm to calculate the Bacon
// numbers of all the actors in our graph.
std::vector<int> bacon_number( num_vertices(g) );
std::vector<default_color_type> color( num_vertices(g) );
std::vector<Vertex> predecessor( num_vertices(g) );
Vertex src = actors["Kevin Bacon"];
dijkstra_shortest_paths
(g, src, &bacon_number[0], get(edge_weight, g),
&color[0], get(vertex_index, g),
make_ucs_visitor(record_predecessors(&predecessor[0],
on_edge_relaxed())));
graph_traits<Graph>::vertex_iterator i, end;
for (tie(i, end) = vertices(g); i != end; ++i)
cout << get(actor_name, *i) << "'s bacon number is "
<< bacon_number[get(vertex_id, *i)] << endl;
// use the predecessors to determine shortest paths to kevin...
}
return 0;
}