commit 744512b5dced2f3e162f2ece05fe3bc4a6b30454 Author: Jeremy Siek Date: Mon Sep 18 08:17:56 2000 +0000 example files for boost graph library [SVN r7700] diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 00000000..3e84d7c7 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,96 @@ +* text=auto !eol svneol=native#text/plain +*.gitattributes text svneol=native#text/plain + +# Scriptish formats +*.bat text svneol=native#text/plain +*.bsh text svneol=native#text/x-beanshell +*.cgi text svneol=native#text/plain +*.cmd text svneol=native#text/plain +*.js text svneol=native#text/javascript +*.php text svneol=native#text/x-php +*.pl text svneol=native#text/x-perl +*.pm text svneol=native#text/x-perl +*.py text svneol=native#text/x-python +*.sh eol=lf svneol=LF#text/x-sh +configure eol=lf svneol=LF#text/x-sh + +# Image formats +*.bmp binary svneol=unset#image/bmp +*.gif binary svneol=unset#image/gif +*.ico binary svneol=unset#image/ico +*.jpeg binary svneol=unset#image/jpeg +*.jpg binary svneol=unset#image/jpeg +*.png binary svneol=unset#image/png +*.tif binary svneol=unset#image/tiff +*.tiff binary svneol=unset#image/tiff +*.svg text svneol=native#image/svg%2Bxml + +# Data formats +*.pdf binary svneol=unset#application/pdf +*.avi binary svneol=unset#video/avi +*.doc binary svneol=unset#application/msword +*.dsp text svneol=crlf#text/plain +*.dsw text svneol=crlf#text/plain +*.eps binary svneol=unset#application/postscript +*.gz binary svneol=unset#application/gzip +*.mov binary svneol=unset#video/quicktime +*.mp3 binary svneol=unset#audio/mpeg +*.ppt binary svneol=unset#application/vnd.ms-powerpoint +*.ps binary svneol=unset#application/postscript +*.psd binary svneol=unset#application/photoshop +*.rdf binary svneol=unset#text/rdf +*.rss text svneol=unset#text/xml +*.rtf binary svneol=unset#text/rtf +*.sln text svneol=native#text/plain +*.swf binary svneol=unset#application/x-shockwave-flash +*.tgz binary svneol=unset#application/gzip +*.vcproj text svneol=native#text/xml +*.vcxproj text svneol=native#text/xml +*.vsprops text svneol=native#text/xml +*.wav binary svneol=unset#audio/wav +*.xls binary svneol=unset#application/vnd.ms-excel +*.zip binary svneol=unset#application/zip + +# Text formats +.htaccess text svneol=native#text/plain +*.bbk text svneol=native#text/xml +*.cmake text svneol=native#text/plain +*.css text svneol=native#text/css +*.dtd text svneol=native#text/xml +*.htm text svneol=native#text/html +*.html text svneol=native#text/html +*.ini text svneol=native#text/plain +*.log text svneol=native#text/plain +*.mak text svneol=native#text/plain +*.qbk text svneol=native#text/plain +*.rst text svneol=native#text/plain +*.sql text svneol=native#text/x-sql +*.txt text svneol=native#text/plain +*.xhtml text svneol=native#text/xhtml%2Bxml +*.xml text svneol=native#text/xml +*.xsd text svneol=native#text/xml +*.xsl text svneol=native#text/xml +*.xslt text svneol=native#text/xml +*.xul text svneol=native#text/xul +*.yml text svneol=native#text/plain +boost-no-inspect text svneol=native#text/plain +CHANGES text svneol=native#text/plain +COPYING text svneol=native#text/plain +INSTALL text svneol=native#text/plain +Jamfile text svneol=native#text/plain +Jamroot text svneol=native#text/plain +Jamfile.v2 text svneol=native#text/plain +Jamrules text svneol=native#text/plain +Makefile* text svneol=native#text/plain +README text svneol=native#text/plain +TODO text svneol=native#text/plain + +# Code formats +*.c text svneol=native#text/plain +*.cpp text svneol=native#text/plain +*.h text svneol=native#text/plain +*.hpp text svneol=native#text/plain +*.ipp text svneol=native#text/plain +*.tpp text svneol=native#text/plain +*.jam text svneol=native#text/plain +*.java text svneol=native#text/plain diff --git a/examples/LEDA_concept_check.cpp b/examples/LEDA_concept_check.cpp new file mode 100644 index 00000000..b7e7d71e --- /dev/null +++ b/examples/LEDA_concept_check.cpp @@ -0,0 +1,40 @@ +//======================================================================= +// 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 +#include + + +int +main(int,char*[]) +{ + using namespace boost; + { + typedef GRAPH Graph; + REQUIRE(Graph, VertexListGraph); + REQUIRE(Graph, BidirectionalGraph); + REQUIRE(Graph, MutableGraph); + } + return 0; +} diff --git a/examples/adjacency_list.cpp b/examples/adjacency_list.cpp new file mode 100644 index 00000000..9d0b720f --- /dev/null +++ b/examples/adjacency_list.cpp @@ -0,0 +1,111 @@ +//======================================================================= +// 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 +#include +#include +#include + +#include +#include + +/* + 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) + + 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) + + */ + +int main(int argc, char* argv[]) +{ + using namespace boost; + using namespace std; + + typedef plugin EdgePlugin; + typedef plugin ColorPlugin; + typedef plugin VertexPlugin; + typedef plugin GraphPlugin; + + typedef adjacency_list Graph; + + const int V = 5; + Graph g(V, GraphPlugin("foo")); + cout << "graph name: " << get_plugin(g, name_tag()) << endl; + vertex_property_accessor::type id + = get_vertex_property_accessor(g, id_tag()); + + edge_property_accessor::type name + = get_edge_property_accessor(g, name_tag()); + + boost::graph_traits::vertex_iterator vi, viend; + int vnum = 0; + + for (boost::tie(vi,viend) = vertices(g); vi != viend; ++vi) + id[*vi] = vnum++; + + add_edge(g, vertex(0,g), vertex(1,g), EdgePlugin("joe")); + add_edge(g, vertex(1,g), vertex(2,g), EdgePlugin("curly")); + add_edge(g, vertex(1,g), vertex(3,g), EdgePlugin("dick")); + add_edge(g, vertex(2,g), vertex(4,g), EdgePlugin("tom")); + add_edge(g, vertex(3,g), vertex(4,g), EdgePlugin("harry")); + + Graph::vertex_iterator i, end; + 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); + + cout << endl << "removing edge (1,3): " << endl; + remove_edge(g, vertex(1,g), vertex(3,g)); + + 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; +} diff --git a/examples/adjacency_list.expected b/examples/adjacency_list.expected new file mode 100644 index 00000000..d7dcbb48 --- /dev/null +++ b/examples/adjacency_list.expected @@ -0,0 +1,15 @@ +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) + +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) diff --git a/examples/bellman_ford.cpp b/examples/bellman_ford.cpp new file mode 100644 index 00000000..d0686b1a --- /dev/null +++ b/examples/bellman_ford.cpp @@ -0,0 +1,95 @@ +//======================================================================= +// 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 +#include +#include +#include +#include +#include +#include +#include + +// +// Example, page 533 CLR +// +// u*===*v +// *|\ ** +// / | \ / | +// z | x | +// \ | / \ | +// **/ *| +// x----*y +// +// (didn't draw the y->z edge) +// +// Sample Output (distance and parent): +// +// u: 2 v +// v: 4 x +// x: 7 z +// y: -2 u +// z: 0 z +// + +int +main(int,char*) +{ + enum { u, v, x, y, z, N }; + char name[] = "uvxyz"; + + typedef std::pair E; + E edges[] = { 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[] = { -4, 8, 5, + -2, + 9, -3, + 7, 2, + 6, 7 }; + + typedef boost::edge_list Graph; + Graph g(edges, edges + sizeof(edges) / sizeof(E)); + + std::vector distance(N, std::numeric_limits::max()); + std::vector parent(N, -1); + + distance[z] = 0; + parent[z] = z; + bool r = boost::bellman_ford_shortest_paths + (g, int(N), weight, distance.begin(), make_bellman_visitor( + record_predecessors(parent.begin(), boost::on_edge_relaxed()))); + + if (r) + for (int i = 0; i < N; ++i) + std::cout << name[i] << ": " << distance[i] + << " " << name[parent[i]] << std::endl; + else + std::cout << "negative cycle" << std::endl; + + return 0; +} diff --git a/examples/bellman_ford.expected b/examples/bellman_ford.expected new file mode 100644 index 00000000..7d388575 --- /dev/null +++ b/examples/bellman_ford.expected @@ -0,0 +1,5 @@ +u: 2 v +v: 4 x +x: 7 z +y: -2 u +z: 0 z diff --git a/examples/bfs.cpp b/examples/bfs.cpp new file mode 100644 index 00000000..759ea7a1 --- /dev/null +++ b/examples/bfs.cpp @@ -0,0 +1,168 @@ +//======================================================================= +// 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 +#include +#include +#include + +#include +#include +#include +#include + +/* + + 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 (plugin) stored internally. + + Two pre-defined visitors are used to record the distance of each + vertex from the source vertex, and also to record the parent of each + vertex. Any number of visitors can be layered and passed to a GGCL + algorithm. + + The call to vertices(G) returns an STL-compatible container which + contains all of the vertices in the graph. In this example we use + the vertices container in the STL for_each() function. + + 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 + parent[0] = 0 + parent[1] = 2 + parent[2] = 0 + parent[3] = 2 + parent[4] = 2 + +*/ + +template +struct print_parent { + print_parent(const ParentDecorator& p_) : p(p_) { } + template + void operator()(const Vertex& v) const { + std::cout << "parent[" << v << "] = " << p[v] << std::endl; + } + ParentDecorator p; +}; + + +template +struct graph_copier + : public boost::base_visitor > +{ + typedef Tag event_filter; + + graph_copier(NewGraph& graph) : new_g(graph) { } + + template + void operator()(Edge e, Graph& g) { + add_edge(new_g, source(e, g), target(e, g)); + } +private: + NewGraph& new_g; +}; + +template +inline graph_copier +copy_graph(NewGraph& g, Tag) { + return graph_copier(g); +} + +int main(int argc, char* argv[]) +{ + typedef boost::adjacency_list< + boost::mapS, boost::vecS, boost::bidirectionalS, + boost::plugin > > > + > Graph; + + Graph G(5); + add_edge(G, 0, 2); + add_edge(G, 1, 1); + add_edge(G, 1, 3); + add_edge(G, 1, 4); + add_edge(G, 2, 1); + add_edge(G, 2, 3); + add_edge(G, 2, 4); + add_edge(G, 3, 1); + add_edge(G, 3, 4); + add_edge(G, 4, 0); + add_edge(G, 4, 1); + + 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 p(num_vertices(G)); + typedef std::vector::iterator 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::vertices_size_type d[5]; + + // The source vertex + Vertex s = *(vertices(G).first); + + boost::breadth_first_search(G, s, + make_bfs_visitor( + std::make_pair(boost::record_distances(d, boost::on_tree_edge()), + std::make_pair(boost::record_predecessors(p.begin(), + boost::on_tree_edge()), + copy_graph(G_copy, boost::on_examine_edge())))) ); + + print_graph(G); + print_graph(G_copy); + + if (num_vertices(G) < 11) { + std::cout << "distances: "; +#ifdef BOOST_OLD_STREAM_ITERATORS + std::copy(d, d + 5, std::ostream_iterator(std::cout, " ")); +#else + std::copy(d, d + 5, std::ostream_iterator(std::cout, " ")); +#endif + std::cout << std::endl; + + for_each(vertices(G).first, vertices(G).second, + print_parent(p.begin())); + } + + return 0; +} diff --git a/examples/bfs_basics.cpp b/examples/bfs_basics.cpp new file mode 100644 index 00000000..74924717 --- /dev/null +++ b/examples/bfs_basics.cpp @@ -0,0 +1,130 @@ +//======================================================================= +// 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 +#include +#include +#include +#include +#include +#include +#include // for iota +#include + +/* + This example records the "discover time" and "finish time" + of each vertex during a breadth-first search. This + gives a little insight into the order in which BFS + traverses a graph. It is instructive to compare + this to the discover and finish time using depth + first search (in dfs_basics.cc). + + Here's the example graph from p. 471 of the CLR: + + r--s t--u + | | /| | + | |/ | | + v w--x--y + + Sample Output: + + order of discovery: s r w v t x u y + order of finish: s r w v t x u y + +*/ + +using namespace std; +using namespace boost; + +int main(int argc, char* argv[]) +{ + // Select the graph type we wish to use + typedef adjacency_list Graph; + // Set up the vertex names + enum { r, s, t, u, v, w, x, y, N }; + char name[] = { 'r', 's', 't', 'u', 'v', 'w', 'x', 'y' }; + int i; + typedef pair E; + // Specify the edges in the graph + 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) }; + const int nedges = sizeof(edge_array) / sizeof(E); + // Create the graph object + Graph G(N, edge_array, edge_array + nedges); + + // Some typedef's to save a little typing + typedef graph_traits::vertex_descriptor Vertex; + typedef graph_traits::vertices_size_type size_type; + + typedef std::vector::iterator Piter; + typedef std::vector::iterator Iiter; + + // color property needed in breadth-first search + std::vector color(num_vertices(G)); + + // discover time property + std::vector dtime(num_vertices(G)); + + // finish time property + std::vector ftime(num_vertices(G)); + + // Call the 4 argument version of BFS. + // There is also a 3 argument version (assume color is in the graph) + // and a 5 argument version (adds an argument for the queue). + int time = 0; + boost::breadth_first_search + (G, vertex(s, G), make_bfs_visitor( + std::make_pair(stamp_times(dtime.begin(), time, on_discover_vertex()), + stamp_times(ftime.begin(), time, on_finish_vertex()))), + color.begin()); + + cout << "order of discovery: "; + + // Perform some STL magic to order the vertices + // according to their discover time + vector discover_order(N); + iota(discover_order.begin(), discover_order.end(), 0); + std::sort(discover_order.begin(), discover_order.end(), + indirect_cmp >(dtime.begin())); + + for (i = 0; i < N; ++i) + cout << name[ discover_order[i] ] << " "; + cout << endl; + + cout << "order of finish: "; + + vector finish_order(N); + iota(finish_order.begin(), finish_order.end(), 0); + std::sort(finish_order.begin(), finish_order.end(), + indirect_cmp >(ftime.begin())); + + for (i = 0; i < N; ++i) + cout << name[ finish_order[i] ] << " "; + cout << endl; + + return 0; +} diff --git a/examples/bfs_basics.expected b/examples/bfs_basics.expected new file mode 100644 index 00000000..6fc6c2db --- /dev/null +++ b/examples/bfs_basics.expected @@ -0,0 +1,2 @@ +order of discovery: s r w v t x u y +order of finish: s r w v t x u y diff --git a/examples/bucket_sorter.cpp b/examples/bucket_sorter.cpp new file mode 100644 index 00000000..e63c9b39 --- /dev/null +++ b/examples/bucket_sorter.cpp @@ -0,0 +1,122 @@ +//======================================================================= +// 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 +#include + +#include +#include + +template +struct trivial_id { + size_t operator[](Integral i) { + return i; + } + size_t operator[](Integral i) const { + return i; + } +}; + + +int main() { + using namespace std; + using boost::bucket_sorter; + + const size_t N = 10; + + vector bucket(N); + for (size_t i=0; i ID; + typedef bucket_sorter::iterator, ID> BS; + BS my_bucket_sorter(N, N, bucket.begin()); + + for (int ii=0; ii +#include +#include +#include + +// +// These concept checks verify that the GGCL classes implement the +// complete interfaces defined in the graph concepts. The concept +// checks are also useful for verifying whether user-defined graph +// classes satisfy the desired graph concepts. Note that these concept +// checks by themselves do not verify whether the classes model the +// concepts, for there are run-time requirements that are not checked +// here. +// + +int +main(int,char*[]) +{ + using namespace boost; + { + typedef adjacency_list, plugin > Graph; + REQUIRE(Graph, VertexAndEdgeListGraph); + REQUIRE(Graph, MutableGraph); + REQUIRE2(Graph, color_tag, VertexPropertyGraph); + REQUIRE2(Graph, weight_tag, EdgePropertyGraph); + // the builtin id property is readable but not writable + typedef vertex_property_accessor::const_type ID_PA; + typedef boost::graph_traits::vertex_descriptor Vertex; + REQUIRE2(ID_PA, Vertex, ReadablePropertyAccessor); + } + { + typedef adjacency_list, + plugin > Graph; + REQUIRE(Graph, VertexAndEdgeListGraph); + REQUIRE(Graph, BidirectionalGraph); + REQUIRE(Graph, MutableGraph); + REQUIRE2(Graph, color_tag, VertexPropertyGraph); + REQUIRE2(Graph, weight_tag, EdgePropertyGraph); + // the builtin id property is readable but not writable + typedef vertex_property_accessor::const_type ID_PA; + typedef boost::graph_traits::vertex_descriptor Vertex; + REQUIRE2(ID_PA, Vertex, ReadablePropertyAccessor); + } + { + typedef adjacency_list< listS, listS, directedS, plugin, + plugin > Graph; + REQUIRE(Graph, VertexAndEdgeListGraph); + REQUIRE(Graph, MutableGraph); + REQUIRE2(Graph, color_tag, VertexPropertyGraph); + REQUIRE2(Graph, weight_tag, EdgePropertyGraph); + } + { + typedef std::pair E; + typedef edge_list EdgeList; + REQUIRE(EdgeList, EdgeListGraph); + } + { // Stanford GraphBase Graph + typedef Graph* Graph; + REQUIRE(Graph, VertexListGraph); + } + return 0; +} diff --git a/examples/concept_checks.expected b/examples/concept_checks.expected new file mode 100644 index 00000000..e69de29b diff --git a/examples/connected_components.cpp b/examples/connected_components.cpp new file mode 100644 index 00000000..67be0df6 --- /dev/null +++ b/examples/connected_components.cpp @@ -0,0 +1,134 @@ +//======================================================================= +// 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 +#include +#include +#include +#include +#include + +/* + + This example demonstrates the usage of the connected_components + algorithm on a directed and undirected graph. The example graphs + come from "Introduction to Algorithms", Cormen, Leiserson, and + Rivest p. 87 (though we number the vertices from zero instead of + one). + + Sample output: + + An undirected graph: + + Total number of components: 3 + Vertex 0 is in component 0 + Vertex 1 is in component 0 + Vertex 2 is in component 1 + Vertex 3 is in component 2 + Vertex 4 is in component 0 + Vertex 5 is in component 1 + + A directed graph: + + Total number of components: 3 + Vertex 0 is in component 2 + Vertex 1 is in component 2 + Vertex 2 is in component 1 + Vertex 3 is in component 2 + Vertex 4 is in component 2 + Vertex 5 is in component 0 + + */ + +using namespace std; + +int main(int argc, char* argv[]) +{ + // First example: the connected components of an undirected graph + using namespace boost; + { + typedef plugin > > VertexPlugin; + typedef adjacency_list Graph; + typedef Graph::vertex_descriptor Vertex; + + const int N = 6; + Graph G(N); + add_edge(G, 0, 1); + add_edge(G, 1, 4); + add_edge(G, 4, 0); + add_edge(G, 2, 5); + + + std::vector c(num_vertices(G)); + int num = connected_components + (G, c.begin(), get_vertex_property_accessor(G,color_tag()), + dfs_visitor<>()); + + cout << "An undirected graph:" << endl; + cout << endl; + std::vector::iterator i; + cout << "Total number of components: " << num << endl; + for (i = c.begin(); i != c.end(); ++i) + cout << "Vertex " << i - c.begin() <<" is in component " << *i << endl; + cout << endl; + } + // Second example: the strongly connected components of a directed + // graph + { + typedef plugin > > VertexPlugin; + typedef adjacency_list< vecS, vecS, directedS, VertexPlugin > Graph; + const int N = 6; + Graph G(N); + add_edge(G, 0, 1); + add_edge(G, 1, 1); + add_edge(G, 1, 3); + add_edge(G, 1, 4); + add_edge(G, 4, 3); + add_edge(G, 3, 4); + add_edge(G, 3, 0); + add_edge(G, 5, 2); + + typedef Graph::vertex_descriptor Vertex; + + std::vector c(N); + int num = connected_components + (G, c.begin(), get_vertex_property_accessor(G, color_tag()), + dfs_visitor<>()); + + cout << "A directed graph:" << endl; + cout << endl; + cout << "Total number of components: " << num << endl; + std::vector::iterator i; + for (i = c.begin(); i != c.end(); ++i) + cout << "Vertex " << i - c.begin() <<" is in component " << *i << endl; + } + + return 0; +} + diff --git a/examples/connected_components.expected b/examples/connected_components.expected new file mode 100644 index 00000000..12c6bd06 --- /dev/null +++ b/examples/connected_components.expected @@ -0,0 +1,19 @@ +An undirected graph: + +Total number of components: 3 +Vertex 0 is in component 0 +Vertex 1 is in component 0 +Vertex 2 is in component 1 +Vertex 3 is in component 2 +Vertex 4 is in component 0 +Vertex 5 is in component 1 + +A directed graph: + +Total number of components: 3 +Vertex 0 is in component 2 +Vertex 1 is in component 2 +Vertex 2 is in component 1 +Vertex 3 is in component 2 +Vertex 4 is in component 2 +Vertex 5 is in component 0 diff --git a/examples/connected_components_on_edgelist.cpp b/examples/connected_components_on_edgelist.cpp new file mode 100644 index 00000000..2ec94b00 --- /dev/null +++ b/examples/connected_components_on_edgelist.cpp @@ -0,0 +1,110 @@ +//======================================================================= +// 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + + This example demonstrates the usage of the + connected_components_on_edgelist algorithm. This differs from the + connect_components algorithm in that the graph object + only needs to provide access to the "list" of edges (via the + edges() function). + + The example graphs come from "Introduction to + Algorithms", Cormen, Leiserson, and Rivest p. 87 (though we number + the vertices from zero instead of one). + + Sample output: + + An undirected graph (edge list): + (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 + Vertex 2 is in the component who's representative is 5 + 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 + + */ + + +using namespace std; +using boost::tie; + +int main(int argc, char* argv[]) +{ + using namespace boost; + typedef int Index; // ID of a Vertex + typedef pair 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 g(edgelist, edgelist + E); + cout << "An undirected graph (edge list):" << endl; + print_edges(g, identity_property_accessor()); + cout << endl; + + disjoint_sets_with_storage<> ds; + dynamic_connected_components(g, ds); + + component_index components(ds.parents().begin(), + ds.parents().end()); + + 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 (component_index::size_type i = 0; i < components.size(); ++i) { + cout << "component " << i << " contains: "; + component_index::value_type::iterator + j = components[i].begin(), + jend = components[i].end(); + for ( ; j != jend; ++j) + cout << *j << " "; + cout << endl; + } + + return 0; +} diff --git a/examples/connected_components_on_edgelist.expected b/examples/connected_components_on_edgelist.expected new file mode 100644 index 00000000..bb12dd33 --- /dev/null +++ b/examples/connected_components_on_edgelist.expected @@ -0,0 +1,14 @@ +An undirected graph (edge list): +(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 +Vertex 2 is in the component who's representative is 5 +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 diff --git a/examples/container_gen.cpp b/examples/container_gen.cpp new file mode 100644 index 00000000..d0eed42f --- /dev/null +++ b/examples/container_gen.cpp @@ -0,0 +1,53 @@ +//======================================================================= +// 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 + + +template +struct list_with_allocatorS { }; + +namespace boost { + template + struct container_gen, ValueType> { + typedef typename Alloc::template rebind::other Allocator; + typedef std::list type; + }; + template + struct parallel_edge_traits< list_with_allocatorS > { + 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 >, + boost::vecS, boost::directedS> MyGraph; + +int main(int, char*[]) +{ + MyGraph g(5); + + return 0; +} diff --git a/examples/container_gen.expected b/examples/container_gen.expected new file mode 100644 index 00000000..e69de29b diff --git a/examples/cuthill_mckee_ordering.cpp b/examples/cuthill_mckee_ordering.cpp new file mode 100644 index 00000000..65730a64 --- /dev/null +++ b/examples/cuthill_mckee_ordering.cpp @@ -0,0 +1,125 @@ +//======================================================================= +// 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 +#include +#include +#include +#include + + /* + Sample Output + 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 + Reverse Cuthill-McKee ordering starting at :0 + 9 1 4 6 7 2 8 5 3 0 + Reverse Cuthill-McKee ordering: //choose vertex 9 + 0 8 5 7 3 6 4 2 1 9 + */ +int main(int argc, char* argv[]) +{ + using namespace boost; + using namespace std; + identity_property_accessor id; + typedef adjacency_list > > Graph; + typedef Graph::vertex_descriptor Vertex; + + typedef std::pair 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(G, edges[i].first, edges[i].second); + + + Graph::vertex_iterator ui, uiend; + + vertex_property_accessor::type deg + = get_vertex_property_accessor(G, degree_tag()); + cout << "degree: " << endl; + for (boost::tie(ui, uiend) = vertices(G); ui != uiend; ++ui) { + deg[*ui] = out_degree(*ui, G); + cout << deg[*ui] << " "; + } + cout << endl; + + std::vector iperm(num_vertices(G)); + { + Vertex s = vertex(6, G); + //reverse cuthill_mckee_ordering + cuthill_mckee_ordering(G, s, iperm.rbegin(), + get_vertex_property_accessor(G, color_tag()), + get_vertex_property_accessor(G, degree_tag())); + cout << "Reverse Cuthill-McKee ordering starting at :" << s << endl; + + for (std::vector::const_iterator i=iperm.begin(); + i != iperm.end(); ++i) + cout << id[*i] << " "; + cout << endl; + } + { + Vertex s = vertex(0, G); + //reverse cuthill_mckee_ordering + cuthill_mckee_ordering(G, s, iperm.rbegin(), + get_vertex_property_accessor(G, color_tag()), + get_vertex_property_accessor(G, degree_tag())); + cout << "Reverse Cuthill-McKee ordering starting at :" << s << endl; + + for (std::vector::const_iterator i=iperm.begin(); + i != iperm.end(); ++i) + cout << id[*i] << " "; + cout << endl; + } + + { + //reverse cuthill_mckee_ordering + cuthill_mckee_ordering(G, iperm.rbegin()); + + cout << "Reverse Cuthill-McKee ordering:" << endl; + + for (std::vector::const_iterator i=iperm.begin(); + i != iperm.end(); ++i) + cout << id[*i] << " "; + cout << endl; + } + return 0; +} diff --git a/examples/cuthill_mckee_ordering.expected b/examples/cuthill_mckee_ordering.expected new file mode 100644 index 00000000..42fc655a --- /dev/null +++ b/examples/cuthill_mckee_ordering.expected @@ -0,0 +1,8 @@ +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 +Reverse Cuthill-McKee ordering starting at :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 diff --git a/examples/dave.cpp b/examples/dave.cpp new file mode 100644 index 00000000..29510d78 --- /dev/null +++ b/examples/dave.cpp @@ -0,0 +1,231 @@ +//======================================================================= +// 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 +#include +#include +#include + +#include +#include +#include +#include + +using namespace std; +using namespace boost; +/* + This example does a best-first-search (using dijkstra's) and + simultaneously makes a copy of the graph (assuming the graph is + connected). + + Example Graph: (p. 90 "Data Structures and Network Algorithms", Tarjan) + + g + 3+ +2 + / 1 \ + e+----f + |+0 5++ + | \ / | + 10| d |12 + |8++\7| + +/ | +| + b 4| c + \ | + + 6+|/3 + a + + Sample Output: +a --> c d +b --> a d +c --> f +d --> c e f +e --> b g +f --> e g +g --> +Starting graph: +a(32767); c d +c(32767); f +d(32767); c e f +f(32767); e g +e(32767); b g +g(32767); +b(32767); a d +Result: +a(0); d c +d(4); f e c +c(3); f +f(9); g e +e(4); g b +g(7); +b(14); d a + +*/ + +typedef plugin > VPlugin; +typedef int weight_t; +typedef plugin EPlugin; + +typedef adjacency_list Graph; + + + +template +struct endl_printer { + typedef Tag event_filter; + endl_printer(std::ostream& os) : m_os(os) { } + template + void operator()(T, Graph&) { m_os << std::endl; } + std::ostream& m_os; +}; +template +endl_printer print_endl(std::ostream& os, Tag) { + return endl_printer(os); +} + +template +struct edge_printer { + typedef Tag event_filter; + + edge_printer(PA pa, std::ostream& os) : m_pa(pa), m_os(os) { } + + template + 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 +edge_printer +print_edge(PA pa, std::ostream& os, Tag) { + return edge_printer(pa, os); +} + + +template +struct graph_copier + : public boost::base_visitor > +{ + typedef Tag event_filter; + + graph_copier(NewGraph& graph) : new_g(graph) { } + + template + void operator()(Edge e, Graph& g) { + add_edge(new_g, source(e, g), target(e, g)); + } +private: + NewGraph& new_g; +}; +template +inline graph_copier +copy_graph(NewGraph& g, Tag) { + return graph_copier(g); +} + +template +void print(Graph& G, Name name) +{ + typename boost::graph_traits::vertex_iterator ui, uiend; + for (boost::tie(ui,uiend)=vertices(G); ui!=uiend; ++ui) { + cout << name[*ui] << " --> "; + typename boost::graph_traits::adjacency_iterator vi, viend; + for(boost::tie(vi,viend)=adjacent_vertices(*ui,G); vi!=viend; ++vi) + cout << name[*vi] << " "; + cout << endl; + } + +} + + +int +main(int argc, char* argv[]) +{ + // Name and ID numbers for the vertices + char name[] = "abcdefg"; + enum { a, b, c, d, e, f, g, N}; + + Graph G(N); + + vector distance(N, numeric_limits::max()); + typedef boost::graph_traits::vertex_descriptor Vertex; + vector parent(N); + + typedef pair 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(G, edges[i].first, edges[i].second, weight[i]); + + print(G, name); + + adjacency_list > G_copy(N); + + cout << "Starting graph:" << endl; + + std::ostream_iterator cout_int(std::cout, " "); + std::ostream_iterator cout_char(std::cout, " "); + + boost::breadth_first_search + (G, vertex(a, G), make_bfs_visitor( + std::make_pair(write_property(name, cout_char, on_discover_vertex()), + std::make_pair(write_property(distance.begin(), cout_int, + on_discover_vertex()), + std::make_pair(print_edge(name, std::cout, on_examine_edge()), + print_endl(std::cout, on_finish_vertex() + )))))); + + dijkstra_shortest_paths(G, vertex(a, G), distance.begin(), + make_ucs_visitor(std::make_pair(copy_graph(G_copy, on_examine_edge()), + record_predecessors(parent.begin(), + on_edge_relaxed())))); + + cout << endl; + cout << "Result:" << endl; + breadth_first_search + (G_copy, vertex(a, G_copy), make_bfs_visitor( + std::make_pair(write_property(name, cout_char, on_discover_vertex()), + std::make_pair(write_property(distance.begin(), cout_int, + on_discover_vertex()), + std::make_pair(print_edge(name, std::cout, on_examine_edge()), + print_endl(std::cout, on_finish_vertex() + )))))); + return 0; +} diff --git a/examples/dave.expected b/examples/dave.expected new file mode 100644 index 00000000..65efe7b4 --- /dev/null +++ b/examples/dave.expected @@ -0,0 +1,24 @@ +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) + +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) diff --git a/examples/dfs.cpp b/examples/dfs.cpp new file mode 100644 index 00000000..cc6d029c --- /dev/null +++ b/examples/dfs.cpp @@ -0,0 +1,133 @@ +//======================================================================= +// 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 +#include + +#include +#include +#include + + +#include +#include +#include + +/* + This calculates the discover finishing time. + + Sample Output + + Tree edge: 0 --> 2 + Tree edge: 2 --> 1 + Back edge: 1 --> 1 + Tree edge: 1 --> 3 + Back edge: 3 --> 1 + Tree edge: 3 --> 4 + Back edge: 4 --> 0 + Back edge: 4 --> 1 + Forward or cross edge: 2 --> 3 + 1 10 + 3 8 + 2 9 + 4 7 + 5 6 + + */ + +using namespace boost; +using namespace std; + + +template +struct edge_categorizer : public dfs_visitor { + typedef dfs_visitor Base; + + edge_categorizer(const VisitorList& v = null_visitor()) : Base(v) { } + + template + void tree_edge(Edge e, Graph& G) { + cout << "Tree edge: " << source(e, G) << + " --> " << target(e, G) << endl; + Base::tree_edge(e, G); + } + template + void back_edge(Edge e, Graph& G) { + cout << "Back edge: " << source(e, G) + << " --> " << target(e, G) << endl; + Base::back_edge(e, G); + } + template + 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 +edge_categorizer +categorize_edges(const VisitorList& v) { + return edge_categorizer(v); +} + +int +main(int argc, char* argv[]) +{ + + using namespace boost; + + typedef adjacency_list<> Graph; + + Graph G(5); + add_edge(G, 0, 2); + add_edge(G, 1, 1); + add_edge(G, 1, 3); + add_edge(G, 2, 1); + add_edge(G, 2, 3); + add_edge(G, 3, 1); + add_edge(G, 3, 4); + add_edge(G, 4, 0); + add_edge(G, 4, 1); + + typedef graph_traits::vertex_descriptor Vertex; + typedef graph_traits::vertices_size_type size_type; + + std::vector c(num_vertices(G)); + std::vector d(num_vertices(G)); + std::vector f(num_vertices(G)); + int t = 0; + depth_first_search(G, categorize_edges( + make_pair(stamp_times(d.begin(), t, on_discover_vertex()), + stamp_times(f.begin(), t, on_finish_vertex()))), + c.begin()); + + + std::vector::iterator i, j; + for (i = d.begin(), j = f.begin(); i != d.end(); ++i, ++j) { + cout << *i << " " << *j << endl; + } + + return 0; +} + diff --git a/examples/dfs.expected b/examples/dfs.expected new file mode 100644 index 00000000..84aa0c45 --- /dev/null +++ b/examples/dfs.expected @@ -0,0 +1,14 @@ +Tree edge: 0 --> 2 +Tree edge: 2 --> 1 +Back edge: 1 --> 1 +Tree edge: 1 --> 3 +Back edge: 3 --> 1 +Tree edge: 3 --> 4 +Back edge: 4 --> 0 +Back edge: 4 --> 1 +Forward or cross edge: 2 --> 3 +1 10 +3 8 +2 9 +4 7 +5 6 diff --git a/examples/dfs_basics.cpp b/examples/dfs_basics.cpp new file mode 100644 index 00000000..305c2536 --- /dev/null +++ b/examples/dfs_basics.cpp @@ -0,0 +1,122 @@ +//======================================================================= +// 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 +#include +#include +#include +#include +#include +#include +#include // for iota +#include +/* + Depth-First Search + + This example records the "discover time" and "finish time" of each + vertex during a depth-first search. This gives a little insight + into the order in which DFS traverses a graph. It is instructive to + compare this to the discover and finish time using breadth first + search (in bfs_basics.cc). Note that the depth first search does + not start at a particular source node, then visit all the other + reachable vertices, as in BFS. Instead it visits all vertices in + the graph, possibly visiting several separate DFS trees. In the + example below, one DFS tree is {u,x,v,y} and another is {w,z}. + + Here's the example graph from p. 479 of the CLR: + + u--+v w + | +| /| + | / | / | + +/ ++ | + x+--y z+_ + \_| + + Sample Output: + + order of discovery: u v y x w z + order of finish: x y v u z w + + */ + +using namespace std; +using namespace boost; + + + +int main(int argc, char* argv[]) +{ + // Select the graph type we wish to use + typedef adjacency_list Graph; + // Set up the vertex names + enum { u, v, w, x, y, z, N }; + char name[] = { 'u', 'v', 'w', 'x', 'y', 'z' }; + int i; + // Specify the edges in the graph + typedef pair 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) }; + Graph G(N, edge_array, edge_array + sizeof(edge_array)/sizeof(E)); + + // Some typedef's to save a little typing + typedef boost::graph_traits::vertex_descriptor Vertex; + typedef boost::graph_traits::vertices_size_type size_type; + typedef std::vector::iterator Piter; + typedef std::vector::iterator Iiter; + + // color, discover time, and finish time properties + std::vector color(num_vertices(G)); + std::vector dtime(num_vertices(G)); + std::vector ftime(num_vertices(G)); + int t = 0; + depth_first_search + (G, make_dfs_visitor(make_pair(stamp_times(dtime.begin(), t, + on_discover_vertex()), + stamp_times(ftime.begin(), t, + on_finish_vertex()))), + color.begin()); + + // use std::sort to order the vertices by their discover time + vector discover_order(N); + iota(discover_order.begin(), discover_order.end(), 0); + std::sort(discover_order.begin(), discover_order.end(), + indirect_cmp >(dtime.begin())); + + cout << "order of discovery: "; + for (i = 0; i < N; ++i) + cout << name[ discover_order[i] ] << " "; + + vector finish_order(N); + iota(finish_order.begin(), finish_order.end(), 0); + std::sort(finish_order.begin(), finish_order.end(), + indirect_cmp >(ftime.begin())); + + cout << endl << "order of finish: "; + for (i = 0; i < N; ++i) + cout << name[ finish_order[i] ] << " "; + cout << endl; + + return 0; +} diff --git a/examples/dfs_basics.expected b/examples/dfs_basics.expected new file mode 100644 index 00000000..a9e90d70 --- /dev/null +++ b/examples/dfs_basics.expected @@ -0,0 +1,2 @@ +order of discovery: u v y x w z +order of finish: x y v u z w diff --git a/examples/dfs_parenthesis.cpp b/examples/dfs_parenthesis.cpp new file mode 100644 index 00000000..394ed79d --- /dev/null +++ b/examples/dfs_parenthesis.cpp @@ -0,0 +1,90 @@ +//======================================================================= +// 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. +//======================================================================= +// +// Sample output +// DFS parenthesis: +// (0(2(3(4(11)4)3)2)0) + +#include +#include + +#include +#include +#include + +#include "boost/graph/visitors.hpp" +#include "boost/graph/adjacency_list.hpp" +#include "boost/graph/breadth_first_search.hpp" +#include "boost/graph/depth_first_search.hpp" + +using namespace boost; +using namespace std; + +struct open_paren : public base_visitor { + typedef on_discover_vertex event_filter; + template + void operator()(Vertex v, Graph& G) { + std::cout << "(" << v; + } +}; +struct close_paren : public base_visitor { + typedef on_finish_vertex event_filter; + template + void operator()(Vertex v, Graph& G) { + std::cout << v << ")"; + } +}; + + +int +main(int argc, char* argv[]) +{ + + using namespace boost; + + typedef adjacency_list<> Graph; + typedef std::pair E; + E edges[] = { 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) }; + Graph G(5, edges, edges + sizeof(edges)/sizeof(E)); + + typedef boost::graph_traits::vertex_descriptor Vertex; + typedef boost::graph_traits::vertices_size_type size_type; + + std::vector c(num_vertices(G)); + std::vector d(num_vertices(G)); + std::vector f(num_vertices(G)); + + std::cout << "DFS parenthesis:" << std::endl; + depth_first_search(G, make_dfs_visitor(std::make_pair(open_paren(), + close_paren())), + c.begin()); + std::cout << std::endl; + return 0; +} + diff --git a/examples/dfs_parenthesis.expected b/examples/dfs_parenthesis.expected new file mode 100644 index 00000000..9d71af73 --- /dev/null +++ b/examples/dfs_parenthesis.expected @@ -0,0 +1,2 @@ +DFS parenthesis: +(0(2(1(3(44)3)1)2)0) diff --git a/examples/dijkstra.cpp b/examples/dijkstra.cpp new file mode 100644 index 00000000..f1e26882 --- /dev/null +++ b/examples/dijkstra.cpp @@ -0,0 +1,97 @@ +//======================================================================= +// 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 + +#include +#include +#include +#include +#include + +/* Output: + + distances from start vertex: + distance(0) = 0 + distance(1) = 6 + distance(2) = 1 + distance(3) = 4 + distance(4) = 5 + + shortest paths tree + 0 --> 2 + 1 --> + 2 --> 3 + 3 --> 4 + 4 --> 1 +*/ + +int +main(int argc, char* argv[]) +{ + using namespace boost; + + typedef plugin weightp; + typedef adjacency_list< listS, vecS, directedS, + plugin, weightp > Graph; + typedef graph_traits::vertex_descriptor Vertex; + + typedef std::pair E; + + const int num_nodes = 5; + E edges[] = { E(0,2), + E(1,1), E(1,3), E(1,4), + E(2,1), E(2,3), + E(3,4), + E(4,0), E(4,1) }; + int weights[] = { 1, 2, 1, 2, 7, 3, 1, 1, 1}; + + std::cout << "constructing graph" << std::endl; + Graph G(num_nodes, edges, edges + sizeof(edges)/sizeof(E), weights); + std::cout << "done constructing" << std::endl; + + std::vector p(num_vertices(G)); + std::vector d(num_vertices(G)); + + Vertex s = *(vertices(G).first); + + dijkstra_shortest_paths(G, s, d.begin(), + make_ucs_visitor(record_predecessors(p.begin(), on_edge_relaxed()))); + + std::cout << "distances from start vertex:" << std::endl; + graph_traits::vertex_iterator vi, vend; + for(tie(vi,vend) = vertices(G); vi != vend; ++vi) + std::cout << "distance(" << *vi << ") = " << d[*vi] << std::endl; + std::cout << std::endl; + + std::cout << std::endl << "shortest paths tree" << std::endl; + adjacency_list<> tree(num_nodes); + tie(vi,vend) = vertices(G); + for(++vi; vi != vend; ++vi) + add_edge(tree, p[*vi], *vi); + + print_graph(tree); + + return 0; +} diff --git a/examples/dijkstra.expected b/examples/dijkstra.expected new file mode 100644 index 00000000..e3fd73d6 --- /dev/null +++ b/examples/dijkstra.expected @@ -0,0 +1,16 @@ +constructing graph +done constructing +distances from start vertex: +distance(0) = 0 +distance(1) = 6 +distance(2) = 1 +distance(3) = 4 +distance(4) = 5 + + +shortest paths tree +0 --> 2 +1 --> +2 --> 3 +3 --> 4 +4 --> 1 diff --git a/examples/dynamic_components.cpp b/examples/dynamic_components.cpp new file mode 100644 index 00000000..4abb0b28 --- /dev/null +++ b/examples/dynamic_components.cpp @@ -0,0 +1,122 @@ +//======================================================================= +// 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 +#include +#include +#include +#include +#include +#include + +/* + + This example shows how to use the disjoint set data structure + to compute the connected components of an undirected, changing + graph. + + Sample output: + + An undirected graph: + 0 <--> 1 4 + 1 <--> 0 4 + 2 <--> 5 + 3 <--> + 4 <--> 1 0 + 5 <--> 2 + + representative[0] = 1 + representative[1] = 1 + representative[2] = 5 + representative[3] = 3 + representative[4] = 1 + representative[5] = 5 + + component 0 contains: 4 1 0 + component 1 contains: 3 + component 2 contains: 5 2 + + */ + +using namespace std; + +int main(int argc, char* argv[]) +{ + using namespace boost; + typedef adjacency_list Graph; + typedef graph_traits::vertex_descriptor Vertex; + typedef graph_traits::vertices_size_type size_type; + + const int N = 6; + Graph G(N); + + std::vector rank(num_vertices(G)); + std::vector parent(num_vertices(G)); + typedef std::vector::iterator Rank; + typedef std::vector::iterator Parent; + disjoint_sets ds(rank.begin(), parent.begin()); + + initialize_dynamic_components(G, ds); + dynamic_connected_components(G, ds); + + graph_traits::edge_descriptor e; + bool flag; + boost::tie(e,flag) = add_edge(G, 0, 1); + ds.union_set(0,1); + + boost::tie(e,flag) = add_edge(G, 1, 4); + ds.union_set(1,4); + + boost::tie(e,flag) = add_edge(G, 4, 0); + ds.union_set(4,0); + + boost::tie(e,flag) = add_edge(G, 2, 5); + ds.union_set(2,5); + + cout << "An undirected graph:" << endl; + print_graph(G, get_vertex_property_accessor(G,id_tag())); + cout << endl; + + graph_traits::vertex_iterator i,end; + for (boost::tie(i,end) = vertices(G); i != end; ++i) + cout << "representative[" << *i << "] = " << + ds.find_set(*i) << endl;; + cout << endl; + + typedef component_index Components; + Components components(parent.begin(), parent.end()); + + for (Components::size_type c = 0; c < components.size(); ++c) { + cout << "component " << c << " contains: "; + Components::value_type::iterator + j = components[c].begin(), + jend = components[c].end(); + for ( ; j != jend; ++j) + cout << *j << " "; + cout << endl; + } + + return 0; +} + diff --git a/examples/dynamic_components.expected b/examples/dynamic_components.expected new file mode 100644 index 00000000..c1e0b510 --- /dev/null +++ b/examples/dynamic_components.expected @@ -0,0 +1,18 @@ +An undirected graph: +0 <--> 1 4 +1 <--> 0 4 +2 <--> 5 +3 <--> +4 <--> 1 0 +5 <--> 2 + +representative[0] = 1 +representative[1] = 1 +representative[2] = 5 +representative[3] = 3 +representative[4] = 1 +representative[5] = 5 + +component 0 contains: 4 1 0 +component 1 contains: 3 +component 2 contains: 5 2 diff --git a/examples/edge_basics.cpp b/examples/edge_basics.cpp new file mode 100644 index 00000000..47343af9 --- /dev/null +++ b/examples/edge_basics.cpp @@ -0,0 +1,103 @@ +//======================================================================= +// 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 +#include +#include + +using namespace std; +using namespace boost; + + +/* + Edge Basics + + This example demonstrates the GGCL Edge interface + + There is not much to the Edge interface. Basically just two + functions to access the source and target vertex: + + source(e) + target(e) + + and one associated type for the vertex type: + + edge_traits::vertex_type + + Sample output: + + (0,1) (0,2) (0,3) (0,4) (2,0) (2,4) (3,0) (3,1) + + */ + + + +template +struct exercise_edge { + exercise_edge(Graph& g) : G(g) {} + + typedef typename boost::graph_traits::edge_descriptor Edge; + typedef typename boost::graph_traits::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; +}; + + +int +main() +{ + typedef adjacency_list<> MyGraph; + + typedef pair 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(G, edge_array[i].first, edge_array[i].second); + + // 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(G)); + cout << endl; + return 0; +} diff --git a/examples/edge_basics.expected b/examples/edge_basics.expected new file mode 100644 index 00000000..684dc15f --- /dev/null +++ b/examples/edge_basics.expected @@ -0,0 +1 @@ +(0,1) (0,2) (0,3) (0,4) (2,0) (2,4) (3,0) (3,1) diff --git a/examples/edge_plugin.cpp b/examples/edge_plugin.cpp new file mode 100644 index 00000000..80b4b29d --- /dev/null +++ b/examples/edge_plugin.cpp @@ -0,0 +1,135 @@ +//======================================================================= +// 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. +//======================================================================= +// +// Sample output: +// +#include + +#include +#include +#include + + +using boost::tie; +using boost::graph_traits; + + +struct flow_tag { enum { num = 200 }; }; +struct capacity_tag { enum { num = 201 }; }; + +using namespace boost; +using namespace std; + +template +void print_network(Graph& G, Capacity capacity, Flow flow) +{ + typedef typename boost::graph_traits::vertex_iterator Viter; + typedef typename boost::graph_traits::out_edge_iterator OutEdgeIter; + typedef typename boost::graph_traits::in_edge_iterator InEdgeIter; + + 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 argc, char* argv[]) +{ + typedef plugin Cap; + typedef plugin Flow; + typedef adjacency_list Graph; + + const int num_vertices = 9; + Graph G(num_vertices); + + /* 2<----5 + / ^ + / \ + V \ + 0 ---->1---->3----->6--->8 + \ ^ + \ / + V / + 4----->7 + */ + + add_edge(G, 0, 1, Flow(10, Cap(8))); + + add_edge(G, 1, 4, Flow(20, Cap(12))); + add_edge(G, 4, 7, Flow(20, Cap(12))); + add_edge(G, 7, 6, Flow(20, Cap(12))); + + add_edge(G, 1, 3, Flow(40, Cap(12))); + add_edge(G, 3, 6, Flow(40, Cap(12))); + + add_edge(G, 6, 5, Flow(20, Cap(16))); + add_edge(G, 5, 2, Flow(20, Cap(16))); + add_edge(G, 2, 1, Flow(20, Cap(16))); + + add_edge(G, 6, 8, Flow(10, Cap(8))); + + typedef boost::graph_traits::edge_descriptor Edge; + + edge_property_accessor::type capacity + = get_edge_property_accessor(G, capacity_tag()); + edge_property_accessor::type flow + = get_edge_property_accessor(G,flow_tag()); + + print_network(G, capacity, flow); + + boost::graph_traits::vertex_iterator v, v_end; + boost::graph_traits::out_edge_iterator e, e_end; + int f = 0; + for (tie(v,v_end) = vertices(G); v != v_end; ++v) + for (tie(e,e_end) = out_edges(*v,G); e != e_end; ++e) + flow[*e] = ++f; + + cout << endl << endl; + + remove_edge(G, 6, 8); + + print_network(G, capacity, flow); + + + return 0; +} diff --git a/examples/edge_plugin.expected b/examples/edge_plugin.expected new file mode 100644 index 00000000..6c71be14 --- /dev/null +++ b/examples/edge_plugin.expected @@ -0,0 +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, 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 + diff --git a/examples/exterior_edge_properties.cpp b/examples/exterior_edge_properties.cpp new file mode 100644 index 00000000..eb06570a --- /dev/null +++ b/examples/exterior_edge_properties.cpp @@ -0,0 +1,133 @@ +//======================================================================= +// 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. +//======================================================================= +// +// This example is similar to the one in edge_plugin.cpp. +// The only difference is that this example uses exterior +// property storage instead of interior (plugins). +// +// Sample output: +// +// 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 + + +#include +#include +#include + + +template +void print_network(Graph& G, Capacity capacity, Flow flow) +{ + typedef typename boost::graph_traits::vertex_iterator Viter; + typedef typename boost::graph_traits::out_edge_iterator OutEdgeIter; + typedef typename boost::graph_traits::in_edge_iterator InEdgeIter; + + Viter ui, uiend; + for (boost::tie(ui, uiend) = vertices(G); ui != uiend; ++ui) { + OutEdgeIter out, out_end; + std::cout << *ui << "\t"; + + for(boost::tie(out, out_end) = out_edges(*ui, G); out != out_end; ++out) + std::cout << "--(" << get(capacity, *out) << ", " + << get(flow, *out) << ")--> " << target(*out,G) << "\t"; + std::cout << std::endl << "\t"; + + InEdgeIter in, in_end; + for(boost::tie(in, in_end) = in_edges(*ui, G); in != in_end; ++in) + std::cout << "<--(" << get(capacity, *in) << "," << get(flow, *in) << ")-- " + << source(*in,G) << "\t"; + std::cout << std::endl; + } +} + + +int main(int argc, char* argv[]) { + + typedef boost::adjacency_list > Graph; + + const int num_vertices = 9; + Graph G(num_vertices); + + /* 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 }; + + // add edges to the graph, and assign each edge an ID number + // to index into the property arrays + add_edge(G, 0, 1, 0); + + add_edge(G, 1, 4, 1); + add_edge(G, 4, 7, 2); + add_edge(G, 7, 6, 3); + + add_edge(G, 1, 3, 4); + add_edge(G, 3, 6, 5); + + add_edge(G, 6, 5, 6); + add_edge(G, 5, 2, 7); + add_edge(G, 2, 1, 8); + + add_edge(G, 6, 8, 9); + + typedef boost::graph_traits::edge_descriptor Edge; + typedef boost::edge_property_accessor::type EdgeID_PA; + EdgeID_PA edge_id = get_edge_property_accessor(G, boost::id_tag()); + + typedef boost::random_access_iterator_property_accessor + RA_PA; + + print_network(G, RA_PA(capacity, edge_id), RA_PA(flow, edge_id)); + + return 0; +} diff --git a/examples/exterior_edge_properties.expected b/examples/exterior_edge_properties.expected new file mode 100644 index 00000000..863e0060 --- /dev/null +++ b/examples/exterior_edge_properties.expected @@ -0,0 +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 diff --git a/examples/exterior_property_accessor.cpp b/examples/exterior_property_accessor.cpp new file mode 100644 index 00000000..35e745e5 --- /dev/null +++ b/examples/exterior_property_accessor.cpp @@ -0,0 +1,109 @@ +//======================================================================= +// 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 +#include +#include +#include +#include + +using namespace std; +using namespace boost; + +/* + Exterior Decorator Basics + + An exterior decorator is a way of associating properties with the + vertices or edges of a graph. The "exterior" part means that the + properties are not stored inside the graph object (see + internal_decorator_basics.cc). Instead they are stored + separately, and passed as an extra argument to any + algorithm they are needed in. There are several standard + decorator types such a color and weight that are used + in the GGCL algorithms. + + The main responsibility of a decorator is to provide an operator[] + that maps a vertex (or vertex ID) to the property value for that + vertex. It just so happens that a normal array provides this. In + addition, a decorator must provide access to the property type + through the decorator_traits class. For convenience, GGCL + already defines a decorator_triats class for pointer and + array types. + + Sample Output + + Jeremy owes Rich some money + Jeremy owes Andrew some money + Jeremy owes Jeff some money + Jeremy owes Kinis some money + Andrew owes Jeremy some money + Andrew owes Kinis some money + Jeff owes Jeremy some money + Jeff owes Rich some money + Jeff owes Kinis some money + Kinis owes Jeremy some money + Kinis owes Rich some money + + */ + +template +void who_owes_who(EdgeIter first, EdgeIter last, const Graph& G, + Name name) +{ + while (first != last) { + + cout << name[source(*first,G)] << " owes " + << name[target(*first,G)] << " some money" << endl; + ++first; + } +} + +int +main(int, char*[]) +{ + /* 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; + + typedef pair 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(G, edge_array[i].first, edge_array[i].second); + + who_owes_who(edges(G).first, edges(G).second, G, names); + + return 0; +} diff --git a/examples/exterior_property_accessor.expected b/examples/exterior_property_accessor.expected new file mode 100644 index 00000000..6fb19310 --- /dev/null +++ b/examples/exterior_property_accessor.expected @@ -0,0 +1,11 @@ +Jeremy owes Rich some money +Jeremy owes Andrew some money +Jeremy owes Jeff some money +Jeremy owes Kinis some money +Andrew owes Jeremy some money +Andrew owes Kinis some money +Jeff owes Jeremy some money +Jeff owes Rich some money +Jeff owes Kinis some money +Kinis owes Jeremy some money +Kinis owes Rich some money diff --git a/examples/family_tree.cpp b/examples/family_tree.cpp new file mode 100644 index 00000000..92c9f62a --- /dev/null +++ b/examples/family_tree.cpp @@ -0,0 +1,98 @@ +//======================================================================= +// 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 +#include +#include +#include +#include + +using namespace std; + +/* + Family Tree Example + + Jeanie + / | \ + Debbie Rick John + / | \ + Amanda Margaret Benjamin + + + Sample Output: + 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 + +*/ + +enum family { Jeanie, Debbie, Rick, John, Amanda, Margaret, Benjamin, N }; + +int main(int argc, char* argv[]) +{ + using namespace boost; + using boost::tie; + + + std::vector name(N); + name[Jeanie] = "Jeanie"; + name[Debbie] = "Debbie"; + name[Rick] = "Rick"; + name[John] = "John"; + name[Amanda] = "Amanda"; + name[Margaret] = "Margaret"; + name[Benjamin] = "Benjamin"; + + adjacency_list<> G(N); + add_edge(G, Jeanie, Debbie); + add_edge(G, Jeanie, Rick); + add_edge(G, Jeanie, John); + add_edge(G, Debbie, Amanda); + add_edge(G, Rick, Margaret); + add_edge(G, John, Benjamin); + + graph_traits< adjacency_list<> >::vertex_iterator i, end; + graph_traits< adjacency_list<> >::adjacency_iterator ai, a_end; + + vertex_property_accessor< adjacency_list<>, id_tag>::type + id = get_vertex_property_accessor(G, id_tag()); + + for(tie(i,end) = vertices(G); i != end; ++i) { + cout << name[get(id, *i)]; + tie(ai, a_end) = adjacent_vertices(*i, G); + if (ai == a_end) + cout << " has no children"; + else + cout << " is the parent of "; + for (; ai != a_end; ++ai) + cout << name[get(id, *ai)] << " "; + cout << endl; + } + return 0; +} diff --git a/examples/family_tree.expected b/examples/family_tree.expected new file mode 100644 index 00000000..b3e6d61a --- /dev/null +++ b/examples/family_tree.expected @@ -0,0 +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 +Amanda has no children +Margaret has no children +Benjamin has no children diff --git a/examples/fibonacci_heap.cpp b/examples/fibonacci_heap.cpp new file mode 100644 index 00000000..3d706294 --- /dev/null +++ b/examples/fibonacci_heap.cpp @@ -0,0 +1,71 @@ +//======================================================================= +// 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 +#include +#include +#include +#include +#include + +using namespace boost; + +int +main() +{ + typedef std::vector ValArray; + typedef indirect_cmp > Cmp; + int i; + for (int N = 2; N < 200; ++N) { + for (int t = 0; t < 10; ++t) { + fibonacci_heap > Q(N, std::less()); + std::vector v, w(N); + + iota(w.begin(), w.end(), 0); + std::random_shuffle(w.begin(), w.end()); + + for (i = 0; i < N; ++i) + Q.push(w[i]); + + for (i = 0; i < N; ++i) { + v.push_back(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(std::cout," ")); + std::cout << std::endl << "correct: "; + std::copy(w.begin(), w.end(), + std::ostream_iterator(std::cout," ")); + std::cout << std::endl; + return -1; + } + } + } + std::cout << "fibonacci heap passed test" << std::endl; + return 0; +} diff --git a/examples/fibonacci_heap.expected b/examples/fibonacci_heap.expected new file mode 100644 index 00000000..a11d7ad1 --- /dev/null +++ b/examples/fibonacci_heap.expected @@ -0,0 +1 @@ +fibonacci heap passed test diff --git a/examples/file_dependencies.cpp b/examples/file_dependencies.cpp new file mode 100644 index 00000000..73ac3c87 --- /dev/null +++ b/examples/file_dependencies.cpp @@ -0,0 +1,212 @@ +//======================================================================= +// 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. +//======================================================================= +/* + + Paul Moore's request: + + As an example of a practical problem which is not restricted to graph + "experts", consider file dependencies. It's basically graph construction, + plus topological sort, but it might make a nice "tutorial" example. Build a + dependency graph of files, then use the algorithms to do things like + + 1. Produce a full recompilation order (topological sort, by modified date) + 2. Produce a "parallel" recompilation order (same as above, but group files + which can be built in parallel) + 3. Change analysis (if I change file x, which others need recompiling) + 4. Dependency changes (if I add a dependency between file x and file y, what + are the effects) + +*/ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +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 + void discover_vertex(Vertex v, Graph&) { + cout << name[v] << " "; + } +}; + + +template +struct cycle_detector : public dfs_visitor<> +{ + typedef typename boost::property_traits::value_type C; + + cycle_detector(Color c, bool& has_cycle) + : _has_cycle(has_cycle), color(c) { } + + template + void back_edge(Edge e, Graph& g) { + _has_cycle = true; + } +protected: + bool& _has_cycle; + Color color; +}; + +int main(int,char*[]) +{ + + typedef pair 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 int nedges = sizeof(used_by)/sizeof(Edge); + int weights[nedges]; + fill(weights, weights + nedges, 1); + + typedef adjacency_list, + plugin + > Graph; + Graph g(N, used_by, used_by + nedges, weights); + typedef Graph::vertex_descriptor Vertex; + + typedef vertex_property_accessor::type Color; + Color color = get_vertex_property_accessor(g, color_tag()); + + // Determine ordering for a full recompilation + { + typedef list MakeOrder; + MakeOrder make_order; + // typedef front_insert_iterator< MakeOrder > OutputIterator; + topological_sort(g, front_inserter(make_order)); + + cout << "make ordering: "; + for (MakeOrder::iterator i = make_order.begin(); + i != make_order.end(); ++i) + cout << name[*i] << " "; + cout << endl; + } + cout << endl; + + // Recompilation order with files that can be compiled in parallel + // grouped together + { + // Set up the necessary graph properties. + vector time(N, 0); + typedef vector::iterator Time; + typedef edge_property_accessor::type Weight; + Weight weight = get_edge_property_accessor(g, weight_tag()); + + // Calculate the in_degree for each vertex. + vector in_degree(N, 0); + Graph::vertex_iterator i, iend; + Graph::out_edge_iterator j, jend; + for (tie(i,iend) = vertices(g); i != iend; ++i) + for (tie(j,jend) = out_edges(*i,g); j != jend; ++j) + in_degree[target(*j,g)] += 1; + + std::greater compare; + std::plus combine; + + // Run best-first-search from each vertex with zero in-degree. + for (tie(i,iend) = vertices(g); i != iend; ++i) { + if (in_degree[*i] == 0) + uniform_cost_search(g, *i, time.begin(), weight, + compare, combine); + } + + cout << "parallel make ordering, " << endl + << "vertices with same group number can be made in parallel" << endl; + for (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), vis); + cout << endl; + } + cout << endl; + + // are there any cycles in the graph? + { + bool has_cycle = false; + cycle_detector vis(color, has_cycle); + depth_first_search(g, 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(g, bar_cpp, dax_h); + } + cout << endl; + + // are there any cycles in the graph? + { + typedef vertex_property_accessor::type Color; + Color color = get_vertex_property_accessor(g, color_tag()); + bool has_cycle = false; + cycle_detector vis(color, has_cycle); + depth_first_search(g, vis); + cout << "The graph has a cycle now? " << has_cycle << endl; + } + + return 0; +} diff --git a/examples/file_dependencies.expected b/examples/file_dependencies.expected new file mode 100644 index 00000000..9f004a7a --- /dev/null +++ b/examples/file_dependencies.expected @@ -0,0 +1,28 @@ +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, +vertices with same group number can be made in parallel +time_slot[dax.h] = 0 +time_slot[yow.h] = 1 +time_slot[boz.h] = 0 +time_slot[zow.h] = 0 +time_slot[foo.cpp] = 1 +time_slot[foo.o] = 2 +time_slot[bar.cpp] = 2 +time_slot[bar.o] = 3 +time_slot[libfoobar.a] = 4 +time_slot[zig.cpp] = 1 +time_slot[zig.o] = 2 +time_slot[zag.cpp] = 2 +time_slot[zag.o] = 3 +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 + +The graph has a cycle? 0 + +adding edge bar_cpp -> dax_h + +The graph has a cycle now? 1 diff --git a/examples/graph.cpp b/examples/graph.cpp new file mode 100644 index 00000000..9e3c067a --- /dev/null +++ b/examples/graph.cpp @@ -0,0 +1,170 @@ +//======================================================================= +// 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 +#include +#include +#include + +#include + +using namespace boost; +using namespace std; + +typedef plugin > > > > VertexPlugin; +typedef plugin EdgePlugin; +typedef adjacency_list Graph; + +template +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; + } +} + +size_t myrand(size_t N) { + size_t ret = rand() % N; + // cout << "N = " << N << " rand = " << ret << endl; + return ret; +} + +template +bool check_edge(Graph& g, size_t a, size_t b) { + typedef typename Graph::vertex_descriptor Vertex; + 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; + + return true; +} + +int main(int argc, char* argv[]) +{ + size_t N = 5; + + Graph g(N); + int i; + + bool is_failed = false; + + for (i=0; i<6; ++i) { + size_t a = myrand(N), b = myrand(N); + while ( a == b ) b = myrand(N); + cout << "edge edge (" << a << "," << b <<")" << endl; + //add edges + add_edge(g, a, b); + 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) { + size_t a = myrand(N), b = myrand(N); + while ( a == b ) b = myrand(N); + cout << "remove edge (" << a << "," << b <<")" << endl; + remove_edge(g, a, b); + 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; + size_t old_N = N; + size_t vid = add_vertex(g); + 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) { + 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(g, vid, a); + add_edge(g, b, vidp1); + 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 + size_t c = myrand(N); + is_failed = false; + clear_vertex(g, c); + + if ( out_degree(c, g) != 0 ) + is_failed = true; + + cout << "Removing vertex " << c << endl; + remove_vertex(g, c); + + 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; +} diff --git a/examples/graph.expected b/examples/graph.expected new file mode 100644 index 00000000..f7232a76 --- /dev/null +++ b/examples/graph.expected @@ -0,0 +1,36 @@ +edge edge (3,0) +edge edge (1,2) +edge edge (0,4) +edge edge (2,1) +edge edge (4,2) +edge edge (4,0) +0 --> 4 +1 --> 2 +2 --> 1 +3 --> 0 +4 --> 2 0 +remove edge (0,3) +remove edge (4,3) +0 --> 4 +1 --> 2 +2 --> 1 +3 --> 0 +4 --> 2 0 +add edge (5,0) +add edge (5,6) +add edge (5,2) +add edge (5,6) +0 --> 4 +1 --> 2 6 +2 --> 1 6 +3 --> 0 +4 --> 2 0 +5 --> 0 2 +6 --> +Removing vertex 6 +0 --> 4 +1 --> 2 +2 --> 1 +3 --> 0 +4 --> 2 0 +5 --> 0 2 diff --git a/examples/in_edges.cpp b/examples/in_edges.cpp new file mode 100644 index 00000000..014afd1a --- /dev/null +++ b/examples/in_edges.cpp @@ -0,0 +1,68 @@ +//======================================================================= +// 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 +#include +#include + +#include + +/* + Sample Output + + 0 <-- + 1 <-- 0 + 2 <-- 1 + 3 <-- 1 + 4 <-- 2 3 + + */ + +int main(int argc, char* argv[]) +{ + using namespace boost; + using namespace std; + using namespace boost; + + typedef adjacency_list Graph; + const int num_vertices = 5; + Graph g(num_vertices); + + add_edge(g, 0, 1); + add_edge(g, 1, 2); + add_edge(g, 1, 3); + add_edge(g, 2, 4); + add_edge(g, 3, 4); + + boost::graph_traits::vertex_iterator i, end; + boost::graph_traits::in_edge_iterator ei, edge_end; + + for(tie(i,end) = vertices(g); i != end; ++i) { + cout << *i << " <-- "; + for (tie(ei,edge_end) = in_edges(*i, g); ei != edge_end; ++ei) + cout << source(*ei, g) << " "; + cout << endl; + } + return 0; +} diff --git a/examples/in_edges.expected b/examples/in_edges.expected new file mode 100644 index 00000000..b7ed0a68 --- /dev/null +++ b/examples/in_edges.expected @@ -0,0 +1,5 @@ +0 <-- +1 <-- 0 +2 <-- 1 +3 <-- 1 +4 <-- 2 3 diff --git a/examples/interior_property_accessor.cpp b/examples/interior_property_accessor.cpp new file mode 100644 index 00000000..c66c75c3 --- /dev/null +++ b/examples/interior_property_accessor.cpp @@ -0,0 +1,120 @@ +//======================================================================= +// 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 +#include +#include +#include +#include + +using namespace std; +using namespace boost; + +/* + Interior Property Accessor Basics + + An interior property accessor is a way of associating properties + with the vertices or edges of a graph. The "interior" part means + that the properties are stored inside the graph object. This can be + convenient when the need for the properties is somewhat permanent, + and when the properties will be with a graph for the duration of its + lifetime. A "distance from source vertex" property is often of this + kind. + + Sample Output + + Jeremy owes Rich some money + Jeremy owes Andrew some money + Jeremy owes Jeff some money + Jeremy owes Kinis some money + Andrew owes Jeremy some money + Andrew owes Kinis some money + Jeff owes Jeremy some money + Jeff owes Rich some money + Jeff owes Kinis some money + Kinis owes Jeremy some money + Kinis owes Rich some money + + */ + +// create a tag for our new property +// the "num" is only needed for a VC++ workaround +struct first_name_tag { enum { num = 300 }; }; + +template +void who_owes_who(EdgeIter first, EdgeIter last, const Graph& G) +{ + // Access the propety acessor type for this graph + typedef typename vertex_property_accessor + ::const_type NamePA; + NamePA name = get_vertex_property_accessor(G, first_name_tag()); + + typedef typename boost::property_traits::value_type NameType; + + NameType src_name, targ_name; + + while (first != last) { + src_name = boost::get(name, source(*first,G)); + targ_name = boost::get(name, target(*first,G)); + cout << src_name << " owes " + << targ_name << " some money" << endl; + ++first; + } +} + +int +main() +{ + { + // Create the plugin type. We will use std::string to store the + // first name's. + typedef plugin FirstNamePlugin; + typedef adjacency_list MyGraphType; + + typedef pair 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(G, edge_array[i].first, edge_array[i].second); + + vertex_property_accessor::type name + = get_vertex_property_accessor(G, first_name_tag()); + + boost::put(name, 0, "Jeremy"); + boost::put(name, 1, "Rich"); + boost::put(name, 2, "Andrew"); + boost::put(name, 3, "Jeff"); + name[4] = "Kinis"; // you can use operator[] too + + who_owes_who(edges(G).first, edges(G).second, G); + } + + cout << endl; + + return 0; +} diff --git a/examples/interior_property_accessor.expected b/examples/interior_property_accessor.expected new file mode 100644 index 00000000..5148599f --- /dev/null +++ b/examples/interior_property_accessor.expected @@ -0,0 +1,12 @@ +Jeremy owes Rich some money +Jeremy owes Andrew some money +Jeremy owes Jeff some money +Jeremy owes Kinis some money +Andrew owes Jeremy some money +Andrew owes Kinis some money +Jeff owes Jeremy some money +Jeff owes Rich some money +Jeff owes Kinis some money +Kinis owes Jeremy some money +Kinis owes Rich some money + diff --git a/examples/johnson.cpp b/examples/johnson.cpp new file mode 100644 index 00000000..aae30fd9 --- /dev/null +++ b/examples/johnson.cpp @@ -0,0 +1,107 @@ +//======================================================================= +// 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. +//======================================================================= +// This is a demonstration of using Johnson's algorithm for solving +// the all-pairs shortest-paths problem. The graph is from figure 36.1 +// page 556 of the CLR. +// +// Sample output: +// +// 0 1 2 3 4 5 +// 0 -> 0 0 -1 -5 0 -4 +// 1 -> inf 0 1 -3 2 -4 +// 2 -> inf 3 0 -4 1 -1 +// 3 -> inf 7 4 0 5 3 +// 4 -> inf 2 -1 -5 0 -2 +// 5 -> inf 8 5 1 6 0 + +#include +#include +#include +#include +#include +#include + +int +main() +{ + using namespace boost; + + typedef adjacency_list > Graph; + const int V = 6; + + typedef std::pair Edge; + Edge edge_array[] = { Edge(0,1), Edge(0,2), Edge(0,3), Edge(0,4), Edge(0,5), + Edge(1, 2), Edge(1,5), Edge(1,3), + Edge(2, 4), Edge(2,5), + Edge(3, 2), + Edge(4, 3), Edge(4,1), + Edge(5, 4) }; + const int E = sizeof(edge_array)/sizeof(Edge); + + Graph g(V, edge_array, edge_array + E); + + edge_property_accessor::type + w = get_edge_property_accessor(g, weight_tag()); + + int weights[] = { 0, 0, 0, 0, 0, + 3, -4, 8, + 1, 7, + 4, + -5, 2, + 6 }; + int* wp = weights; + + Graph::edge_iterator e,e_end; + for (boost::tie(e,e_end) = edges(g); e != e_end; ++e) + w[*e] = *wp++; + + std::vector d(V, std::numeric_limits::max()); + std::vector h(V); + std::vector c(V); + + //int D[V][V]; //SGI MIPSpro Compiler barfs for the type of D. + std::vector > D(6, std::vector(6)); + + johnson_all_pairs_shortest_paths(g, D, d.begin(), h.begin(), w, c.begin(), + get_vertex_property_accessor(g, id_tag())); + + std::cout << "\t"; + for (int k = 0; k < V; ++k) + std::cout << k << "\t"; + std::cout << std::endl; + for (int i = 0; i < V; ++i) { + std::cout << i << " ->\t"; + for (int j = 0; j < V; ++j) { + if (D[i][j] > 20 || D[i][j] < -20) + std::cout << "inf\t"; + else + std::cout << D[i][j] << "\t"; + } + std::cout << std::endl; + } + + return 0; +} diff --git a/examples/johnson.expected b/examples/johnson.expected new file mode 100644 index 00000000..55084c12 --- /dev/null +++ b/examples/johnson.expected @@ -0,0 +1,7 @@ + 0 1 2 3 4 5 +0 -> 0 0 -1 -5 0 -4 +1 -> inf 0 1 -3 2 -4 +2 -> inf 3 0 -4 1 -1 +3 -> inf 7 4 0 5 3 +4 -> inf 2 -1 -5 0 -2 +5 -> inf 8 5 1 6 0 diff --git a/examples/kevin_bacon.cpp b/examples/kevin_bacon.cpp new file mode 100644 index 00000000..eabef436 --- /dev/null +++ b/examples/kevin_bacon.cpp @@ -0,0 +1,143 @@ +//======================================================================= +// 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 +#include +#include +#include +#include +#include +#include +#include +#include + +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 plugin > EdgePlugin; + typedef plugin VertexPlugin; + typedef adjacency_list Graph; + + typedef Graph::vertex_descriptor Vertex; + typedef Graph::edge_descriptor Edge; + + typedef map NameVertexMap; + NameVertexMap actors; + Graph g; + + vertex_property_accessor::type + actor_name = get_vertex_property_accessor(g, name_tag()); + edge_property_accessor::type + connecting_movie = get_edge_property_accessor(g, name_tag()); + edge_property_accessor::type + weight = get_edge_property_accessor(g, weight_tag()); + + string line; + while (getline(datafile,line)) { + + list line_toks; + stringtok(line_toks, line, "|"); + + NameVertexMap::iterator pos; + bool inserted; + Vertex u, v; + + list::iterator i = line_toks.begin(); + + tie(pos, inserted) = actors.insert(make_pair(*i, Vertex())); + if (inserted) { + u = add_vertex(g); + 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); + actor_name[v] = *i; + pos->second = v; + } else + v = pos->second; + + Edge e; + tie(e, inserted) = add_edge(g, u, v); + if (inserted) { + connecting_movie[e] = movie_name; + weight[e] = 1; + } + } + + { + Graph::edge_iterator i, end; + for (tie(i, end) = edges(g); i != end; ++i) + cout << actor_name[source(*i, g)] << " was in " + << connecting_movie[*i] << " with " + << 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 bacon_number( num_vertices(g) ); + std::vector color( num_vertices(g) ); + std::vector predecessor( num_vertices(g) ); + + Vertex src = actors["Kevin Bacon"]; + + dijkstra_shortest_paths + (g, src, bacon_number.begin(), + get_edge_property_accessor(g, weight_tag()), + color.begin(), + get_vertex_property_accessor(g, id_tag()), + make_ucs_visitor(record_predecessors(predecessor.begin(), + on_edge_relaxed()))); + + Graph::vertex_iterator i, end; + for (tie(i,end) = vertices(g); i != end; ++i) + cout << actor_name[*i] << "'s bacon number is " + << bacon_number[*i] << endl; + + // use the predecessors to determine shortest paths to kevin... + } + + return 0; +} diff --git a/examples/kevin_bacon.dat b/examples/kevin_bacon.dat new file mode 100644 index 00000000..f8a0b7ca --- /dev/null +++ b/examples/kevin_bacon.dat @@ -0,0 +1,50 @@ +William Shatner|Loaded Weapon 1 (1993)|Denise Richards +Denise Richards|Wild Things (1998)|Kevin Bacon +Patrick Stewart|Prince of Egypt, The (1998)|Steve Martin +Steve Martin|Novocaine (2000)|Kevin Bacon +Gerard Depardieu|Unhook the Stars (1996)|Clint Howard +Clint Howard|My Dog Skip (2000)|Kevin Bacon +Sean Astin|White Water Summer (1987)|Kevin Bacon +Theodore Hesburgh|Rudy (1993)|Gerry Becker +Gerry Becker|Sleepers (1996)|Kevin Bacon +Henry Fonda|Midway (1976)|Robert Wagner +Robert Wagner|Wild Things (1998)|Kevin Bacon +Mark Hamill|Slipstream (1989)|Bill Paxton +Bill Paxton|Apollo 13 (1995)|Kevin Bacon +Harrison Ford|Random Hearts (1999)|Steve Altes +Steve Altes|Hollow Man (2000)|Kevin Bacon +Alec Guinness|Kafka (1991)|Theresa Russell +Theresa Russell|Wild Things (1998)|Kevin Bacon +Carrie Fisher|Soapdish (1991)|Elisabeth Shue +Elisabeth Shue|Hollow Man (2000)|Kevin Bacon +Sean Connery|Rising Sun (1993)|Peter Crombie +Peter Crombie|My Dog Skip (2000)|Kevin Bacon +Dana Young|Bersaglio mobile (1967)|Bebe Drake +Bebe Drake|Report to the Commissioner (1975)|William Devane +A. Paliakov|Kutuzov (1944)|Nikolai Brilling +Nikolai Brilling|Otello (1955)|Kathleen Byron +Kathleen Byron|Saving Private Ryan (1998)|Tom Hanks +Tom Hanks|Apollo 13 (1995)|Kevin Bacon +Zoya Barantsevich|Slesar i kantzler (1923)|Nikolai Panov +Nikolai Panov|Zhenshchina s kinzhalom (1916)|Zoia Karabanova +Zoia Karabanova|Song to Remember, A (1945)|William Challee +William Challee|Irish Whiskey Rebellion (1972)|William Devane +William Devane|Hollow Man (2000)|Kevin Bacon +P. Biryukov|Pikovaya dama (1910)|Aleksandr Gromov +Aleksandr Gromov|Tikhij Don (1930)|Yelena Maksimova +Yelena Maksimova|Bezottsovshchina (1976)|Lev Prygunov +Lev Prygunov|Saint, The (1997)|Elisabeth Shue +Yelena Chaika|Ostrov zabenya (1917)|Viktor Tourjansky +Viktor Tourjansky|Zagrobnaya skitalitsa (1915)|Olga Baclanova +Olga Baclanova|Freaks (1932)|Angelo Rossitto +Angelo Rossitto|Dark, The (1979)|William Devane +Christel Holch|Hvide Slavehandel, Den (1910/I)|Aage Schmidt +Aage Schmidt|Begyndte ombord, Det (1937)|Valso Holm +Valso Holm|Spion 503 (1958)|Max von Sydow +Max von Sydow|Judge Dredd (1995)|Diane Lane +Diane Lane|My Dog Skip (2000)|Kevin Bacon +Val Kilmer|Saint, The (1997)|Elisabeth Shue +Marilyn Monroe|Niagara (1953)|George Ives +George Ives|Stir of Echoes (1999)|Kevin Bacon +Jacques Perrin|Deserto dei tartari, Il (1976)|Vittorio Gassman +Vittorio Gassman|Sleepers (1996)|Kevin Bacon diff --git a/examples/kevin_bacon.expected b/examples/kevin_bacon.expected new file mode 100644 index 00000000..c49f55c6 --- /dev/null +++ b/examples/kevin_bacon.expected @@ -0,0 +1,101 @@ +William Shatner was in Loaded Weapon 1 (1993) with Denise Richards +Denise Richards was in Wild Things (1998) with Kevin Bacon +Patrick Stewart was in Prince of Egypt, The (1998) with Steve Martin +Steve Martin was in Novocaine (2000) with Kevin Bacon +Gerard Depardieu was in Unhook the Stars (1996) with Clint Howard +Clint Howard was in My Dog Skip (2000) with Kevin Bacon +Sean Astin was in White Water Summer (1987) with Kevin Bacon +Theodore Hesburgh was in Rudy (1993) with Gerry Becker +Gerry Becker was in Sleepers (1996) with Kevin Bacon +Henry Fonda was in Midway (1976) with Robert Wagner +Robert Wagner was in Wild Things (1998) with Kevin Bacon +Mark Hamill was in Slipstream (1989) with Bill Paxton +Bill Paxton was in Apollo 13 (1995) with Kevin Bacon +Harrison Ford was in Random Hearts (1999) with Steve Altes +Steve Altes was in Hollow Man (2000) with Kevin Bacon +Alec Guinness was in Kafka (1991) with Theresa Russell +Theresa Russell was in Wild Things (1998) with Kevin Bacon +Carrie Fisher was in Soapdish (1991) with Elisabeth Shue +Elisabeth Shue was in Hollow Man (2000) with Kevin Bacon +Sean Connery was in Rising Sun (1993) with Peter Crombie +Peter Crombie was in My Dog Skip (2000) with Kevin Bacon +Dana Young was in Bersaglio mobile (1967) with Bebe Drake +Bebe Drake was in Report to the Commissioner (1975) with William Devane +A. Paliakov was in Kutuzov (1944) with Nikolai Brilling +Nikolai Brilling was in Otello (1955) with Kathleen Byron +Kathleen Byron was in Saving Private Ryan (1998) with Tom Hanks +Tom Hanks was in Apollo 13 (1995) with Kevin Bacon +Zoya Barantsevich was in Slesar i kantzler (1923) with Nikolai Panov +Nikolai Panov was in Zhenshchina s kinzhalom (1916) with Zoia Karabanova +Zoia Karabanova was in Song to Remember, A (1945) with William Challee +William Challee was in Irish Whiskey Rebellion (1972) with William Devane +William Devane was in Hollow Man (2000) with Kevin Bacon +P. Biryukov was in Pikovaya dama (1910) with Aleksandr Gromov +Aleksandr Gromov was in Tikhij Don (1930) with Yelena Maksimova +Yelena Maksimova was in Bezottsovshchina (1976) with Lev Prygunov +Lev Prygunov was in Saint, The (1997) with Elisabeth Shue +Yelena Chaika was in Ostrov zabenya (1917) with Viktor Tourjansky +Viktor Tourjansky was in Zagrobnaya skitalitsa (1915) with Olga Baclanova +Olga Baclanova was in Freaks (1932) with Angelo Rossitto +Angelo Rossitto was in Dark, The (1979) with William Devane +Christel Holch was in Hvide Slavehandel, Den (1910/I) with Aage Schmidt +Aage Schmidt was in Begyndte ombord, Det (1937) with Valso Holm +Valso Holm was in Spion 503 (1958) with Max von Sydow +Max von Sydow was in Judge Dredd (1995) with Diane Lane +Diane Lane was in My Dog Skip (2000) with Kevin Bacon +Val Kilmer was in Saint, The (1997) with Elisabeth Shue +Marilyn Monroe was in Niagara (1953) with George Ives +George Ives was in Stir of Echoes (1999) with Kevin Bacon +Jacques Perrin was in Deserto dei tartari, Il (1976) with Vittorio Gassman +Vittorio Gassman was in Sleepers (1996) with Kevin Bacon +William Shatner's bacon number is 2 +Denise Richards's bacon number is 1 +Kevin Bacon's bacon number is 0 +Patrick Stewart's bacon number is 2 +Steve Martin's bacon number is 1 +Gerard Depardieu's bacon number is 2 +Clint Howard's bacon number is 1 +Sean Astin's bacon number is 1 +Theodore Hesburgh's bacon number is 2 +Gerry Becker's bacon number is 1 +Henry Fonda's bacon number is 2 +Robert Wagner's bacon number is 1 +Mark Hamill's bacon number is 2 +Bill Paxton's bacon number is 1 +Harrison Ford's bacon number is 2 +Steve Altes's bacon number is 1 +Alec Guinness's bacon number is 2 +Theresa Russell's bacon number is 1 +Carrie Fisher's bacon number is 2 +Elisabeth Shue's bacon number is 1 +Sean Connery's bacon number is 2 +Peter Crombie's bacon number is 1 +Dana Young's bacon number is 3 +Bebe Drake's bacon number is 2 +William Devane's bacon number is 1 +A. Paliakov's bacon number is 4 +Nikolai Brilling's bacon number is 3 +Kathleen Byron's bacon number is 2 +Tom Hanks's bacon number is 1 +Zoya Barantsevich's bacon number is 5 +Nikolai Panov's bacon number is 4 +Zoia Karabanova's bacon number is 3 +William Challee's bacon number is 2 +P. Biryukov's bacon number is 5 +Aleksandr Gromov's bacon number is 4 +Yelena Maksimova's bacon number is 3 +Lev Prygunov's bacon number is 2 +Yelena Chaika's bacon number is 5 +Viktor Tourjansky's bacon number is 4 +Olga Baclanova's bacon number is 3 +Angelo Rossitto's bacon number is 2 +Christel Holch's bacon number is 5 +Aage Schmidt's bacon number is 4 +Valso Holm's bacon number is 3 +Max von Sydow's bacon number is 2 +Diane Lane's bacon number is 1 +Val Kilmer's bacon number is 2 +Marilyn Monroe's bacon number is 2 +George Ives's bacon number is 1 +Jacques Perrin's bacon number is 2 +Vittorio Gassman's bacon number is 1 diff --git a/examples/knights_tour.cpp b/examples/knights_tour.cpp new file mode 100644 index 00000000..62de2fc9 --- /dev/null +++ b/examples/knights_tour.cpp @@ -0,0 +1,422 @@ +//======================================================================= +// 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 +#include +#include +#include +#include +#include +#include + +typedef std::pair Position; + +static Position knight_jumps[8] + = { Position(2, -1), Position(1, -2), Position(-1, -2), Position(-2, -1), + Position(-2, 1), Position(-1, 2), Position(1, 2 ), Position(2, 1 ) }; + +Position operator+(const Position& p1, const Position& p2) +{ + return Position(p1.first + p2.first, p1.second + p2.second); +} + +struct knights_tour_graph; + +struct knight_adjacency_iterator + : public boost::forward_iterator_helper< + knight_adjacency_iterator, Position, std::ptrdiff_t, Position*, Position> +{ + knight_adjacency_iterator() { } + knight_adjacency_iterator(int ii, Position p, const knights_tour_graph& g) + : pos(p), m_g(&g), i(ii) { valid_position(); } + Position operator*() const { return pos + knight_jumps[i]; } + void operator++() { ++i; valid_position(); } + bool operator==(const knight_adjacency_iterator& x) const + { return i == x.i; } +protected: + void valid_position(); + Position pos; + const knights_tour_graph* m_g; + int i; +}; + +struct knights_tour_graph +{ + typedef Position vertex_descriptor; + typedef std::pair edge_descriptor; + typedef knight_adjacency_iterator adjacency_iterator; + typedef void out_edge_iterator; + typedef void in_edge_iterator; + typedef void edge_iterator; + typedef void vertex_iterator; + typedef int degree_size_type; + typedef int vertices_size_type; + typedef int edges_size_type; + typedef boost::directed_tag directed_category; + typedef boost::disallow_parallel_edge_tag edge_parallel_category; + + knights_tour_graph(int n) + : m_board_size(n) { } + + int m_board_size; +}; + +void knight_adjacency_iterator::valid_position() +{ + Position new_pos = pos + knight_jumps[i]; + while (i < 8 && (new_pos.first < 0 || new_pos.second < 0 + || new_pos.first >= m_g->m_board_size + || new_pos.second >= m_g->m_board_size)) { + ++i; + new_pos = pos + knight_jumps[i]; + } +} + + +int num_vertices(const knights_tour_graph& g) { return g.m_board_size; } + +std::pair +adjacent_vertices(knights_tour_graph::vertex_descriptor v, const knights_tour_graph& g) +{ + typedef knights_tour_graph::adjacency_iterator Iter; + return std::make_pair(Iter(0, v, g), Iter(8, v, g)); +} + + +template +int number_of_successors(Vertex x, Graph g, Board board) { + int s_x = 0; + typename boost::graph_traits::adjacency_iterator i, end; + for (boost::tie(i, end) = adjacent_vertices(x, g); i != end; ++i) + if (get(board, *i) == -1) + ++s_x; + return s_x; +} + +struct compare_first { + template + bool operator()(const P& x, const P& y) { return x.first < y.first; } +}; + + +template +bool backtracking_search + (Graph& g, + typename boost::graph_traits::vertex_descriptor x, + TimePropertyAccessor time_pa) +{ + typedef typename boost::graph_traits::vertex_descriptor Vertex; + typedef std::pair P; + std::stack

