diff --git a/doc/DijkstraVisitor.html b/doc/DijkstraVisitor.html index e8c8c6c9..1f25bc84 100644 --- a/doc/DijkstraVisitor.html +++ b/doc/DijkstraVisitor.html @@ -80,7 +80,7 @@ the search. w -An object of type DistanceMap. +An object of type WeightMap. diff --git a/doc/directed_graph.html b/doc/directed_graph.html new file mode 100644 index 00000000..d17038c4 --- /dev/null +++ b/doc/directed_graph.html @@ -0,0 +1,191 @@ + + + +Boost Graph Library: Directed Graph + +C++ Boost + +
+ +

+
+directed_graph<VertexProp, EdgeProp, GraphProp>
+
+

+ + +

+The directed_graph class template is is a simplified version +of the BGL adjacency list. This class is provided for ease of use, but +may not perform as well as custom-defined adjacency list classes. Instances +of this template model the BidirectionalGraph, VertexIndexGraph, and +EdgeIndexGraph concepts. + +

Example

+ +A simple examples of creating a directed_graph is available here libs/graph/example/directed_graph.cpp. +

+ + +

+  typedef boost::directed_graph<> Graph;
+  Graph g;
+  boost::graph_traits::vertex_descriptor v0 = g.add_vertex();
+  boost::graph_traits::vertex_descriptor v1 = g.add_vertex();
+
+  g.add_edge(v0, v1);
+
+ +

Template Parameters

+ +

+ + + + + + + + + + + + + + + + + + + + + +
ParameterDescriptionDefault
VertexPropA property map for the graph vertices. 
EdgePropA property map for the graph edges. 
GraphPropA property map for the graph itself.
+

+ +

Where Defined

+ +

+boost/graph/directed_graph.hpp + +

+ +
+


+ + +
Copyright © 2000-2001 +Jeremy Siek, +Indiana University (jsiek@osl.iu.edu)
+Lie-Quan Lee, Indiana University (llee@cs.indiana.edu)
+Andrew Lumsdaine, +Indiana University (lums@osl.iu.edu) +
+ + + + + + +Boost Graph Library: Directed Graph + +C++ Boost + +
+ +

+
+directed_graph<VertexProp, EdgeProp, GraphProp>
+
+

+ + +

+The directed_graph class template is is a simplified version +of the BGL adjacency list. This class is provided for ease of use, but +may not perform as well as custom-defined adjacency list classes. Instances +of this template model the BidirectionalGraph, VertexIndexGraph, and +EdgeIndexGraph concepts. + +

Example

+ +

+ + +

+  typedef boost::directed_graph<> Graph;
+  Graph g;
+  Graph::vertex_descriptor v0 = g.add_vertex();
+  Graph::vertex_descriptor v1 = g.add_vertex();
+
+  g.add_edge(v0, v1);
+
+ +

Template Parameters

+ +

+ + + + + + + + + + + + + + + + + + + + + +
ParameterDescriptionDefault
VertexPropA property map for the graph vertices. 
EdgePropA property map for the graph edges. 
GraphPropA property map for the graph itself.
+

+ +

Where Defined

+ +

+boost/graph/directed_graph.hpp + +

+ +
+


+ + +
Copyright © 2000-2001 +Jeremy Siek, +Indiana University (jsiek@osl.iu.edu)
+Lie-Quan Lee, Indiana University (llee@cs.indiana.edu)
+Andrew Lumsdaine, +Indiana University (lums@osl.iu.edu) +
+ + + diff --git a/doc/grid_graph.html b/doc/grid_graph.html index bebbd1c2..100c97ec 100644 --- a/doc/grid_graph.html +++ b/doc/grid_graph.html @@ -69,7 +69,7 @@

Defined in boost/graph/grid_graph.hpp - with all functions in the boost namespace. All examples are available in a single program file in libs/graph/example/grid_graph_example.cpp + with all functions in the boost namespace. A simple examples of creating and iterating over a grid_graph is available here libs/graph/example/grid_graph_example.cpp. An example of adding properties to a grid_graph is also available libs/graph/example/grid_graph_properties.cpp

Template Parameters

diff --git a/doc/planar_face_traversal.html b/doc/planar_face_traversal.html index c52fa8b8..9a93799d 100644 --- a/doc/planar_face_traversal.html +++ b/doc/planar_face_traversal.html @@ -97,7 +97,7 @@ and might produce the output New face: 1 2 5 4 New face: 2 3 4 5 New face: 3 0 1 4 - New face: 2 3 0 1 + New face: 1 0 3 2

Visitor Event Points