S; + int time_stamp = 0; + S.push(std::make_pair(time_stamp, x)); + + while (!S.empty()) { + boost::tie(time_stamp, x) = S.top(); + put(time_pa, x, time_stamp); + + if (time_stamp == num_vertices(g) * num_vertices(g) - 1) + return true; // success! + + bool deadend = true; + typename boost::graph_traits::adjacency_iterator i, end; + for (boost::tie(i, end) = adjacent_vertices(x, g); i != end; ++i) + if (get(time_pa, *i) == -1) { + S.push(std::make_pair(time_stamp + 1, *i)); + deadend = false; + } + + if (deadend) { + put(time_pa, x, -1); + S.pop(); + boost::tie(time_stamp, x) = S.top(); + // unwind stack to unexplored vertex + while (get(time_pa, x) != -1) { + put(time_pa, x, -1); + S.pop(); + boost::tie(time_stamp, x) = S.top(); + } + } + + } // while (!S.empty()) + return false; +} + + +template +bool warnsdorff + (Graph& g, + typename boost::graph_traits::vertex_descriptor src, + TimePropertyAccessor time_pa) +{ + typedef typename boost::graph_traits::vertex_descriptor Vertex; + typedef std::pair P; + std::stack

S; + std::priority_queue, compare_first> Q; + int time_stamp = 0; + S.push(std::make_pair(time_stamp, src)); + + while (!S.empty()) { + Vertex x; + boost::tie(time_stamp, x) = S.top(); + put(time_pa, x, time_stamp); + S.pop(); + + if (time_stamp == num_vertices(g) * num_vertices(g) - 1) + return true; // success! + + typename boost::graph_traits::adjacency_iterator i, end; + boost::tie(i, end) = adjacent_vertices(x, g); + int num_succ; + for (; i != end; ++i) + if (get(time_pa, *i) == -1) { + num_succ = number_of_successors(*i, g, time_pa); + Q.push(std::make_pair(num_succ, *i)); + } + + if (Q.empty()) { // hit dead-end + put(time_pa, x, -1); + boost::tie(time_stamp, x) = S.top(); + while (get(time_pa, x) != -1) { // unwind stack + put(time_pa, x, -1); + S.pop(); + boost::tie(time_stamp, x) = S.top(); + } + } else { + for (; !Q.empty(); Q.pop()) { + boost::tie(num_succ, x) = Q.top(); + S.push(std::make_pair(time_stamp + 1, x)); + } + } + + } // while (!S.empty()) + return false; +} + + +struct board_accessor { + typedef int value_type; + typedef Position key_type; + typedef boost::read_write_property_accessor_tag category; + board_accessor(int* b, int n) : m_board(b), m_size(n) { } + friend int get(const board_accessor& ba, Position p); + friend void put(const board_accessor& ba, Position p, int v); + friend std::ostream& operator<<(std::ostream& os, const board_accessor& ba); +private: + int* m_board; + int m_size; +}; + +int get(const board_accessor& ba, Position p) { + return ba.m_board[p.first * ba.m_size + p.second]; +} +void put(const board_accessor& ba, Position p, int v) { + ba.m_board[p.first * ba.m_size + p.second] = v; +} + +std::ostream& operator<<(std::ostream& os, const board_accessor& ba) { + for (int i = 0; i < ba.m_size; ++i) { + for (int j = 0; j < ba.m_size; ++j) + os << get(ba, Position(i,j)) << "\t"; + os << std::endl; + } + return os; +} + +int +main(int argc, char* argv[]) +{ + int N; + if (argc == 2) + N = atoi(argv[1]); + else + N = 8; + + knights_tour_graph g(N); + int* board = new int[num_vertices(g) * num_vertices(g)]; + + board_accessor chessboard(board, num_vertices(g)); + + for (int i = 0; i < num_vertices(g); ++i) + for (int j = 0; j < num_vertices(g); ++j) + put(chessboard, Position(i,j), -1); + + bool ret = warnsdorff(g, Position(0,0), chessboard); + + if (ret) + for (int i = 0; i < num_vertices(g); ++i) { + for (int j = 0; j < num_vertices(g); ++j) + std::cout << get(chessboard, Position(i,j)) << "\t"; + std::cout << std::endl; + } + else + std::cout << "method failed" << std::endl; +} + +/* + +(* Improved Warnsdorff's Algorithm for the Problem of *) +(* the Knight *) +(* Mathematica 2.2 Version Copyright 1992-93 Arnd Roth *) + +knightJumps = {{2, -1}, {1, -2}, {-1, -2}, {-2, -1}, + {-2, 1}, {-1, 2}, {1, 2 }, {2, 1 }}; + +successors[s_, n_, position_] := +Block[{moves, onBoard}, + moves = Map[position + # &, knightJumps]; + (* moves over the edge of the chessboard are *) + (* invalid *) + onBoard = Select[moves, And @@ Thread[ + {0, 0} < # <= {n, n}] &]; + Select[onBoard, s[[Sequence @@ #]] == 0 &] +] + +numberOfSuccessors[s_, n_, position_] := +Length[successors[s, n, position]] + +mina[s_, n_, position_] := +(* successor(s) with least number of successors *) +Block[{localSuccessors, localNumbersOfSuccessors, + minimum}, + localSuccessors = successors[s, n, position]; + localNumbersOfSuccessors = + Map[numberOfSuccessors[s, n, #] &, + localSuccessors]; + minimum = Min[localNumbersOfSuccessors]; + localSuccessors[[Flatten[Positionition[ + localNumbersOfSuccessors, minimum]]]] +] + +mabst[destination_, successorlist_] := +(* successor(s) with greatest distance from *) +(* destination *) +Block[{vectors, distances, maximum}, + vectors = Map[destination - # &, successorlist]; + distances = Map[# . # &, vectors]; + maximum = Max[distances]; + successorlist[[Flatten[Positionition[ + distances, maximum]]]] +] + +improvedWarnsdorff[n_] := +(* main program *) +Block[{s, destination, position, localMina}, + (* initialize chessboard s *) + (* s[[x, y]] == 0 ==> square (x, y) is *) + (* untouched. *) + (* in the end, s contains the step numbers *) + (* at which every square was visited *) + s = Table[0, {n}, {n}]; + (* path should end near the following *) + destination = + {Round[n / 2] - 1 / 2, Round[n / 2] - 1 / 2}; + (* starting point in the corner of the board *) + position = {1, 1}; + s[[1, 1]] = 1; + Do[ + localMina = mina[s, n, position]; + If[Length[localMina] == 0, + Print["Blind alley"]; + (* algorithm failed *) + Break[] + ]; + position = If[Length[localMina] == 1, + First[localMina], + First[mabst[destination, + localMina]] + ]; + s[[First[position], Last[position]]] = + stepNumber, + {stepNumber, 2, n n}]; + s +] s + +*/ + + +#if 0 +template +bool recursive_backtracking(Vertex x, Graph& g, Board chessboard, int t) +{ + put(chessboard, x, t); + if (t == num_vertices(g) * num_vertices(g) - 1) + return true; // success! + + typename boost::graph_traits::adjacency_iterator i, end; + boost::tie(i, end) = adjacent_vertices(x, g); + for (; i != end; ++i) + if (get(chessboard, *i) == -1 + && recursive_backtracking(*i, g, chessboard, t + 1)) + return true; + put(chessboard, x, -1); + return false; +} +template +bool backtracking(Graph& g, Board chessboard) +{ + Position x(0,0); + int t = 0; + return recursive_backtracking(x, g, chessboard, t); +} + + + +template +bool recursive_warnsdorff(Vertex u, Graph& g, Board chessboard, int t) +{ + typename boost::graph_traits::adjacency_iterator i, end; + typedef std::pair P; + std::priority_queue, compare_first> Q; + int num_succ; + + put(chessboard, u, t); + if (t == num_vertices(g) * num_vertices(g) - 1) + return true; // success! + + for (boost::tie(i, end) = adjacent_vertices(u, g); i != end; ++i) + if (get(chessboard, *i) == -1) { + num_succ = number_of_successors(*i, g, chessboard); + Q.push(std::make_pair(num_succ, *i)); + } + for (; !Q.empty(); Q.pop()) { + Vertex v; + boost::tie(num_succ, v) = Q.top(); + if (recursive_warnsdorff(v, g, chessboard, t + 1)) + return true; + } + put(chessboard, u, -1); + return false; +} +template +bool warnsdorff(Graph& g, Board chessboard) +{ + Position start(0,0); + int t = 0; + return recursive_warnsdorff(start, g, chessboard, t); +} + +#endif diff --git a/examples/knights_tour.expected b/examples/knights_tour.expected new file mode 100644 index 00000000..a7f230b4 --- /dev/null +++ b/examples/knights_tour.expected @@ -0,0 +1,8 @@ +0 13 28 61 10 15 18 47 +29 36 11 14 27 46 9 16 +12 1 62 37 60 17 48 19 +35 30 59 54 49 26 45 8 +2 55 34 63 38 53 20 25 +31 58 39 52 23 50 7 44 +40 3 56 33 42 5 24 21 +57 32 41 4 51 22 43 6 diff --git a/examples/kruskal.cpp b/examples/kruskal.cpp new file mode 100644 index 00000000..32f424e1 --- /dev/null +++ b/examples/kruskal.cpp @@ -0,0 +1,91 @@ +//======================================================================= +// 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 + +#include +#include + +#include +#include +/* + + Sample output: + + Print the edge in MST: + 0 <--> 2 with weight of 1 + 3 <--> 4 with weight of 1 + 4 <--> 0 with weight of 1 + 1 <--> 3 with weight of 1 +*/ + + +int main(int argc, char* argv[]) +{ + using namespace boost; + using namespace std; + + typedef plugin weightp; + typedef adjacency_list< vecS, vecS, undirectedS, + no_plugin, weightp > Graph; + typedef Graph::edge_descriptor Edge; + typedef Graph::vertex_descriptor Vertex; + + typedef std::pair E; + const int num_nodes = 5; + E edges[] = { E(0,2), + E(1,1), E(1,3), E(1,4), + E(2,1), E(2,3), + E(3,4), + E(4,0), E(4,1) }; + int weights[] = { 1, + 2, 1, 2, + 7, 3, + 1, + 1, 1}; + + Graph G(num_nodes, edges, edges + sizeof(edges)/sizeof(E), weights); + edge_property_accessor::type weight + = get_edge_property_accessor(G, weight_tag()); + + typedef std::vector container; + std::vector spanning_tree_edges; + spanning_tree_edges.reserve(num_vertices(G)); + std::vector p(num_vertices(G)); + std::vector rank(num_vertices(G)); + + kruskal_minimum_spanning_tree(G, std::back_inserter(spanning_tree_edges), + rank.begin(), p.begin()); + + cout << "Print the edge in MST:" << endl; + for (std::vector::iterator ei = spanning_tree_edges.begin(); + ei != spanning_tree_edges.end(); ++ei) { + cout << source(*ei, G) << " <--> " + << target(*ei, G) + << " with weight of " << weight[*ei] + << endl; + } + + return 0; +} diff --git a/examples/kruskal.expected b/examples/kruskal.expected new file mode 100644 index 00000000..7fa4320f --- /dev/null +++ b/examples/kruskal.expected @@ -0,0 +1,5 @@ +Print the edge in MST: +0 <--> 2 with weight of 1 +3 <--> 4 with weight of 1 +4 <--> 0 with weight of 1 +1 <--> 3 with weight of 1 diff --git a/examples/miles_span.cpp b/examples/miles_span.cpp new file mode 100644 index 00000000..8e3298c8 --- /dev/null +++ b/examples/miles_span.cpp @@ -0,0 +1,127 @@ +//======================================================================= +// 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 +#include +#include +#include + +// A visitor class for accumulating the total length of the minimum +// spanning tree. The Distance template parameter is for a +// PropertyAccessor. +template +struct total_length_visitor : public boost::ucs_visitor<> { + typedef typename boost::property_traits::value_type D; + total_length_visitor(D& len, Distance d) + : _total_length(len), _distance(d) { } + template + inline void finish_vertex(Vertex s, Graph& g) { + _total_length += get(_distance, s); + } + D& _total_length; + Distance _distance; +}; + +// We will use the "y" utility field for keeping track of the state +// (color) of each vertex during the algorithm. The algorithm will +// need to access constants for white, gray, and black of the +// appropriate type (the type must match the type of the "y" utility +// field, which in this case is long), hence the following function +// definitions. The choice of constants is arbitrary. +namespace boost { + long white(long) { return 0; } // "unseen" + long gray(long) { return 2; } // "seen" + long black(long) { return 1; } // "known" +} + +int main(int argc, char* argv[]) +{ + using namespace boost; + Graph* g; + + unsigned long n = 100; + unsigned long n_weight = 0; + unsigned long w_weight = 0; + unsigned long p_weight = 0; + unsigned long d = 10; + long s = 0; + unsigned long r = 1; + char* file_name = NULL; + + while(--argc){ + if(sscanf(argv[argc],"-n%lu",&n)==1); + else if(sscanf(argv[argc],"-N%lu",&n_weight)==1); + else if(sscanf(argv[argc],"-W%lu",&w_weight)==1); + else if(sscanf(argv[argc],"-P%lu",&p_weight)==1); + else if(sscanf(argv[argc],"-d%lu",&d)==1); + else if(sscanf(argv[argc],"-r%lu",&r)==1); + else if(sscanf(argv[argc],"-s%ld",&s)==1); + else if(strcmp(argv[argc],"-v")==0) verbose = 1; + else if(strncmp(argv[argc],"-g",2)==0) file_name = argv[argc]+2; + else{ + fprintf(stderr, + "Usage: %s [-nN][-dN][-rN][-sN][-NN][-WN][-PN][-v][-gfoo]\n", + argv[0]); + return -2; + } + } + if (file_name) r = 1; + + while (r--) { + if (file_name) + g = restore_graph(file_name); + else + g = miles(n,n_weight,w_weight,p_weight,0L,d,s); + + if(g == NULL || g->n <= 1) { + fprintf(stderr,"Sorry, can't create the graph! (error code %ld)\n", + panic_code); + return-1; + } + + printf("The graph %s has %ld edges,\n", g->id, g->m / 2); + + long sp_length = 0; + + // Use the "z" utility field for distance. + typedef vertex_property_accessor >::type Distance; + Distance d = get_vertex_property_accessor(g, z_tag()); + total_length_visitor length_vis(sp_length, d); + + prim_minimum_spanning_tree(g, vertex(0,g), + get_vertex_property_accessor(g, z_tag()), + get_edge_property_accessor(g, length_tag()), + // Use the "y" utility field for color. + get_vertex_property_accessor(g, y_tag()), + get_vertex_property_accessor(g, id_tag()), + length_vis); + + printf(" and its minimum spanning tree has length %ld.\n", sp_length); + + gb_recycle(g); + s++; + } + return 0; +} diff --git a/examples/prim.cpp b/examples/prim.cpp new file mode 100644 index 00000000..70107ef6 --- /dev/null +++ b/examples/prim.cpp @@ -0,0 +1,70 @@ +//======================================================================= +// 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 +#include +#include +#include +#include + +// Sample output +// +// parent[0] = 0 +// parent[1] = 3 +// parent[2] = 0 +// parent[3] = 4 +// parent[4] = 0 + + +int main(int argc, char* argv[]) +{ + using namespace boost; + typedef adjacency_list < vecS, vecS, undirectedS, + plugin >, plugin > Graph; + typedef std::pair E; + const int num_nodes = 5; + E edges[] = { E(0,2), + E(1,1), E(1,3), E(1,4), + E(2,1), E(2,3), + E(3,4), + E(4,0) }; + int weights[] = { 1, 2, 1, 2, 7, 3, 1, 1}; + Graph G(num_nodes, edges, edges + sizeof(edges)/sizeof(E), weights); + + std::vector p(num_vertices(G)); + prim_minimum_spanning_tree + (G, *(vertices(G).first), + get_vertex_property_accessor(G, distance_tag()), + make_ucs_visitor(record_predecessors(p.begin(), on_edge_relaxed()))); + + for ( std::vector::iterator i = p.begin(); + i != p.end(); ++i) + std::cout << "parent[" << i - p.begin() + << "] = " << *i << std::endl; + return 0; +} + + + diff --git a/examples/prim.expected b/examples/prim.expected new file mode 100644 index 00000000..bbbf5166 --- /dev/null +++ b/examples/prim.expected @@ -0,0 +1,5 @@ +parent[0] = 0 +parent[1] = 3 +parent[2] = 0 +parent[3] = 4 +parent[4] = 0 diff --git a/examples/quick_tour.cpp b/examples/quick_tour.cpp new file mode 100644 index 00000000..36e618c2 --- /dev/null +++ b/examples/quick_tour.cpp @@ -0,0 +1,125 @@ +//======================================================================= +// 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 // for std::cout +#include // for std::pair +#include // for std::for_each +#include // for boost::tie +#include // for boost::graph_traits +#include + +using namespace boost; + +template struct exercise_vertex { + exercise_vertex(Graph& g_) : g(g_) { } + typedef typename graph_traits::vertex_descriptor Vertex; + void operator()(const Vertex& v) const + { + using namespace boost; + typename vertex_property_accessor::type + vertex_id = get_vertex_property_accessor(g, id_tag()); + std::cout << "vertex: " << get(vertex_id, v) << std::endl; + + // Write out the outgoing edges + std::cout << "\tout-edges: "; + typename graph_traits::out_edge_iterator out_i, out_end; + typename graph_traits::edge_descriptor e; + for (tie(out_i, out_end) = out_edges(v, g); + out_i != out_end; ++out_i) + { + e = *out_i; + Vertex src = source(e, g), targ = target(e, g); + std::cout << "(" << get(vertex_id, src) + << "," << get(vertex_id, targ) << ") "; + } + std::cout << std::endl; + + // Write out the incoming edges + std::cout << "\tin-edges: "; + typename graph_traits::in_edge_iterator in_i, in_end; + for (tie(in_i, in_end) = in_edges(v, g); in_i != in_end; ++in_i) + { + e = *in_i; + Vertex src = source(e, g), targ = target(e, g); + std::cout << "(" << get(vertex_id, src) + << "," << get(vertex_id, targ) << ") "; + } + std::cout << std::endl; + + // Write out all adjacent vertices + std::cout << "\tadjacent vertices: "; + typename graph_traits::adjacency_iterator ai, ai_end; + for (tie(ai,ai_end) = adjacent_vertices(v, g); ai != ai_end; ++ai) + std::cout << get(vertex_id, *ai) << " "; + std::cout << std::endl; + } + Graph& g; +}; + + +int main(int,char*[]) +{ + typedef std::pair E; + const int num_edges = 11; + // writing out the edges in the graph + E edge_array[num_edges] = { E(0,1), E(0,2), E(0,3), E(0,4), + E(2,0), E(3,0), E(2,4), E(3,1), + E(3,4), E(4,0), E(4,1) }; + const int num_vertices = 5; + + // create a typedef for the Graph type + typedef adjacency_list Graph; + + // declare a graph object + Graph g(num_vertices); + + boost::vertex_property_accessor::type + vertex_id = get_vertex_property_accessor(g, id_tag()); + + // add the edges to the graph object + for (int i = 0; i < num_edges; ++i) + add_edge(g, edge_array[i].first, edge_array[i].second); + + std::cout << "vertices(g) = "; + typedef graph_traits::vertex_iterator vertex_iter; + std::pair vp; + for (vp = vertices(g); vp.first != vp.second; ++vp.first) + std::cout << get(vertex_id, *vp.first) << " "; + std::cout << std::endl; + + std::cout << "edges(g) = "; + graph_traits::edge_iterator ei, ei_end; + for (tie(ei,ei_end) = edges(g); ei != ei_end; ++ei) + std::cout << "(" << get(vertex_id, source(*ei, g)) + << "," << get(vertex_id, target(*ei, g)) << ") "; + std::cout << std::endl; + + std::for_each(vertices(g).first, vertices(g).second, + exercise_vertex(g)); + + return 0; +} + + diff --git a/examples/quick_tour.expected b/examples/quick_tour.expected new file mode 100644 index 00000000..ec66d962 --- /dev/null +++ b/examples/quick_tour.expected @@ -0,0 +1,22 @@ +vertices(g) = 0 1 2 3 4 +edges(g) = (0,1) (0,2) (0,3) (0,4) (2,0) (2,4) (3,0) (3,1) (3,4) (4,0) (4,1) +vertex: 0 + out-edges: (0,1) (0,2) (0,3) (0,4) + in-edges: (2,0) (3,0) (4,0) + adjacent vertices: 1 2 3 4 +vertex: 1 + out-edges: + in-edges: (0,1) (3,1) (4,1) + adjacent vertices: +vertex: 2 + out-edges: (2,0) (2,4) + in-edges: (0,2) + adjacent vertices: 0 4 +vertex: 3 + out-edges: (3,0) (3,1) (3,4) + in-edges: (0,3) + adjacent vertices: 0 1 4 +vertex: 4 + out-edges: (4,0) (4,1) + in-edges: (0,4) (2,4) (3,4) + adjacent vertices: 0 1 diff --git a/examples/stl_concept_checks.cpp b/examples/stl_concept_checks.cpp new file mode 100644 index 00000000..ac744177 --- /dev/null +++ b/examples/stl_concept_checks.cpp @@ -0,0 +1,101 @@ +//======================================================================= +// 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 +#include + +#include +#include +#include +#include +#include +#include +#ifndef BOOST_NO_SLIST +#include +#endif + +int +main() +{ + typedef boost::trivial_iterator_skeleton TrivIterSkeleton; + typedef boost::mutable_trivial_iterator_skeleton MutTrivIterSkeleton; + REQUIRE(TrivIterSkeleton, TrivialIterator); + REQUIRE(MutTrivIterSkeleton, Mutable_TrivialIterator); + +#if defined(_ITERATOR_) + // VC++ STL implementation is not standard conformant and + // fails to pass these concept checks +#else + typedef std::vector Vector; + typedef std::deque Deque; + typedef std::list List; + + // VC++ missing pointer and const_pointer typedefs + REQUIRE(Vector, Mutable_RandomAccessContainer); + REQUIRE(Vector, BackInsertionSequence); + +#if !defined(__GNUC__) +#if !defined __sgi + // old deque iterator missing n + iter operation + REQUIRE(Deque, Mutable_RandomAccessContainer); +#endif + // warnings about signed and unsigned in old deque version + REQUIRE(Deque, FrontInsertionSequence); + REQUIRE(Deque, BackInsertionSequence); +#endif + + // VC++ missing pointer and const_pointer typedefs + REQUIRE(List, Mutable_ReversibleContainer); + REQUIRE(List, FrontInsertionSequence); + REQUIRE(List, BackInsertionSequence); + +#ifndef BOOST_NO_SLIST + typedef std::slist SList; + REQUIRE(SList, FrontInsertionSequence); +#endif + + typedef std::set Set; + typedef std::multiset MultiSet; + typedef std::map Map; + typedef std::multimap MultiMap; + + REQUIRE(Set, SortedAssociativeContainer); + REQUIRE(Set, SimpleAssociativeContainer); + REQUIRE(Set, UniqueAssociativeContainer); + + REQUIRE(MultiSet, SortedAssociativeContainer); + REQUIRE(MultiSet, SimpleAssociativeContainer); + REQUIRE(MultiSet, MultipleAssociativeContainer); + + REQUIRE(Map, SortedAssociativeContainer); + REQUIRE(Map, UniqueAssociativeContainer); + REQUIRE(Map, PairAssociativeContainer); + + REQUIRE(MultiMap, SortedAssociativeContainer); + REQUIRE(MultiMap, MultipleAssociativeContainer); + REQUIRE(MultiMap, PairAssociativeContainer); +#endif + + return 0; +} diff --git a/examples/stl_concept_checks.expected b/examples/stl_concept_checks.expected new file mode 100644 index 00000000..e69de29b diff --git a/examples/topo_sort.cpp b/examples/topo_sort.cpp new file mode 100644 index 00000000..8ef4c7b3 --- /dev/null +++ b/examples/topo_sort.cpp @@ -0,0 +1,83 @@ +//======================================================================= +// 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 +#include +#include +#include +#include +#include +#include + + +typedef std::pair Pair; + +/* + Topological sort example + + The topological sort algorithm creates a linear ordering + of the vertices such that if edge (u,v) appears in the graph, + then u comes before v in the ordering. + + Sample output: + + A topological ordering: 2 5 0 1 4 3 + +*/ + +int +main(int argc, char* argv[]) +{ + //begin + using namespace boost; + + /* Topological sort will need to color the graph. Here we use an + internal decorator, so we "plugin" the color to the graph. + */ + typedef adjacency_list > Graph; + + typedef boost::graph_traits::vertex_descriptor Vertex; + Pair edges[7] = { Pair(0,1), Pair(2,4), + Pair(2,5), + Pair(0,3), Pair(1,4), + Pair(4,3), Pair(5,5) }; + Graph G(6, edges, edges + 7); + + boost::vertex_property_accessor::type + id = get_vertex_property_accessor(G, id_tag()); + + typedef std::vector< Vertex > container; + container c; + topological_sort(G, std::back_inserter(c)); + + std::cout << "A topological ordering: "; + for (container::reverse_iterator ii = c.rbegin(); + ii != c.rend(); ++ii) + std::cout << id[*ii] << " "; + std::cout << std::endl; + + return 0; +} + diff --git a/examples/topo_sort.expected b/examples/topo_sort.expected new file mode 100644 index 00000000..aeb3f41f --- /dev/null +++ b/examples/topo_sort.expected @@ -0,0 +1 @@ +A topological ordering: 2 5 0 1 4 3 diff --git a/examples/undirected.cpp b/examples/undirected.cpp new file mode 100644 index 00000000..65629f42 --- /dev/null +++ b/examples/undirected.cpp @@ -0,0 +1,115 @@ +//======================================================================= +// 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 +#include +#include +#include + +/* + This example demonstrates the differences between directed and + undirected graphs. + + Sample Output + + in a directed graph is (u,v) == (v,u) ? 0 + weight[(u,v)] = 1.2 + weight[(v,u)] = 2.4 + in an undirected graph is (u,v) == (v,u) ? 1 + weight[(u,v)] = 3.1 + weight[(v,u)] = 3.1 + the edges incident to v: (0,1) + + + */ + +int +main(int, char*[]) +{ + using namespace boost; + using namespace std; + + const int V = 2; + + typedef plugin Weight; + typedef adjacency_list UndirectedGraph; + UndirectedGraph undigraph(V); + + typedef adjacency_list DirectedGraph; + DirectedGraph digraph(V); + + + { + graph_traits::vertex_descriptor u, v; + u = vertex(0, digraph); + v = vertex(1, digraph); + add_edge(digraph, u, v, Weight(1.2)); + add_edge(digraph, v, u, Weight(2.4)); + graph_traits::edge_descriptor e1, e2; + bool found; + tie(e1,found) = edge(u, v, digraph); + tie(e2,found) = edge(v, u, digraph); + cout << "in a directed graph is "; + cout << "(u,v) == (v,u) ? " << (e1 == e2) << endl; + + edge_property_accessor::type + weight = get_edge_property_accessor(digraph, weight_tag()); + cout << "weight[(u,v)] = " << get(weight, e1) << endl; + cout << "weight[(v,u)] = " << get(weight, e2) << endl; + } + { + graph_traits::vertex_descriptor u, v; + u = vertex(0, undigraph); + v = vertex(1, undigraph); + add_edge(undigraph, u, v, Weight(3.1)); + graph_traits::edge_descriptor e1, e2; + bool found; + tie(e1,found) = edge(u, v, undigraph); + tie(e2,found) = edge(v, u, undigraph); + cout << "in an undirected graph is "; + cout << "(u,v) == (v,u) ? " << (e1 == e2) << endl; + + edge_property_accessor::type + weight = get_edge_property_accessor(undigraph, weight_tag()); + cout << "weight[(u,v)] = " << get(weight, e1) << endl; + cout << "weight[(v,u)] = " << get(weight, e2) << endl; + } + + // Vertices in undirected graphs don't have "out-edges", they have + // "incident" edges, but we still use the out_edge() function. + // Similarly, "in" and "out" have no meaning in undirected graphs + // but we still use source() and target() to access the unordered + // pair of vertices connected by the edge. + cout << "the edges incident to v: "; + graph_traits::out_edge_iterator e, e_end; + graph_traits::vertex_descriptor + s = vertex(0, undigraph); + for (tie(e, e_end) = out_edges(s, undigraph); e != e_end; ++e) + cout << "(" << source(*e, undigraph) + << "," << target(*e, undigraph) << ")" << endl; + + return 0; +} diff --git a/examples/undirected.expected b/examples/undirected.expected new file mode 100644 index 00000000..015a7afc --- /dev/null +++ b/examples/undirected.expected @@ -0,0 +1,7 @@ +in a directed graph is (u,v) == (v,u) ? 0 +weight[(u,v)] = 1.2 +weight[(v,u)] = 2.4 +in an undirected graph is (u,v) == (v,u) ? 1 +weight[(u,v)] = 3.1 +weight[(v,u)] = 3.1 +the edges incident to v: (0,1) diff --git a/examples/vector_as_graph.cpp b/examples/vector_as_graph.cpp new file mode 100644 index 00000000..a65f7681 --- /dev/null +++ b/examples/vector_as_graph.cpp @@ -0,0 +1,102 @@ +//======================================================================= +// 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 +#include +#include +#include +#include +#include +#include +#include + +using namespace std; +using namespace boost; + +// Sample output +// order of discovery: s r w v t x y u +// order of finish: s r w v t x y u + +int main() +{ +#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + enum { r, s, t, u, v, w, x, y, N }; + char name[] = { 'r', 's', 't', 'u', 'v', 'w', 'x', 'y' }; + + typedef std::vector< std::vector > Graph; + Graph g(N); + + g[s].push_back(r); + + g[s].push_back(r); + g[r].push_back(v); + g[s].push_back(w); + g[w].push_back(t); + g[w].push_back(x); + g[t].push_back(x); + g[u].push_back(t); + g[x].push_back(y); + g[y].push_back(u); + + vector color(N, white(default_color_type())); + vector discover(N), finish(N); + typedef vector::iterator iter_t; + int time = 0; + breadth_first_search + (g, int(s), make_bfs_visitor(make_pair(stamp_times(discover.begin(), time, + on_discover_vertex()), + stamp_times(finish.begin(), time, + on_finish_vertex()))), + color.begin()); + + std::cout << "order of discovery: "; + + // Perform some STL magic to order the vertices according to their + // discover time + vector discover_order(N); + boost::integer_range ir(0,N); + copy(ir.begin(), ir.end(), discover_order.begin()); + sort(discover_order.begin(), discover_order.end(), + indirect_cmp >(discover.begin())); + + for (int i = 0; i < N; ++i) + std::cout << name[ discover_order[i] ] << " "; + std::cout << std::endl; + + std::cout << "order of finish: "; + + // Order vertices according to their finish time + vector finish_order(N); + copy(ir.begin(), ir.end(), finish_order.begin()); + sort(finish_order.begin(), finish_order.end(), + indirect_cmp >(finish.begin())); + + for (int j = 0; j < N; ++j) + std::cout << name[ finish_order[j] ] << " "; + std::cout << std::endl; +#else + std::cout << "The vec_adj_list module requires partial specialization" << std::endl; +#endif + return 0; +} diff --git a/examples/vector_as_graph.expected b/examples/vector_as_graph.expected new file mode 100644 index 00000000..1f728794 --- /dev/null +++ b/examples/vector_as_graph.expected @@ -0,0 +1,2 @@ +order of discovery: s r w v t x y u +order of finish: s r w v t x y u diff --git a/examples/vertex_basics.cpp b/examples/vertex_basics.cpp new file mode 100644 index 00000000..5e3a6a51 --- /dev/null +++ b/examples/vertex_basics.cpp @@ -0,0 +1,174 @@ +//======================================================================= +// 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 +#include +#include + +using namespace std; +using namespace boost; + + +/* + Vertex Basics + + This example demonstrates the GGCL Vertex interface. + + Sample output: + + vertices(g) = 0 1 2 3 4 + vertex id: 0 + out-edges: (0,1) (0,2) (0,3) (0,4) + in-edges: (2,0) (3,0) (4,0) + adjacent vertices: 1 2 3 4 + + vertex id: 1 + out-edges: + in-edges: (0,1) (3,1) (4,1) + adjacent vertices: + + vertex id: 2 + out-edges: (2,0) (2,4) + in-edges: (0,2) + adjacent vertices: 0 4 + + vertex id: 3 + out-edges: (3,0) (3,1) (3,4) + in-edges: (0,3) + adjacent vertices: 0 1 4 + + vertex id: 4 + out-edges: (4,0) (4,1) + in-edges: (0,4) (2,4) (3,4) + adjacent vertices: 0 1 + + + */ + + +/* some helper functors for output */ + +template +struct print_edge { + print_edge(Graph& g) : G(g) { } + + typedef typename boost::graph_traits::edge_descriptor Edge; + typedef typename boost::graph_traits::vertex_descriptor Vertex; + void operator()(Edge e) const + { + typename boost::vertex_property_accessor::type + id = get_vertex_property_accessor(G, id_tag()); + + Vertex src = source(e, G); + Vertex targ = target(e, G); + + cout << "(" << id[src] << "," << id[targ] << ") "; + } + + Graph& G; +}; + +template +struct print_index { + print_index(Graph& g) : G(g){ } + + typedef typename boost::graph_traits::vertex_descriptor Vertex; + void operator()(Vertex c) const + { + typename boost::vertex_property_accessor::type + id = get_vertex_property_accessor(G, id_tag()); + cout << id[c] << " "; + } + + Graph& G; +}; + + +template +struct exercise_vertex { + typedef typename boost::graph_traits::vertex_descriptor Vertex; + + exercise_vertex(Graph& _g) : g(_g) { } + + void operator()(Vertex v) const + { + typename boost::vertex_property_accessor::type + id = get_vertex_property_accessor(g, id_tag()); + + cout << "vertex id: " << id[v] << endl; + + cout << "out-edges: "; + for_each(out_edges(v, g).first, out_edges(v,g).second, + print_edge(g)); + + cout << endl; + + cout << "in-edges: "; + for_each(in_edges(v, g).first, in_edges(v,g).second, + print_edge(g)); + + cout << endl; + + cout << "adjacent vertices: "; + for_each(adjacent_vertices(v,g).first, + adjacent_vertices(v,g).second, print_index(g)); + cout << endl << endl; + } + + Graph& g; +}; + + +int +main() +{ + typedef adjacency_list MyGraphType; + + typedef pair 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) }; + + /* Construct a graph using the edge_array*/ + MyGraphType g(5); + for (int i=0; i<11; ++i) + add_edge(g, edge_array[i].first, edge_array[i].second); + + boost::vertex_property_accessor::type + id = get_vertex_property_accessor(g, id_tag()); + + cout << "vertices(g) = "; + boost::graph_traits::vertex_iterator vi; + for (vi = vertices(g).first; vi != vertices(g).second; ++vi) + std::cout << id[*vi] << " "; + std::cout << std::endl; + + /* Use the STL for_each algorithm to "exercise" all + of the vertices in the graph */ + for_each(vertices(g).first, vertices(g).second, + exercise_vertex(g)); + + return 0; +} diff --git a/examples/vertex_basics.expected b/examples/vertex_basics.expected new file mode 100644 index 00000000..96a103d9 --- /dev/null +++ b/examples/vertex_basics.expected @@ -0,0 +1,26 @@ +vertices(g) = 0 1 2 3 4 +vertex id: 0 +out-edges: (0,1) (0,2) (0,3) (0,4) +in-edges: (2,0) (3,0) (4,0) +adjacent vertices: 1 2 3 4 + +vertex id: 1 +out-edges: +in-edges: (0,1) (3,1) (4,1) +adjacent vertices: + +vertex id: 2 +out-edges: (2,0) (2,4) +in-edges: (0,2) +adjacent vertices: 0 4 + +vertex id: 3 +out-edges: (3,0) (3,1) (3,4) +in-edges: (0,3) +adjacent vertices: 0 1 4 + +vertex id: 4 +out-edges: (4,0) (4,1) +in-edges: (0,4) (2,4) (3,4) +adjacent vertices: 0 1 + diff --git a/examples/visitor.cpp b/examples/visitor.cpp new file mode 100644 index 00000000..5f4066d6 --- /dev/null +++ b/examples/visitor.cpp @@ -0,0 +1,121 @@ +//======================================================================= +// 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. +//======================================================================= +// +// Sample output +// +// DFS categorized directed graph +// tree: 0 --> 2 +// tree: 2 --> 3 +// tree: 3 --> 4 +// back: 4 --> 0 +// tree: 4 --> 1 +// back: 1 --> 1 +// back: 1 --> 3 +// forward or cross: 3 --> 1 +// forward or cross: 2 --> 1 +// +// BFS categorized directed graph +// tree: 0 --> 2 +// tree: 2 --> 1 +// back or cross: 1 --> 1 +// tree: 2 --> 3 +// back or cross: 3 --> 1 +// back or cross: 1 --> 3 +// tree: 3 --> 4 +// back or cross: 4 --> 0 +// back or cross: 4 --> 1 + +#include +#include + +#include +#include +#include +#include + +#include "boost/graph/visitors.hpp" +#include "boost/graph/adjacency_list.hpp" +#include "boost/graph/breadth_first_search.hpp" +#include "boost/graph/depth_first_search.hpp" + +using namespace boost; +using namespace std; + +template +struct edge_printer : public base_visitor > { + typedef Tag event_filter; + edge_printer(std::string edge_t) : m_edge_type(edge_t) { } + template + void operator()(Edge e, Graph& G) { + std::cout << m_edge_type << ": " << source(e, G) + << " --> " << target(e, G) << std::endl; + } + std::string m_edge_type; +}; +template +edge_printer print_edge(std::string type, Tag) { + return edge_printer(type); +} + +int +main(int argc, char* argv[]) +{ + + using namespace boost; + + typedef adjacency_list<> Graph; + typedef std::pair E; + E edges[] = { 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) }; + Graph G(5, edges, edges + sizeof(edges)/sizeof(E)); + + typedef boost::graph_traits::vertex_descriptor Vertex; + typedef boost::graph_traits::vertices_size_type size_type; + + std::vector c(num_vertices(G)); + std::vector d(num_vertices(G)); + std::vector f(num_vertices(G)); + + cout << "DFS categorized directed graph" << endl; + depth_first_search(G, make_dfs_visitor( + std::make_pair(print_edge("tree", on_tree_edge()), + std::make_pair(print_edge("back", on_back_edge()), + print_edge("forward or cross", on_forward_or_cross_edge()) + ))), + c.begin()); + + cout << endl << "BFS categorized directed graph" << endl; + boost::breadth_first_search + (G, vertex(0, G), make_bfs_visitor( + std::make_pair(print_edge("tree", on_tree_edge()), + print_edge("cycle", on_cycle_edge()))), + c.begin()); + + return 0; +} + diff --git a/examples/visitor.expected b/examples/visitor.expected new file mode 100644 index 00000000..18bad31f --- /dev/null +++ b/examples/visitor.expected @@ -0,0 +1,21 @@ +DFS categorized directed graph +tree: 0 --> 2 +tree: 2 --> 1 +back: 1 --> 1 +tree: 1 --> 3 +back: 3 --> 1 +tree: 3 --> 4 +back: 4 --> 0 +back: 4 --> 1 +forward or cross: 2 --> 3 + +BFS categorized directed graph +tree: 0 --> 2 +tree: 2 --> 1 +tree: 2 --> 3 +cycle: 1 --> 1 +cycle: 1 --> 3 +cycle: 3 --> 1 +tree: 3 --> 4 +cycle: 4 --> 0 +cycle: 4 --> 1