diff --git a/doc/table_of_contents.html b/doc/table_of_contents.html index 6032e9cc..090053bb 100644 --- a/doc/table_of_contents.html +++ b/doc/table_of_contents.html @@ -101,6 +101,10 @@
  • Graph classes
    1. adjacency_list
    2. +
        +
      1. directed_graph
      2. +
      3. undirected_graph
      4. +
    3. adjacency_matrix
    4. compressed_sparse_row_graph
  • diff --git a/doc/topology.html b/doc/topology.html index 24271c0c..57f53e57 100644 --- a/doc/topology.html +++ b/doc/topology.html @@ -124,8 +124,8 @@ class convex_topology struct point { point() { } - double& operator[](std::size_t i) {return values[i];} - const double& operator[](std::size_t i) const {return values[i];} + double& operator[](std::size_t i) {return values[i];} + const double& operator[](std::size_t i) const {return values[i];} private: double values[Dims]; @@ -157,7 +157,7 @@ class hypercube_topology : public convex_topology { public: explicit hypercube_topology(double scaling = 1.0); - hypercube_topology(RandomNumberGenerator& gen, double scaling = 1.0); + hypercube_topology(RandomNumberGenerator& gen, double scaling = 1.0); point_type random_point() const; }; @@ -173,13 +173,13 @@ class square_topology : public hypercube_topology< { public: explicit square_topology(double scaling = 1.0); - square_topology(RandomNumberGenerator& gen, double scaling = 1.0); + square_topology(RandomNumberGenerator& gen, double scaling = 1.0); };

    Class template cube_topology

    -

    Class template cube_topology is a two-dimensional +

    Class template cube_topology is a three-dimensional hypercube topology.

    @@ -188,7 +188,7 @@ class cube_topology : public hypercube_topology
     
    @@ -209,7 +209,7 @@ class ball_topology : public convex_topology<D
     {
     public:
       explicit ball_topology(double radius = 1.0);
    -  ball_topology(RandomNumberGenerator& gen, double radius = 1.0); 
    +  ball_topology(RandomNumberGenerator& gen, double radius = 1.0); 
       point_type random_point() const;
     };
     
    @@ -225,13 +225,13 @@ class circle_topology : public ball_topology<2, { public: explicit circle_topology(double radius = 1.0); - circle_topology(RandomNumberGenerator& gen, double radius = 1.0); + circle_topology(RandomNumberGenerator& gen, double radius = 1.0); };

    Class template sphere_topology

    -

    Class template sphere_topology is a two-dimensional +

    Class template sphere_topology is a three-dimensional ball topology.

    @@ -240,7 +240,7 @@ class sphere_topology : public ball_topology<3,
     {
      public:
       explicit sphere_topology(double radius = 1.0);
    -  sphere_topology(RandomNumberGenerator& gen, double radius = 1.0);
    +  sphere_topology(RandomNumberGenerator& gen, double radius = 1.0);
     };
     
    @@ -258,7 +258,7 @@ class heart_topology typedef unspecified point_type; heart_topology(); - heart_topology(RandomNumberGenerator& gen); + heart_topology(RandomNumberGenerator& gen); point_type random_point() const; double distance(point_type a, point_type b) const; point_type move_position_toward(point_type a, double fraction, point_type b) const; diff --git a/doc/undirected_graph.html b/doc/undirected_graph.html new file mode 100644 index 00000000..09a55b0c --- /dev/null +++ b/doc/undirected_graph.html @@ -0,0 +1,96 @@ + + + +Boost Graph Library: Undirected Graph + +C++ Boost + +
    + +

    +
    +undirected_graph<VertexProp, EdgeProp, GraphProp>
    +
    +

    + + +

    +The undirected_graph class template is is a simplified version +of the BGL adjacency list. This class is provided for ease of use, but +may not perform as well as custom-defined adjacency list classes. Instances +of this template model the BidirectionalGraph, VertexIndexGraph, and +EdgeIndexGraph concepts. + +

    Example

    + +A simple example of creating an undirected_graph is available here libs/graph/example/undirected_graph.cpp +

    + + +

    +  typedef boost::undirected_graph<> Graph;
    +  Graph g;
    +  boost::graph_traits::vertex_descriptor v0 = g.add_vertex();
    +  boost::graph_traits::vertex_descriptor v1 = g.add_vertex();
    +
    +  g.add_edge(v0, v1);
    +
    + +

    Template Parameters

    + +

    + + + + + + + + + + + + + + + + + + + + + +
    ParameterDescriptionDefault
    VertexPropA property map for the graph vertices. 
    EdgePropA property map for the graph edges. 
    GraphPropA property map for the graph itself.
    +

    + +

    Where Defined

    + +

    +boost/graph/undirected_graph.hpp + +

    + +
    +


    + + +
    Copyright © 2000-2001 +Jeremy Siek, +Indiana University (jsiek@osl.iu.edu)
    +Lie-Quan Lee, Indiana University (llee@cs.indiana.edu)
    +Andrew Lumsdaine, +Indiana University (lums@osl.iu.edu) +
    + + + diff --git a/example/Jamfile.v2 b/example/Jamfile.v2 index fa7ebf9d..ca46194a 100644 --- a/example/Jamfile.v2 +++ b/example/Jamfile.v2 @@ -20,6 +20,7 @@ exe bron_kerbosch_print_cliques : bron_kerbosch_print_cliques.cpp ; exe bron_kerbosch_clique_number : bron_kerbosch_clique_number.cpp ; exe mcgregor_subgraphs_example : mcgregor_subgraphs_example.cpp ; exe grid_graph_example : grid_graph_example.cpp ; +exe grid_graph_properties : grid_graph_properties.cpp ; exe bipartite_example : bipartite_example.cpp ; exe fr_layout : fr_layout.cpp ; exe canonical_ordering : canonical_ordering.cpp ; @@ -33,3 +34,7 @@ exe stoer_wagner : stoer_wagner.cpp ; exe bfs-example : bfs-example.cpp ; exe bfs-example2 : bfs-example2.cpp ; exe dfs-example : dfs-example.cpp ; +exe adjacency_list_io : adjacency_list_io.cpp ; +exe undirected_adjacency_list : undirected_adjacency_list.cpp ; +exe directed_graph : directed_graph.cpp ; +exe undirected_graph : undirected_graph.cpp ; diff --git a/example/directed_graph.cpp b/example/directed_graph.cpp new file mode 100644 index 00000000..bb308aa5 --- /dev/null +++ b/example/directed_graph.cpp @@ -0,0 +1,26 @@ +//======================================================================= +// Copyright 2012 +// Authors: David Doria +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +//======================================================================= + +#include // A subclass to provide reasonable arguments to adjacency_list for a typical directed graph + +int main(int,char*[]) +{ + // directed_graph is a subclass of adjacency_list which gives you object oriented access to functions + // like add_vertex and add_edge, which makes the code easier to understand. However, it hard codes many + // of the template parameters, so it is much less flexible. + + typedef boost::directed_graph<> Graph; + Graph g; + boost::graph_traits::vertex_descriptor v0 = g.add_vertex(); + boost::graph_traits::vertex_descriptor v1 = g.add_vertex(); + + g.add_edge(v0, v1); + + return 0; +} diff --git a/example/grid_graph_properties.cpp b/example/grid_graph_properties.cpp new file mode 100644 index 00000000..37d252a8 --- /dev/null +++ b/example/grid_graph_properties.cpp @@ -0,0 +1,40 @@ +//======================================================================= +// Copyright 2012 David Doria +// Authors: David Doria +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +//======================================================================= + +#include +#include +#include + +int main(int argc, char* argv[]) +{ + // A 2D grid graph + typedef boost::grid_graph<2> GraphType; + + // Create a 5x5 graph + const unsigned int dimension = 5; + boost::array lengths = { { dimension, dimension } }; + GraphType graph(lengths); + + // Get the index map of the grid graph + typedef boost::property_map::const_type indexMapType; + indexMapType indexMap(get(boost::vertex_index, graph)); + + // Create a float for every node in the graph + boost::vector_property_map dataMap(num_vertices(graph), indexMap); + + // Associate the value 2.0 with the node at position (0,1) in the grid + boost::graph_traits::vertex_descriptor v = { { 0, 1 } }; + put(dataMap, v, 2.0f); + + // Get the data at the node at position (0,1) in the grid + float retrieved = get(dataMap, v); + std::cout << "Retrieved value: " << retrieved << std::endl; + + return 0; +} diff --git a/example/undirected.cpp b/example/undirected_adjacency_list.cpp similarity index 100% rename from example/undirected.cpp rename to example/undirected_adjacency_list.cpp diff --git a/example/undirected.expected b/example/undirected_adjacency_list.expected similarity index 100% rename from example/undirected.expected rename to example/undirected_adjacency_list.expected diff --git a/example/undirected_graph.cpp b/example/undirected_graph.cpp new file mode 100644 index 00000000..d926c7b5 --- /dev/null +++ b/example/undirected_graph.cpp @@ -0,0 +1,30 @@ +//======================================================================= +// Copyright 2012 +// Authors: David Doria +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +//======================================================================= + +#include +#include + +typedef boost::undirected_graph Graph; + +int main(int,char*[]) +{ + // Create a graph object + Graph g; + + // Add vertices + boost::graph_traits::vertex_descriptor v0 = g.add_vertex(); + boost::graph_traits::vertex_descriptor v1 = g.add_vertex(); + boost::graph_traits::vertex_descriptor v2 = g.add_vertex(); + + // Add edges + g.add_edge(v0, v1); + g.add_edge(v1, v2); + + return 0; +} diff --git a/include/boost/graph/adjacency_list_io.hpp b/include/boost/graph/adjacency_list_io.hpp index 30d87b10..547c0290 100644 --- a/include/boost/graph/adjacency_list_io.hpp +++ b/include/boost/graph/adjacency_list_io.hpp @@ -215,7 +215,7 @@ struct PropertyPrinter template PropertyPrinter& operator () ( std::ostream& out, const Val& v ) { - typename property_map::type ps = get(Tag(), *graph); + typename property_map::const_type ps = get(Tag(), *graph); out << ps[ v ] <<" "; PropertyPrinter print(*graph); print(out, v); diff --git a/include/boost/graph/astar_search.hpp b/include/boost/graph/astar_search.hpp index 316e7063..132dca02 100644 --- a/include/boost/graph/astar_search.hpp +++ b/include/boost/graph/astar_search.hpp @@ -158,6 +158,7 @@ namespace boost { template void tree_edge(Edge e, const Graph& g) { + using boost::get; m_decreased = relax(e, g, m_weight, m_predecessor, m_distance, m_combine, m_compare); @@ -173,6 +174,7 @@ namespace boost { template void gray_target(Edge e, const Graph& g) { + using boost::get; m_decreased = relax(e, g, m_weight, m_predecessor, m_distance, m_combine, m_compare); @@ -189,6 +191,7 @@ namespace boost { template void black_target(Edge e, const Graph& g) { + using boost::get; m_decreased = relax(e, g, m_weight, m_predecessor, m_distance, m_combine, m_compare); diff --git a/include/boost/graph/biconnected_components.hpp b/include/boost/graph/biconnected_components.hpp index 9586f9a2..0fdbad0d 100644 --- a/include/boost/graph/biconnected_components.hpp +++ b/include/boost/graph/biconnected_components.hpp @@ -28,17 +28,23 @@ namespace boost { template struct biconnected_components_visitor : public dfs_visitor<> { biconnected_components_visitor - (ComponentMap comp, std::size_t& c, DiscoverTimeMap dtm, + (ComponentMap comp, std::size_t& c, + std::size_t& children_of_root, DiscoverTimeMap dtm, std::size_t& dfs_time, LowPointMap lowpt, PredecessorMap pred, - OutputIterator out, Stack& S, DFSVisitor vis) - : comp(comp), c(c), children_of_root(0), dtm(dtm), - dfs_time(dfs_time), lowpt(lowpt), - pred(pred), out(out), S(S), vis(vis) { } + OutputIterator out, Stack& S, + ArticulationVector& is_articulation_point, IndexMap index_map, + DFSVisitor vis) + : comp(comp), c(c), children_of_root(children_of_root), + dtm(dtm), dfs_time(dfs_time), lowpt(lowpt), + pred(pred), out(out), S(S), + is_articulation_point(is_articulation_point), + index_map(index_map), vis(vis) { } template void initialize_vertex(const Vertex& u, Graph& g) @@ -89,8 +95,7 @@ namespace boost typename boost::graph_traits::vertex_descriptor src = source(e, g); typename boost::graph_traits::vertex_descriptor tgt = target(e, g); - if ( ( tgt != get(pred, src) || get(pred, src) == src ) && - get(dtm, tgt) < get(dtm, src) ) { + if ( tgt != get(pred, src) ) { S.push(e); put(lowpt, src, min BOOST_PREVENT_MACRO_SUBSTITUTION(get(lowpt, src), @@ -111,40 +116,41 @@ namespace boost BOOST_USING_STD_MIN(); Vertex parent = get(pred, u); if (parent == u) { // Root of tree is special - if (children_of_root >= 2) { - *out++ = u; - } - return; - } - put(lowpt, parent, - min BOOST_PREVENT_MACRO_SUBSTITUTION(get(lowpt, parent), + is_articulation_point[get(index_map, u)] = (children_of_root > 1); + } else { + put(lowpt, parent, + min BOOST_PREVENT_MACRO_SUBSTITUTION(get(lowpt, parent), get(lowpt, u))); - if ( get(lowpt, u) >= get(dtm, parent) ) { - if ( get(pred, parent) != parent ) { - *out++ = parent; - } - while ( get(dtm, source(S.top(), g)) >= get(dtm, u) ) { + if ( get(lowpt, u) >= get(dtm, parent) ) { + is_articulation_point[get(index_map, parent)] = true; + while ( get(dtm, source(S.top(), g)) >= get(dtm, u) ) { + put(comp, S.top(), c); + S.pop(); + } + assert (source(S.top(), g) == parent); + assert (target(S.top(), g) == u); put(comp, S.top(), c); S.pop(); + ++c; } - assert (source(S.top(), g) == parent); - assert (target(S.top(), g) == u); - put(comp, S.top(), c); - S.pop(); - ++c; + } + if ( is_articulation_point[get(index_map, u)] ) { + *out++ = u; } vis.finish_vertex(u, g); } ComponentMap comp; std::size_t& c; - std::size_t children_of_root; + std::size_t& children_of_root; DiscoverTimeMap dtm; std::size_t& dfs_time; LowPointMap lowpt; PredecessorMap pred; OutputIterator out; Stack& S; + ArticulationVector& is_articulation_point; + IndexMap index_map; DFSVisitor vis; }; @@ -168,14 +174,16 @@ namespace boost vertex_t> )); std::size_t num_components = 0; + std::size_t children_of_root; std::size_t dfs_time = 0; - std::stack S; + std::stack S; + std::vector is_articulation_point(num_vertices(g)); - biconnected_components_visitor, - DFSVisitor> - vis(comp, num_components, dtm, dfs_time, lowpt, pred, out, - S, dfs_vis); + biconnected_components_visitor, + std::vector, VertexIndexMap, DFSVisitor> + vis(comp, num_components, children_of_root, dtm, dfs_time, + lowpt, pred, out, S, is_articulation_point, index_map, dfs_vis); depth_first_search(g, visitor(vis).vertex_index_map(index_map)); diff --git a/include/boost/graph/compressed_sparse_row_graph.hpp b/include/boost/graph/compressed_sparse_row_graph.hpp index caa27a90..75e61659 100644 --- a/include/boost/graph/compressed_sparse_row_graph.hpp +++ b/include/boost/graph/compressed_sparse_row_graph.hpp @@ -1134,7 +1134,6 @@ add_vertices(typename BOOST_DIR_CSR_GRAPH_TYPE::vertices_size_type count, BOOST_ Vertex old_num_verts_plus_one = g.m_forward.m_rowstart.size(); EdgeIndex numedges = g.m_forward.m_rowstart.back(); g.m_forward.m_rowstart.resize(old_num_verts_plus_one + count, numedges); - g.m_backward.m_rowstart.resize(old_num_verts_plus_one + count, numedges); g.vertex_properties().resize(num_vertices(g)); return old_num_verts_plus_one - 1; } diff --git a/include/boost/graph/detail/histogram_sort.hpp b/include/boost/graph/detail/histogram_sort.hpp index b359a73d..e8fbadb8 100644 --- a/include/boost/graph/detail/histogram_sort.hpp +++ b/include/boost/graph/detail/histogram_sort.hpp @@ -60,6 +60,7 @@ count_starts // Put the degree of each vertex v into m_rowstart[v + 1] for (KeyIterator i = begin; i != end; ++i) { if (key_filter(*i)) { + assert (key_transform(*i) < numkeys); ++starts[key_transform(*i) + 1]; } } @@ -99,6 +100,7 @@ histogram_sort(KeyIterator key_begin, KeyIterator key_end, for (KeyIterator i = key_begin; i != key_end; ++i, ++v1i) { if (key_filter(*i)) { vertices_size_type source = key_transform(*i); + assert (source < numkeys); EdgeIndex insert_pos = current_insert_positions[source]; ++current_insert_positions[source]; values1_out[insert_pos] = *v1i; @@ -137,6 +139,7 @@ histogram_sort(KeyIterator key_begin, KeyIterator key_end, for (KeyIterator i = key_begin; i != key_end; ++i, ++v1i, ++v2i) { if (key_filter(*i)) { vertices_size_type source = key_transform(*i); + assert (source < numkeys); EdgeIndex insert_pos = current_insert_positions[source]; ++current_insert_positions[source]; values1_out[insert_pos] = *v1i; @@ -163,6 +166,7 @@ histogram_sort_inplace(KeyIterator key_begin, std::vector insert_positions(rowstart, rowstart + numkeys); // 2. Swap the sources and targets into place for (size_t i = 0; i < rowstart[numkeys]; ++i) { + assert (key_transform(key_begin[i]) < numkeys); // While edge i is not in the right bucket: while (!(i >= rowstart[key_transform(key_begin[i])] && i < insert_positions[key_transform(key_begin[i])])) { // Add a slot in the right bucket @@ -197,6 +201,7 @@ histogram_sort_inplace(KeyIterator key_begin, std::vector insert_positions(rowstart, rowstart + numkeys); // 2. Swap the sources and targets into place for (size_t i = 0; i < rowstart[numkeys]; ++i) { + assert (key_transform(key_begin[i]) < numkeys); // While edge i is not in the right bucket: while (!(i >= rowstart[key_transform(key_begin[i])] && i < insert_positions[key_transform(key_begin[i])])) { // Add a slot in the right bucket diff --git a/include/boost/graph/detail/read_graphviz_spirit.hpp b/include/boost/graph/detail/read_graphviz_spirit.hpp index 4e8b22e5..99464698 100644 --- a/include/boost/graph/detail/read_graphviz_spirit.hpp +++ b/include/boost/graph/detail/read_graphviz_spirit.hpp @@ -604,7 +604,9 @@ bool read_graphviz_spirit(MultiPassIterator begin, MultiPassIterator end, scanner_t scan(begin, end, policies); - return p.parse(scan); + bool ok = p.parse(scan); + m_graph.finish_building_graph(); + return ok; } } // namespace boost diff --git a/include/boost/graph/edmonds_karp_max_flow.hpp b/include/boost/graph/edmonds_karp_max_flow.hpp index 43cc592d..6aba1d05 100644 --- a/include/boost/graph/edmonds_karp_max_flow.hpp +++ b/include/boost/graph/edmonds_karp_max_flow.hpp @@ -52,21 +52,21 @@ namespace boost { // find minimum residual capacity along the augmenting path FlowValue delta = (std::numeric_limits::max)(); - e = p[sink]; + e = get(p, sink); do { BOOST_USING_STD_MIN(); - delta = min BOOST_PREVENT_MACRO_SUBSTITUTION(delta, residual_capacity[e]); + delta = min BOOST_PREVENT_MACRO_SUBSTITUTION(delta, get(residual_capacity, e)); u = source(e, g); - e = p[u]; + e = get(p, u); } while (u != src); // push delta units of flow along the augmenting path - e = p[sink]; + e = get(p, sink); do { - residual_capacity[e] -= delta; - residual_capacity[reverse_edge[e]] += delta; + put(residual_capacity, e, get(residual_capacity, e) - delta); + put(residual_capacity, get(reverse_edge, e), get(residual_capacity, get(reverse_edge, e)) + delta); u = source(e, g); - e = p[u]; + e = get(p, u); } while (u != src); } @@ -94,22 +94,22 @@ namespace boost { typename graph_traits::out_edge_iterator ei, e_end; for (boost::tie(u_iter, u_end) = vertices(g); u_iter != u_end; ++u_iter) for (boost::tie(ei, e_end) = out_edges(*u_iter, g); ei != e_end; ++ei) - res[*ei] = cap[*ei]; + put(res, *ei, get(cap, *ei)); - color[sink] = Color::gray(); - while (color[sink] != Color::white()) { + put(color, sink, Color::gray()); + while (get(color, sink) != Color::white()) { boost::queue Q; breadth_first_search (detail::residual_graph(g, res), src, Q, make_bfs_visitor(record_edge_predecessors(pred, on_tree_edge())), color); - if (color[sink] != Color::white()) + if (get(color, sink) != Color::white()) detail::augment(g, src, sink, pred, res, rev); } // while typename property_traits::value_type flow = 0; for (boost::tie(ei, e_end) = out_edges(src, g); ei != e_end; ++ei) - flow += (cap[*ei] - res[*ei]); + flow += (get(cap, *ei) - get(res, *ei)); return flow; } // edmonds_karp_max_flow() diff --git a/include/boost/graph/graphml.hpp b/include/boost/graph/graphml.hpp index 2239d966..028cdc26 100644 --- a/include/boost/graph/graphml.hpp +++ b/include/boost/graph/graphml.hpp @@ -262,7 +262,7 @@ write_graphml(std::ostream& out, const Graph& g, VertexIndexMap vertex_index, for (dynamic_properties::const_iterator i = dp.begin(); i != dp.end(); ++i) { std::string key_id = "key" + lexical_cast(key_count++); - if (i->second->key() == typeid(Graph)) + if (i->second->key() == typeid(Graph*)) graph_key_ids[i->first] = key_id; else if (i->second->key() == typeid(vertex_descriptor)) vertex_key_ids[i->first] = key_id; @@ -273,7 +273,7 @@ write_graphml(std::ostream& out, const Graph& g, VertexIndexMap vertex_index, std::string type_name = "string"; mpl::for_each(get_type_name(i->second->value(), type_names, type_name)); out << " second->key() == typeid(Graph) ? "graph" : (i->second->key() == typeid(vertex_descriptor) ? "node" : "edge")) << "\"" + << (i->second->key() == typeid(Graph*) ? "graph" : (i->second->key() == typeid(vertex_descriptor) ? "node" : "edge")) << "\"" << " attr.name=\"" << i->first << "\"" << " attr.type=\"" << type_name << "\"" << " />\n"; @@ -287,10 +287,12 @@ write_graphml(std::ostream& out, const Graph& g, VertexIndexMap vertex_index, // Output graph data for (dynamic_properties::const_iterator i = dp.begin(); i != dp.end(); ++i) { - if (i->second->key() == typeid(Graph)) + if (i->second->key() == typeid(Graph*)) { + // The const_cast here is just to get typeid correct for property + // map key; the graph should not be mutated using it. out << " first] << "\">" - << encode_char_entities(i->second->get_string(g)) << "\n"; + << encode_char_entities(i->second->get_string(const_cast(&g))) << "\n"; } } diff --git a/include/boost/graph/graphviz.hpp b/include/boost/graph/graphviz.hpp index 718220ff..3fc5b1cd 100644 --- a/include/boost/graph/graphviz.hpp +++ b/include/boost/graph/graphviz.hpp @@ -25,10 +25,15 @@ #include #include #include +#include +#include #include #include +#include #include #include +#include +#include namespace boost { @@ -713,6 +718,9 @@ class mutate_graph virtual void // RG: need new second parameter to support BGL subgraphs set_graph_property(const id_t& key, const id_t& value) = 0; + + virtual void + finish_building_graph() = 0; }; template @@ -781,6 +789,8 @@ class mutate_graph_impl : public mutate_graph put(key, dp_, &graph_, value); } + void finish_building_graph() {} + protected: MutableGraph& graph_; @@ -790,6 +800,109 @@ class mutate_graph_impl : public mutate_graph std::map bgl_edges; }; +template +class mutate_graph_impl > + : public mutate_graph +{ + typedef compressed_sparse_row_graph CSRGraph; + typedef typename graph_traits::vertices_size_type bgl_vertex_t; + typedef typename graph_traits::edges_size_type bgl_edge_t; + typedef typename graph_traits::edge_descriptor edge_descriptor; + + public: + mutate_graph_impl(CSRGraph& graph, dynamic_properties& dp, + std::string node_id_prop) + : graph_(graph), dp_(dp), vertex_count(0), node_id_prop_(node_id_prop) { } + + ~mutate_graph_impl() {} + + void finish_building_graph() { + typedef compressed_sparse_row_graph TempCSRGraph; + TempCSRGraph temp(edges_are_unsorted_multi_pass, + edges_to_add.begin(), edges_to_add.end(), + counting_iterator(0), + vertex_count); + set_property(temp, graph_all, get_property(graph_, graph_all)); + graph_.assign(temp); // Copies structure, not properties + std::vector edge_permutation_from_sorting(num_edges(temp)); + BGL_FORALL_EDGES_T(e, temp, TempCSRGraph) { + edge_permutation_from_sorting[temp[e]] = e; + } + typedef tuple v_prop; + BOOST_FOREACH(const v_prop& t, vertex_props) { + put(get<0>(t), dp_, get<1>(t), get<2>(t)); + } + typedef tuple e_prop; + BOOST_FOREACH(const e_prop& t, edge_props) { + put(get<0>(t), dp_, edge_permutation_from_sorting[get<1>(t)], get<2>(t)); + } + } + + bool is_directed() const + { + return + boost::is_convertible< + typename boost::graph_traits::directed_category, + boost::directed_tag>::value; + } + + virtual void do_add_vertex(const node_t& node) + { + // Add the node to the graph. + bgl_vertex_t v = vertex_count++; + + // Set up a mapping from name to BGL vertex. + bgl_nodes.insert(std::make_pair(node, v)); + + // node_id_prop_ allows the caller to see the real id names for nodes. + vertex_props.push_back(make_tuple(node_id_prop_, v, node)); + } + + void + do_add_edge(const edge_t& edge, const node_t& source, const node_t& target) + { + bgl_edge_t result = edges_to_add.size(); + edges_to_add.push_back(std::make_pair(bgl_nodes[source], bgl_nodes[target])); + bgl_edges.insert(std::make_pair(edge, result)); + } + + void + set_node_property(const id_t& key, const node_t& node, const id_t& value) + { + vertex_props.push_back(make_tuple(key, bgl_nodes[node], value)); + } + + void + set_edge_property(const id_t& key, const edge_t& edge, const id_t& value) + { + edge_props.push_back(make_tuple(key, bgl_edges[edge], value)); + } + + void + set_graph_property(const id_t& key, const id_t& value) + { + /* RG: pointer to graph prevents copying */ + put(key, dp_, &graph_, value); + } + + + protected: + CSRGraph& graph_; + dynamic_properties& dp_; + bgl_vertex_t vertex_count; + std::string node_id_prop_; + std::vector > vertex_props; + std::vector > edge_props; + std::vector > edges_to_add; + std::map bgl_nodes; + std::map bgl_edges; +}; + } } } // end namespace boost::detail::graph #ifdef BOOST_GRAPH_USE_SPIRIT_PARSER diff --git a/include/boost/graph/isomorphism.hpp b/include/boost/graph/isomorphism.hpp index bbdd1f7b..f8e44867 100644 --- a/include/boost/graph/isomorphism.hpp +++ b/include/boost/graph/isomorphism.hpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -195,69 +196,123 @@ namespace boost { } private: + struct match_continuation { + enum {pos_G2_vertex_loop, pos_fi_adj_loop, pos_dfs_num} position; + typedef typename graph_traits::vertex_iterator vertex_iterator; + std::pair G2_verts; + typedef typename graph_traits::adjacency_iterator adjacency_iterator; + std::pair fi_adj; + edge_iter iter; + int dfs_num_k; + }; + bool match(edge_iter iter, int dfs_num_k) { + std::vector k; + typedef typename graph_traits::vertex_iterator vertex_iterator; + std::pair G2_verts(vertices(G2)); + typedef typename graph_traits::adjacency_iterator adjacency_iterator; + std::pair fi_adj; + vertex1_t i, j; + + recur: if (iter != ordered_edges.end()) { - vertex1_t i = source(*iter, G1), j = target(*iter, G2); + i = source(*iter, G1); + j = target(*iter, G2); if (dfs_num[i] > dfs_num_k) { - vertex1_t kp1 = dfs_vertices[dfs_num_k + 1]; - BGL_FORALL_VERTICES_T(u, G2, Graph2) { - if (invariant1(kp1) == invariant2(u) && in_S[u] == false) { - f[kp1] = u; - in_S[u] = true; - num_edges_on_k = 0; - - if (match(iter, dfs_num_k + 1)) -#if 0 - // dwa 2003/7/11 -- this *HAS* to be a bug! - ; -#endif - return true; + G2_verts = vertices(G2); + while (G2_verts.first != G2_verts.second) { + { + vertex2_t u = *G2_verts.first; + vertex1_t kp1 = dfs_vertices[dfs_num_k + 1]; + if (invariant1(kp1) == invariant2(u) && in_S[u] == false) { + { + f[kp1] = u; + in_S[u] = true; + num_edges_on_k = 0; - in_S[u] = false; + match_continuation new_k; + new_k.position = match_continuation::pos_G2_vertex_loop; + new_k.G2_verts = G2_verts; + new_k.iter = iter; + new_k.dfs_num_k = dfs_num_k; + k.push_back(new_k); + ++dfs_num_k; + goto recur; + } + } } +G2_loop_k: ++G2_verts.first; } } else if (dfs_num[j] > dfs_num_k) { - vertex1_t k = dfs_vertices[dfs_num_k]; - num_edges_on_k -= - count_if(adjacent_vertices(f[k], G2), make_indirect_pmap(in_S)); - - for (int jj = 0; jj < dfs_num_k; ++jj) { - vertex1_t j = dfs_vertices[jj]; - num_edges_on_k -= count(adjacent_vertices(f[j], G2), f[k]); + { + vertex1_t vk = dfs_vertices[dfs_num_k]; + num_edges_on_k -= + count_if(adjacent_vertices(f[vk], G2), make_indirect_pmap(in_S)); + + for (int jj = 0; jj < dfs_num_k; ++jj) { + vertex1_t j = dfs_vertices[jj]; + num_edges_on_k -= count(adjacent_vertices(f[j], G2), f[vk]); + } } if (num_edges_on_k != 0) - return false; - BGL_FORALL_ADJ_T(f[i], v, G2, Graph2) - if (invariant2(v) == invariant1(j) && in_S[v] == false) { - f[j] = v; - in_S[v] = true; - num_edges_on_k = 1; - BOOST_USING_STD_MAX(); - int next_k = max BOOST_PREVENT_MACRO_SUBSTITUTION(dfs_num_k, max BOOST_PREVENT_MACRO_SUBSTITUTION(dfs_num[i], dfs_num[j])); - if (match(boost::next(iter), next_k)) - return true; - in_S[v] = false; + goto return_point_false; + fi_adj = adjacent_vertices(f[i], G2); + while (fi_adj.first != fi_adj.second) { + { + vertex2_t v = *fi_adj.first; + if (invariant2(v) == invariant1(j) && in_S[v] == false) { + f[j] = v; + in_S[v] = true; + num_edges_on_k = 1; + BOOST_USING_STD_MAX(); + int next_k = max BOOST_PREVENT_MACRO_SUBSTITUTION(dfs_num_k, max BOOST_PREVENT_MACRO_SUBSTITUTION(dfs_num[i], dfs_num[j])); + match_continuation new_k; + new_k.position = match_continuation::pos_fi_adj_loop; + new_k.fi_adj = fi_adj; + new_k.iter = iter; + new_k.dfs_num_k = dfs_num_k; + ++iter; + dfs_num_k = next_k; + k.push_back(new_k); + goto recur; + } } - - +fi_adj_loop_k:++fi_adj.first; + } } else { if (container_contains(adjacent_vertices(f[i], G2), f[j])) { ++num_edges_on_k; - if (match(boost::next(iter), dfs_num_k)) - return true; + match_continuation new_k; + new_k.position = match_continuation::pos_dfs_num; + k.push_back(new_k); + ++iter; + goto recur; } } } else - return true; - return false; - } + goto return_point_true; + goto return_point_false; + { + return_point_true: return true; + + return_point_false: + if (k.empty()) return false; + const match_continuation& this_k = k.back(); + switch (this_k.position) { + case match_continuation::pos_G2_vertex_loop: {G2_verts = this_k.G2_verts; iter = this_k.iter; dfs_num_k = this_k.dfs_num_k; k.pop_back(); in_S[*G2_verts.first] = false; i = source(*iter, G1); j = target(*iter, G2); goto G2_loop_k;} + case match_continuation::pos_fi_adj_loop: {fi_adj = this_k.fi_adj; iter = this_k.iter; dfs_num_k = this_k.dfs_num_k; k.pop_back(); in_S[*fi_adj.first] = false; i = source(*iter, G1); j = target(*iter, G2); goto fi_adj_loop_k;} + case match_continuation::pos_dfs_num: {k.pop_back(); goto return_point_false;} + default: assert (!"Bad position"); abort(); + } + } + } }; diff --git a/include/boost/graph/property_maps/null_property_map.hpp b/include/boost/graph/property_maps/null_property_map.hpp index f6273481..09ff55e3 100644 --- a/include/boost/graph/property_maps/null_property_map.hpp +++ b/include/boost/graph/property_maps/null_property_map.hpp @@ -29,7 +29,7 @@ namespace boost // The null_property_map only has a put() function. template - void put(null_property_map& pm, const K& key, const V& value) + void put(null_property_map& /*pm*/, const K& /*key*/, const V& /*value*/) { } // A helper function for intantiating null property maps. diff --git a/include/boost/graph/subgraph.hpp b/include/boost/graph/subgraph.hpp index b98c3902..1860c8ce 100644 --- a/include/boost/graph/subgraph.hpp +++ b/include/boost/graph/subgraph.hpp @@ -131,15 +131,29 @@ public: // copy constructor subgraph(const subgraph& x) - : m_graph(x.m_graph), m_parent(x.m_parent), m_edge_counter(x.m_edge_counter) + : m_parent(x.m_parent), m_edge_counter(x.m_edge_counter) , m_global_vertex(x.m_global_vertex), m_global_edge(x.m_global_edge) { - // Do a deep copy (recursive). - for(typename ChildrenList::const_iterator i = x.m_children.begin(); - i != x.m_children.end(); ++i) + if(x.is_root()) { - m_children.push_back(new subgraph( **i )); + m_graph = x.m_graph; } + // Do a deep copy (recursive). + // Only the root graph is copied, the subgraphs contain + // only references to the global vertices they own. + typename subgraph::children_iterator i,i_end; + boost::tie(i,i_end) = x.children(); + for(; i != i_end; ++i) + { + subgraph child = this->create_subgraph(); + child = *i; + vertex_iterator vi,vi_end; + boost::tie(vi,vi_end) = vertices(*i); + for (;vi!=vi_end;++vi) + { + add_vertex(*vi,child); + } + } } diff --git a/include/boost/graph/vector_as_graph.hpp b/include/boost/graph/vector_as_graph.hpp index ee0df4bc..c1799993 100644 --- a/include/boost/graph/vector_as_graph.hpp +++ b/include/boost/graph/vector_as_graph.hpp @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -71,7 +72,7 @@ namespace boost { out_edge_iterator; typedef void in_edge_iterator; typedef void edge_iterator; - typedef typename integer_range::iterator vertex_iterator; + typedef counting_iterator vertex_iterator; typedef directed_tag directed_category; typedef allow_parallel_edge_tag edge_parallel_category; typedef vector_as_graph_traversal_tag traversal_category; @@ -178,14 +179,11 @@ namespace boost { // source() and target() already provided for pairs in graph_traits.hpp template - std::pair - ::iterator, - typename boost::integer_range - ::iterator > + std::pair, + boost::counting_iterator > vertices(const std::vector& v) { - typedef typename boost::integer_range - ::iterator Iter; + typedef boost::counting_iterator Iter; return std::make_pair(Iter(0), Iter(v.size())); } diff --git a/src/read_graphviz_new.cpp b/src/read_graphviz_new.cpp index 130a112c..6c6608c7 100644 --- a/src/read_graphviz_new.cpp +++ b/src/read_graphviz_new.cpp @@ -787,6 +787,7 @@ namespace read_graphviz_detail { for (properties::const_iterator i = root_graph_props.begin(); i != root_graph_props.end(); ++i) { mg->set_graph_property(i->first, i->second); } + mg->finish_building_graph(); } } // end namespace read_graphviz_detail diff --git a/test/graphviz_test.cpp b/test/graphviz_test.cpp index 765175df..adc29034 100644 --- a/test/graphviz_test.cpp +++ b/test/graphviz_test.cpp @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -41,33 +42,46 @@ typedef std::pair edge_t; typedef std::map mass_map_t; typedef std::map weight_map_t; -template +template +bool test_graph(std::istream& dotfile, graph_t& graph, + std::size_t correct_num_vertices, + mass_map_t const& masses, + weight_map_t const& weights, + std::string const& node_id, + std::string const& g_name, + NameMap name, + MassMap mass, + WeightMap weight); + +template bool test_graph(std::istream& dotfile, std::size_t correct_num_vertices, mass_map_t const& masses, weight_map_t const& weights, std::string const& node_id = "node_id", std::string const& g_name = std::string()) { + graph_t g; + return test_graph(dotfile, g, correct_num_vertices, masses, weights, node_id, g_name, + get(vertex_name, g), get(vertex_color, g), get(edge_weight, g)); +} + +template +bool test_graph(std::istream& dotfile, graph_t& graph, + std::size_t correct_num_vertices, + mass_map_t const& masses, + weight_map_t const& weights, + std::string const& node_id, + std::string const& g_name, + NameMap name, + MassMap mass, + WeightMap weight) { - typedef property < vertex_name_t, std::string, - property < vertex_color_t, float > > vertex_p; - typedef property < edge_weight_t, double > edge_p; - typedef property < graph_name_t, std::string > graph_p; - typedef adjacency_list < OutEdgeList, vecS, Directedness, - vertex_p, edge_p, graph_p > graph_t; typedef typename graph_traits < graph_t >::edge_descriptor edge_t; typedef typename graph_traits < graph_t >::vertex_descriptor vertex_t; // Construct a graph and set up the dynamic_property_maps. - graph_t graph(0); dynamic_properties dp(ignore_other_properties); - typename property_map::type name = - get(vertex_name, graph); dp.property(node_id,name); - typename property_map::type mass = - get(vertex_color, graph); dp.property("mass",mass); - typename property_map::type weight = - get(edge_weight, graph); dp.property("weight",weight); boost::ref_property_map gname( @@ -139,19 +153,31 @@ bool test_graph(std::istream& dotfile, std::size_t correct_num_vertices, typedef istringstream gs_t; + typedef property < vertex_name_t, std::string, + property < vertex_color_t, float > > vertex_p; + typedef property < edge_weight_t, double > edge_p; + typedef property < graph_name_t, std::string > graph_p; + + struct vertex_p_bundled {std::string name; float color;}; + struct edge_p_bundled {double weight;}; + // Basic directed graph tests BOOST_AUTO_TEST_CASE (basic_directed_graph_1) { mass_map_t masses; insert ( masses ) ("a",0.0f) ("c",7.7f) ("e", 6.66f); gs_t gs("digraph { a node [mass = 7.7] c e [mass = 6.66] }"); - BOOST_CHECK((test_graph(gs,3,masses,weight_map_t()))); + typedef adjacency_list < vecS, vecS, directedS, + vertex_p, edge_p, graph_p > graph_t; + BOOST_CHECK((test_graph(gs,3,masses,weight_map_t()))); } BOOST_AUTO_TEST_CASE (basic_directed_graph_2) { mass_map_t masses; insert ( masses ) ("a",0.0f) ("e", 6.66f); gs_t gs("digraph { a node [mass = 7.7] \"a\" e [mass = 6.66] }"); - BOOST_CHECK((test_graph(gs,2,masses,weight_map_t()))); + typedef adjacency_list < vecS, vecS, directedS, + vertex_p, edge_p, graph_p > graph_t; + BOOST_CHECK((test_graph(gs,2,masses,weight_map_t()))); } BOOST_AUTO_TEST_CASE (basic_directed_graph_3) { @@ -162,7 +188,9 @@ bool test_graph(std::istream& dotfile, std::size_t correct_num_vertices, gs_t gs("digraph { a -> b eDge [weight = 7.7] " "c -> d e-> f [weight = 6.66] " "d ->e->a [weight=.5]}"); - BOOST_CHECK((test_graph(gs,6,mass_map_t(),weights))); + typedef adjacency_list < vecS, vecS, directedS, + vertex_p, edge_p, graph_p > graph_t; + BOOST_CHECK((test_graph(gs,6,mass_map_t(),weights))); } // undirected graph with alternate node_id property name @@ -170,8 +198,10 @@ bool test_graph(std::istream& dotfile, std::size_t correct_num_vertices, mass_map_t masses; insert ( masses ) ("a",0.0f) ("c",7.7f) ("e", 6.66f); gs_t gs("graph { a node [mass = 7.7] c e [mass = 6.66] }"); - BOOST_CHECK((test_graph(gs,3,masses,weight_map_t(), - "nodenames"))); + typedef adjacency_list < vecS, vecS, undirectedS, + vertex_p, edge_p, graph_p > graph_t; + BOOST_CHECK((test_graph(gs,3,masses,weight_map_t(), + "nodenames"))); } // Basic undirected graph tests @@ -179,7 +209,9 @@ bool test_graph(std::istream& dotfile, std::size_t correct_num_vertices, mass_map_t masses; insert ( masses ) ("a",0.0f) ("c",7.7f) ("e", 6.66f); gs_t gs("graph { a node [mass = 7.7] c e [mass =\\\n6.66] }"); - BOOST_CHECK((test_graph(gs,3,masses,weight_map_t()))); + typedef adjacency_list < vecS, vecS, undirectedS, + vertex_p, edge_p, graph_p > graph_t; + BOOST_CHECK((test_graph(gs,3,masses,weight_map_t()))); } BOOST_AUTO_TEST_CASE (basic_undirected_graph_2) { @@ -188,7 +220,9 @@ bool test_graph(std::istream& dotfile, std::size_t correct_num_vertices, (make_pair("c","d"),7.7)(make_pair("e","f"),6.66); gs_t gs("graph { a -- b eDge [weight = 7.7] " "c -- d e -- f [weight = 6.66] }"); - BOOST_CHECK((test_graph(gs,6,mass_map_t(),weights))); + typedef adjacency_list < vecS, vecS, undirectedS, + vertex_p, edge_p, graph_p > graph_t; + BOOST_CHECK((test_graph(gs,6,mass_map_t(),weights))); } // Mismatch directed graph test @@ -197,7 +231,9 @@ bool test_graph(std::istream& dotfile, std::size_t correct_num_vertices, insert ( masses ) ("a",0.0f) ("c",7.7f) ("e", 6.66f); gs_t gs("graph { a nodE [mass = 7.7] c e [mass = 6.66] }"); try { - test_graph(gs,3,masses,weight_map_t()); + typedef adjacency_list < vecS, vecS, directedS, + vertex_p, edge_p, graph_p > graph_t; + test_graph(gs,3,masses,weight_map_t()); BOOST_ERROR("Failed to throw boost::undirected_graph_error."); } catch (boost::undirected_graph_error&) { } catch (boost::directed_graph_error&) { @@ -211,7 +247,9 @@ bool test_graph(std::istream& dotfile, std::size_t correct_num_vertices, insert ( masses ) ("a",0.0f) ("c",7.7f) ("e", 6.66f); gs_t gs("digraph { a node [mass = 7.7] c e [mass = 6.66] }"); try { - test_graph(gs,3,masses,weight_map_t()); + typedef adjacency_list < vecS, vecS, undirectedS, + vertex_p, edge_p, graph_p > graph_t; + test_graph(gs,3,masses,weight_map_t()); BOOST_ERROR("Failed to throw boost::directed_graph_error."); } catch (boost::directed_graph_error&) {} } @@ -223,7 +261,9 @@ bool test_graph(std::istream& dotfile, std::size_t correct_num_vertices, insert( weights )(make_pair("a","b"),7.7); gs_t gs("diGraph { a -> b [weight = 7.7] a -> b [weight = 7.7] }"); try { - test_graph(gs,2,mass_map_t(),weights); + typedef adjacency_list < setS, vecS, directedS, + vertex_p, edge_p, graph_p > graph_t; + test_graph(gs,2,mass_map_t(),weights); BOOST_ERROR("Failed to throw boost::bad_parallel_edge."); } catch (boost::bad_parallel_edge&) {} } @@ -233,7 +273,9 @@ bool test_graph(std::istream& dotfile, std::size_t correct_num_vertices, weight_map_t weights; insert( weights )(make_pair("a","b"),7.7); gs_t gs("digraph { a -> b [weight = 7.7] a -> b [weight = 7.7] }"); - BOOST_CHECK((test_graph(gs,2,mass_map_t(),weights))); + typedef adjacency_list < vecS, vecS, directedS, + vertex_p, edge_p, graph_p > graph_t; + BOOST_CHECK((test_graph(gs,2,mass_map_t(),weights))); } // Graph Property Test 1 @@ -242,8 +284,10 @@ bool test_graph(std::istream& dotfile, std::size_t correct_num_vertices, insert ( masses ) ("a",0.0f) ("c",0.0f) ("e", 6.66f); gs_t gs("digraph { graph [name=\"foo \\\"escaped\\\"\"] a c e [mass = 6.66] }"); std::string graph_name("foo \"escaped\""); - BOOST_CHECK((test_graph(gs,3,masses,weight_map_t(),"", - graph_name))); + typedef adjacency_list < vecS, vecS, directedS, + vertex_p, edge_p, graph_p > graph_t; + BOOST_CHECK((test_graph(gs,3,masses,weight_map_t(),"", + graph_name))); } // Graph Property Test 2 @@ -252,8 +296,10 @@ bool test_graph(std::istream& dotfile, std::size_t correct_num_vertices, insert ( masses ) ("a",0.0f) ("c",0.0f) ("e", 6.66f); gs_t gs("digraph { name=\"fo\"+ \"\\\no\" a c e [mass = 6.66] }"); std::string graph_name("foo"); - BOOST_CHECK((test_graph(gs,3,masses,weight_map_t(),"", - graph_name))); + typedef adjacency_list < vecS, vecS, directedS, + vertex_p, edge_p, graph_p > graph_t; + BOOST_CHECK((test_graph(gs,3,masses,weight_map_t(),"", + graph_name))); } // Graph Property Test 3 (HTML) @@ -262,8 +308,10 @@ bool test_graph(std::istream& dotfile, std::size_t correct_num_vertices, insert ( masses ) ("a",0.0f) ("c",0.0f) ("e", 6.66f); std::string graph_name = "foo]]>bar\n
    \nbaz"; gs_t gs("digraph { name=" + graph_name + " a c e [mass = 6.66] }"); - BOOST_CHECK((test_graph(gs,3,masses,weight_map_t(),"", - graph_name))); + typedef adjacency_list < vecS, vecS, directedS, + vertex_p, edge_p, graph_p > graph_t; + BOOST_CHECK((test_graph(gs,3,masses,weight_map_t(),"", + graph_name))); } // Comments embedded in strings @@ -274,7 +322,40 @@ bool test_graph(std::istream& dotfile, std::size_t correct_num_vertices, "a1 [ label = \"//depot/path/to/file_29#9\" ];" "a0 -> a1 [ color=gray ];" "}"); - BOOST_CHECK((test_graph(gs,2,mass_map_t(),weight_map_t()))); + typedef adjacency_list < vecS, vecS, directedS, + vertex_p, edge_p, graph_p > graph_t; + BOOST_CHECK((test_graph(gs,2,mass_map_t(),weight_map_t()))); } + +#if 0 // Currently broken + BOOST_AUTO_TEST_CASE (basic_csr_directed_graph) { + weight_map_t weights; + insert( weights )(make_pair("a","b"),0.0) + (make_pair("c","d"),7.7)(make_pair("e","f"),6.66) + (make_pair("d","e"),0.5)(make_pair("e","a"),0.5); + gs_t gs("digraph { a -> b eDge [weight = 7.7] " + "c -> d e-> f [weight = 6.66] " + "d ->e->a [weight=.5]}"); + typedef compressed_sparse_row_graph graph_t; + BOOST_CHECK((test_graph(gs,6,mass_map_t(),weights,"node_id","",&vertex_p_bundled::name,&vertex_p_bundled::color,&edge_p_bundled::weight))); + } +#endif + + BOOST_AUTO_TEST_CASE (basic_csr_directed_graph_ext_props) { + weight_map_t weights; + insert( weights )(make_pair("a","b"),0.0) + (make_pair("c","d"),7.7)(make_pair("e","f"),6.66) + (make_pair("d","e"),0.5)(make_pair("e","a"),0.5); + gs_t gs("digraph { a -> b eDge [weight = 7.7] " + "c -> d e-> f [weight = 6.66] " + "d ->e->a [weight=.5]}"); + typedef compressed_sparse_row_graph graph_t; + graph_t g; + vector_property_map::const_type> vertex_name(get(vertex_index, g)); + vector_property_map::const_type> vertex_color(get(vertex_index, g)); + vector_property_map::const_type> edge_weight(get(edge_index, g)); + BOOST_CHECK((test_graph(gs,g,6,mass_map_t(),weights,"node_id","",vertex_name,vertex_color,edge_weight))); + } + // return 0; // }