From 7b548b372fcc9558eec0198532d2bbddc61a0e5b Mon Sep 17 00:00:00 2001 From: Jeremiah Willcock Date: Fri, 2 Apr 2010 15:25:11 +0000 Subject: [PATCH] Applied changes r58876, r59133, r59134, r59628, r60078, r60079, r60126, r60127, r60196, r60197, r60198, r60365, r60366, r60384, r60385, r60472, r60485, r60610, r60611, r60651, r60769, r60770, r60899, r60900, r60916, r60919, r60920, r60958, r60998, r60999, r61000 from trunk, except for changes to which are waiting for Boost.Range algorithms to be merged; added find_if to [SVN r61001] --- doc/AStarVisitor.html | 10 +- doc/BFSVisitor.html | 4 +- doc/BellmanFordVisitor.html | 4 +- doc/DFSVisitor.html | 2 +- doc/EventVisitorList.html | 4 +- doc/adjacency_list.html | 4 +- doc/adjacency_matrix.html | 4 +- doc/bc_clustering.html | 2 +- doc/bellman_visitor.html | 4 +- doc/bfs_visitor.html | 4 +- doc/biconnected_components.html | 9 + doc/compressed_sparse_row.html | 18 +- doc/dfs_visitor.html | 4 +- doc/dijkstra_visitor.html | 4 +- doc/distance_recorder.html | 4 +- doc/find_odd_cycle.html | 152 +++++++ doc/graph_theory_review.html | 4 +- doc/history.html | 2 +- doc/is_bipartite.html | 127 ++++++ doc/maximum_matching.html | 6 +- doc/planar_canonical_ordering.html | 10 + doc/planar_graphs.html | 2 +- doc/predecessor_recorder.html | 12 +- doc/property_put.html | 190 +++++++++ doc/property_writer.html | 8 +- doc/random_layout.html | 2 +- doc/table_of_contents.html | 3 + doc/time_stamper.html | 6 +- doc/tsp_tour_len_visitor.html | 2 +- doc/visitor_concepts.html | 2 + example/Jamfile.v2 | 1 + example/bipartite_example.cpp | 115 ++++++ include/boost/detail/algorithm.hpp | 6 + include/boost/graph/adjacency_list.hpp | 13 +- include/boost/graph/astar_search.hpp | 9 +- include/boost/graph/bipartite.hpp | 386 ++++++++++++++++++ .../graph/compressed_sparse_row_graph.hpp | 130 ++++-- include/boost/graph/detail/adjacency_list.hpp | 11 +- .../boost/graph/detail/array_binary_tree.hpp | 61 ++- .../detail/compressed_sparse_row_struct.hpp | 27 +- .../boost/graph/detail/indexed_properties.hpp | 53 ++- .../boost/graph/detail/read_graphviz_new.hpp | 18 +- .../graph/detail/read_graphviz_spirit.hpp | 6 +- include/boost/graph/filtered_graph.hpp | 1 + include/boost/graph/graph_test.hpp | 8 +- include/boost/graph/graphml.hpp | 37 +- include/boost/graph/graphviz.hpp | 70 +++- include/boost/graph/gursoy_atun_layout.hpp | 3 +- include/boost/graph/metric_tsp_approx.hpp | 4 +- include/boost/graph/one_bit_color_map.hpp | 103 +++++ include/boost/graph/topological_sort.hpp | 3 +- include/boost/graph/two_bit_color_map.hpp | 22 +- include/boost/graph/visitors.hpp | 46 +++ include/boost/pending/container_traits.hpp | 129 ++++-- include/boost/pending/indirect_cmp.hpp | 2 +- include/boost/pending/mutable_queue.hpp | 28 +- src/graphml.cpp | 14 +- src/read_graphviz_new.cpp | 2 +- src/read_graphviz_spirit.cpp | 47 --- test/Jamfile.v2 | 3 +- test/bipartite_test.cpp | 189 +++++++++ test/csr_graph_test.cpp | 33 +- test/graphviz_test.cpp | 2 +- test/metric_tsp_approx.cpp | 4 +- 64 files changed, 1898 insertions(+), 297 deletions(-) create mode 100644 doc/find_odd_cycle.html create mode 100644 doc/is_bipartite.html create mode 100644 doc/property_put.html create mode 100644 example/bipartite_example.cpp create mode 100644 include/boost/graph/bipartite.hpp create mode 100644 include/boost/graph/one_bit_color_map.hpp delete mode 100644 src/read_graphviz_spirit.cpp create mode 100644 test/bipartite_test.cpp diff --git a/doc/AStarVisitor.html b/doc/AStarVisitor.html index da99a8ed..81fa6129 100644 --- a/doc/AStarVisitor.html +++ b/doc/AStarVisitor.html @@ -118,7 +118,7 @@ OPEN list. vis.examine_vertex(u, g) void -This is invoked on a vertex as it is popped from the queue (i.e. it +This is invoked on a vertex as it is popped from the queue (i.e., it has the lowest cost on the OPEN list). This happens immediately before examine_edge() is invoked on each of the out-edges of vertex u. @@ -160,7 +160,7 @@ assert(compare(combine(d_u, w_e), d_s)); vis.edge_not_relaxed(e, g) void -Upon examination, if an edge is not relaxed (see above), then this +Upon examination, if an edge is not relaxed (see above) then this method is invoked. @@ -171,7 +171,7 @@ method is invoked. void This is invoked when a vertex that is on the CLOSED list is -``rediscovered'' via a more efficient path, and is re-added to the +``rediscovered'' via a more efficient path and is re-added to the OPEN list. @@ -181,8 +181,8 @@ OPEN list. vis.finish_vertex(u, g) void -This is invoked on a vertex when it is added to the CLOSED list, which -happens after all of its out edges have been examined. +This is invoked on a vertex when it is added to the CLOSED list. This +happens after all of its out-edges have been examined. diff --git a/doc/BFSVisitor.html b/doc/BFSVisitor.html index 2390a294..5333a9df 100644 --- a/doc/BFSVisitor.html +++ b/doc/BFSVisitor.html @@ -140,7 +140,7 @@ edges for undirected graphs. vis.gray_target(e, g) void -This is invoked on the subset of non-tree edges who's target vertex is +This is invoked on the subset of non-tree edges whose target vertex is colored gray at the time of examination. The color gray indicates that the vertex is currently in the queue. @@ -151,7 +151,7 @@ that the vertex is currently in the queue. vis.black_target(e, g) void -This is invoked on the subset of non-tree edges who's target vertex is +This is invoked on the subset of non-tree edges whose target vertex is colored black at the time of examination. The color black indicates that the vertex has been removed from the queue. diff --git a/doc/BellmanFordVisitor.html b/doc/BellmanFordVisitor.html index 96462288..4bfbdfd9 100644 --- a/doc/BellmanFordVisitor.html +++ b/doc/BellmanFordVisitor.html @@ -116,8 +116,8 @@ this method is invoked. vis.edge_minimized(e, g) void -After the num_vertices(g) iterations through the edge set -of the graph is complete, one last iteration is made to test whether +After num_vertices(g) iterations through the edge set +of the graph are completed, one last iteration is made to test whether each edge was minimized. If the edge is minimized then this function is invoked. diff --git a/doc/DFSVisitor.html b/doc/DFSVisitor.html index 7ba1c342..f81f616f 100644 --- a/doc/DFSVisitor.html +++ b/doc/DFSVisitor.html @@ -157,7 +157,7 @@ undirected graph this method is never called. This is invoked on vertex u after finish_vertex has been called for all the vertices in the DFS-tree rooted at vertex u. If vertex u is a leaf in the DFS-tree, then -the finish_vertex function is call on u after +the finish_vertex function is called on u after all the out-edges of u have been examined. diff --git a/doc/EventVisitorList.html b/doc/EventVisitorList.html index c4dd24f7..09e8e9cc 100644 --- a/doc/EventVisitorList.html +++ b/doc/EventVisitorList.html @@ -19,7 +19,7 @@ An EventVisitorList is either an EventVisitor, or a list of -EventVisitor's combined using std::pair. Each graph algorithm +EventVisitors combined using std::pair. Each graph algorithm defines visitor adaptors that convert an EventVisitorList into the particular kind of visitor needed by the algorithm. @@ -91,7 +91,7 @@ Now we can pass the resulting visitor object into color.begin()); -For creating a list of more than two event visitors, nest calls to +For creating a list of more than two event visitors, you can nest calls to std::make_pair in the following way:
diff --git a/doc/adjacency_list.html b/doc/adjacency_list.html
index be600274..311d888f 100644
--- a/doc/adjacency_list.html
+++ b/doc/adjacency_list.html
@@ -37,7 +37,7 @@ href="#fig:adj-list-graph">Figure 1 shows an adjacency list
 representation of a directed graph.
 
 

-
+
@@ -67,7 +67,7 @@ href="#fig:undir-adj-list-graph">Figure 2 shows an adjacency list representation of an undirected graph.

-
+
Figure 1: Adjacency List Representation of a Directed Graph.
diff --git a/doc/adjacency_matrix.html b/doc/adjacency_matrix.html index 7da34fc0..f074f5b4 100644 --- a/doc/adjacency_matrix.html +++ b/doc/adjacency_matrix.html @@ -32,7 +32,7 @@ href="#fig:adj-matrix-graph">Figure 1 shows the adjacency matrix representation of a graph.

-
+
Figure 2: Adjacency List Representation of an Undirected Graph.
@@ -72,7 +72,7 @@ href="#fig:undir-adj-matrix-graph">Figure 2 shows an adjacency matrix representation of an undirected graph.

-
+
Figure 1: Adjacency Matrix Representation of a Directed Graph.
diff --git a/doc/bc_clustering.html b/doc/bc_clustering.html index 14fefb4b..261dfa0b 100644 --- a/doc/bc_clustering.html +++ b/doc/bc_clustering.html @@ -61,7 +61,7 @@ clustering based on edge betweenness centrality.

Description

This algorithm implements graph clustering based on edge betweenness centrality. It is an iterative algorithm, where in each -step it compute the edge betweenness centrality (via brandes_betweenness_centrality) and removes the edge with the maximum betweenness centrality. The done function object determines diff --git a/doc/bellman_visitor.html b/doc/bellman_visitor.html index bd6eb9b5..72dae162 100644 --- a/doc/bellman_visitor.html +++ b/doc/bellman_visitor.html @@ -22,7 +22,7 @@ bellman_visitor<EventVisitorList> This class is an adapter that converts a list of EventVisitor's (constructed using +href="./EventVisitor.html">EventVisitors (constructed using std::pair) into a BellmanFordVisitor. @@ -63,7 +63,7 @@ with std::pair. This class implements all of the member functions required by BellmanFordVisitor. In each function the appropriate event is dispatched to the EventVisitor's in the EventVisitorList. +href="./EventVisitor.html">EventVisitor in the EventVisitorList.

Non-Member Functions

diff --git a/doc/bfs_visitor.html b/doc/bfs_visitor.html index 751a742a..b175ac96 100644 --- a/doc/bfs_visitor.html +++ b/doc/bfs_visitor.html @@ -22,7 +22,7 @@ bfs_visitor<EventVisitorList> This class is an adapter that converts a list of EventVisitor's (constructed using +href="./EventVisitor.html">EventVisitors (constructed using std::pair) into a BFSVisitor. @@ -80,7 +80,7 @@ with std::pair. This class implements all of the member functions required by BFSVisitor. In each function the appropriate event is dispatched to the EventVisitor's in the EventVisitorList. +href="./EventVisitor.html">EventVisitor in the EventVisitorList.

Non-Member Functions

diff --git a/doc/biconnected_components.html b/doc/biconnected_components.html index 4af85e15..e45787b4 100644 --- a/doc/biconnected_components.html +++ b/doc/biconnected_components.html @@ -239,6 +239,15 @@ href="../example/biconnected_components.cpp">examples/biconnected_components contains an example of calculating the biconnected components and articulation points of an undirected graph. +

Notes

+ +

[1] + Since the visitor parameter is passed by value, if your visitor + contains state then any changes to the state during the algorithm + will be made to a copy of the visitor object, not the visitor object + passed in. Therefore you may want the visitor to hold this state by + pointer or reference. +


Figure 1: Adjacency Matrix Representation of an Undirected Graph.
diff --git a/doc/compressed_sparse_row.html b/doc/compressed_sparse_row.html index 68a0ed9b..8850822d 100644 --- a/doc/compressed_sparse_row.html +++ b/doc/compressed_sparse_row.html @@ -224,7 +224,7 @@ std::pair<edge_iterator, edge_iterator> edges(const compressed_sparse_row_ edges_size_type num_edges(const compressed_sparse_row_graph&); // Vertex access -vertex_descriptor vertex(vertices_size_type i, const compressed_sparse_row_graph&); +vertex_descriptor vertex(vertices_size_type i, const compressed_sparse_row_graph&); // Edge access std::pair<edge_descriptor, bool> @@ -460,7 +460,7 @@ void add_edges_sorted(BidirectionalIterator
-

+    

   template<typename MultiPassInputIterator>
   compressed_sparse_row_graph(edges_are_unsorted_multi_pass_t,
                               MultiPassInputIterator edge_begin, MultiPassInputIterator edge_end,
@@ -489,7 +489,7 @@ void add_edges_sorted(BidirectionalIterator
 
     
-

+    

   template<typename MultiPassInputIterator, typename EdgePropertyIterator>
   compressed_sparse_row_graph(edges_are_unsorted_multi_pass_t,
                               MultiPassInputIterator edge_begin, MultiPassInputIterator edge_end,
@@ -624,7 +624,7 @@ void add_edges_sorted(BidirectionalIterator
 
     
-

+    

   template<typename Graph, typename VertexIndexMap>
   compressed_sparse_row_graph(const Graph& g, const VertexIndexMap& vi,
                               vertices_size_type numverts,
@@ -713,7 +713,7 @@ void add_edges_sorted(BidirectionalIterator
 
     

Vertex access

-

+    

   vertex_descriptor vertex(vertices_size_type i, const compressed_sparse_row_graph&);
     

@@ -723,6 +723,8 @@ void add_edges_sorted(BidirectionalIterator


+

Edge access

+

   std::pair<edge_descriptor, bool> 
     edge(vertex_descriptor u, vertex_descriptor v, const compressed_sparse_row_graph&);
@@ -733,8 +735,10 @@ void add_edges_sorted(BidirectionalIterator
       descriptor for that edge and true; otherwise, the
       second value in the pair will be false. If multiple
       edges exist from u to v, the first edge will
-      be returned; use edge_range
-      to retrieve all edges.  This function requires linear time in the
+      be returned; use out_edges and a
+      conditional statement
+      to retrieve all edges to a given target.  This function requires linear
+      time in the
       number of edges outgoing from u.
     

diff --git a/doc/dfs_visitor.html b/doc/dfs_visitor.html index 9c3fb1a2..990117c6 100644 --- a/doc/dfs_visitor.html +++ b/doc/dfs_visitor.html @@ -22,7 +22,7 @@ dfs_visitor<EventVisitorList> This class is an adapter that converts a list of EventVisitor's (constructed using +href="./EventVisitor.html">EventVisitors (constructed using std::pair) into a DFSVisitor. @@ -63,7 +63,7 @@ with std::pair. This class implements all of the member functions required by DFSVisitor. In each function the appropriate event is dispatched to the EventVisitor's in the EventVisitorList. +href="./EventVisitor.html">EventVisitor in the EventVisitorList.

Non-Member Functions

diff --git a/doc/dijkstra_visitor.html b/doc/dijkstra_visitor.html index 80b00af9..1e7ec036 100644 --- a/doc/dijkstra_visitor.html +++ b/doc/dijkstra_visitor.html @@ -22,7 +22,7 @@ dijkstra_visitor<EventVisitorList> This class is an adapter that converts a list of EventVisitor's (constructed using +href="./EventVisitor.html">EventVisitors (constructed using std::pair) into a DijkstraVisitor. @@ -77,7 +77,7 @@ with std::pair. This class implements all of the member functions required by DijkstraVisitor. In each function the appropriate event is dispatched to the EventVisitor's in the EventVisitorList. +href="./EventVisitor.html">EventVisitor in the EventVisitorList.

Non-Member Functions

diff --git a/doc/distance_recorder.html b/doc/distance_recorder.html index e10e3f57..fe7cd559 100644 --- a/doc/distance_recorder.html +++ b/doc/distance_recorder.html @@ -27,7 +27,7 @@ href="property_map.html">property map) from some source vertex during a graph search. When applied to edge e = (u,v), the distance of v is recorded to be one more than the distance of u. The distance recorder is typically used with -the on_tree_edge or on_relax_edge events, and +the on_tree_edge or on_relax_edge events and cannot be used with vertex events.

@@ -64,7 +64,7 @@ See the example for bfs_visitor.

diff --git a/doc/find_odd_cycle.html b/doc/find_odd_cycle.html new file mode 100644 index 00000000..f29aba48 --- /dev/null +++ b/doc/find_odd_cycle.html @@ -0,0 +1,152 @@ + + + + +Boost Graph Library: find_odd_cycle + + + + +

+find_odd_cycle +

+ +
+// Version with a colormap to retrieve the bipartition
+template <typename Graph, typename IndexMap, typename PartitionMap, typename OutputIterator>
+OutputIterator find_odd_cycle (const Graph& graph, const IndexMap index_map, PartitionMap partition_map, OutputIterator result)
+
+template <typename Graph, typename IndexMap, typename OutputIterator>
+OutputIterator find_odd_cycle (const Graph& graph, const IndexMap index_map, OutputIterator result)
+
+// Version which uses the internal index map
+template <typename Graph, typename OutputIterator>
+OutputIterator find_odd_cycle (const Graph& graph, OutputIterator result)
+
+ +

+The find_odd_cycle function tests a given graph for bipartiteness +using a DFS-based coloring approach. +

+ +

+An undirected graph is bipartite if one can partition its set of vertices +into two sets "left" and "right", such that each edge goes from either side +to the other. Obviously, a two-coloring of the graph is exactly the same as +a two-partition. is_bipartite() tests whether such a two-coloring +is possible and can return it in a given property map. +

+ +

+Another equivalent characterization is the non-existance of odd-length cycles, +meaning that a graph is bipartite if and only if it does not contain a +cycle with an odd number of vertices as a subgraph. +find_odd_cycle() does nearly the same as +is_bipartite(), +but additionally constructs an odd-length cycle if the graph is found to be +not bipartite. +

+ +

+The bipartition is recorded in the color map partition_map, +which will contain a two-coloring of the graph, i.e. an assignment of +black and white to the vertices such that no edge is monochromatic. +The odd-length cycle is written into the Output Iterator result if +one exists. The final final iterator is returned by the function. +

+ +

Where Defined

+ +

+boost/graph/bipartite.hpp +

+ +

Parameters

+ +

+IN: const Graph& graph +

+

+An undirected graph. The graph type must be a model of Vertex List Graph and Incidence Graph.
+

+ +

+IN: const IndexMap index_map +

+

+This maps each vertex to an integer in the range [0, +num_vertices(graph)). The type VertexIndexMap +must be a model of Readable Property +Map. The value type of the map must be an integer type. The +vertex descriptor type of the graph needs to be usable as the key +type of the map.
+

+ + +

+OUT: PartitionMap partition_map +

+

+The algorithm tests whether the graph is bipartite and assigns each +vertex either a white or a black color, according to the partition. +The PartitionMap type must be a model of +Readable Property +Map and +Writable Property +Map. The value type must model ColorValue. +

+ +

+OUT: OutputIterator result +

+

+The find_odd_cycle function finds an odd-length cycle if the graph is +not bipartite. The sequence of vertices producing such a cycle is written +into this iterator. The OutputIterator type must be a model of + +OutputIterator. The graph's vertex descriptor type must be in the set +of value types of the iterator. The final value is returned by the +function. If the graph is bipartite (i.e. no odd-length cycle exists), nothing +is written, thus the given iterator matches the return value. +

+ + +

Complexity

+ +

+The time complexity for the algorithm is O(V + E). +

+ +

See Also

+ +

+is_bipartite() +

+ +

Example

+ +

+The file example/bipartite_example.cpp +contains an example of testing an undirected graph for bipartiteness. +
+

+ +
+ +

+Copyright © 2010 Matthias Walter +(xammy@xammy.homelinux.net) +

+ + + diff --git a/doc/graph_theory_review.html b/doc/graph_theory_review.html index 8d79b2d3..81801e86 100644 --- a/doc/graph_theory_review.html +++ b/doc/graph_theory_review.html @@ -90,7 +90,7 @@ allowed in a directed or undirected graph).

-
+
DistanceMap A WritablePropertyMap, +href="../../property_map/doc/WritablePropertyMap.html">WritablePropertyMap where the key type and the value type are the vertex descriptor type of the graph.
@@ -558,7 +558,7 @@ A flow network is shown in Figure vertex.

-
+
Figure 1: Example of a directed graph.
diff --git a/doc/property_put.html b/doc/property_put.html new file mode 100644 index 00000000..9f0ebd8a --- /dev/null +++ b/doc/property_put.html @@ -0,0 +1,190 @@ + + + +Boost Graph Library: property_put + +C++ Boost + +
+ +

+
+property_put<PropertyMap, EventTag>
+
+

+ +This is an EventVisitor that can be +used to write a fixed value to a property map when a vertex or edge is +visited at some event-point within an algorithm. For example, this +visitor can be used as an alternative to a loop to initialize a +property map, or it can be used to mark only back edges with a +property. + +

+property_put can be used with graph algorithms by +wrapping it with the algorithm-specific adaptor, such as bfs_visitor and dfs_visitor. Also, this event +visitor can be combined with other event visitors using +std::pair to form an EventVisitorList. + +

Example

+ +
+  boost::depth_first_search
+    (G, boost::visitor(
+          boost::make_dfs_visitor(
+            boost::put_property(is_back_edge, boost::on_back_edge()))));
+
+ +

Model of

+ +EventVisitor + + +

Where Defined

+ +

+ +boost/graph/visitors.hpp + +

Template Parameters

+ +

+

Figure 8: A Maximum Flow Network.
Edges are labeled with the flow and capacity diff --git a/doc/history.html b/doc/history.html index 5c210a25..d89b35df 100644 --- a/doc/history.html +++ b/doc/history.html @@ -76,7 +76,7 @@ September 27, 2000.

Changes by version

PredecessorMap A WritablePropertyMap, +href="../../property_map/doc/WritablePropertyMap.html">WritablePropertyMap where the key type and the value type are the vertex descriptor type of the graph.
+ + + + + + + + + + + + + + +
ParameterDescriptionDefault
PropertyMap +A WritablePropertyMap, +where the key_type is the vertex descriptor type or edge +descriptor of the graph (depending on the kind of event tag). + 
EventTag +The tag to specify when the property_put should be +applied during the graph algorithm. + 
+ +

Associated Types

+ + + + + + + + + + + + +
TypeDescription
property_put::event_filter +This will be the same type as the template parameter EventTag. +
+ +

Member Functions

+ +

+ + + + + + + + + + + + + + + + +
MemberDescription
+property_put(PropertyMap pa, property_traits::value_type val); + +Construct a property put object with the property map +pa and constant value val. +
+template <class X, class Graph>
+void operator()(X x, const Graph& g); +
+This puts the value val into the property map for the vertex +or edge x.
+
+ +

Non-Member Functions

+ + + + + + + + +
FunctionDescription
+template <class PropertyMap, class EventTag>
+property_put<PropertyMap, EventTag>
+put_property(PropertyMap pa, + typename property_traits::value_type val, + EventTag); +
+A convenient way to create a property_put. +
+ +

See Also

+ +Visitor concepts +

+The following are other event visitors: distance_recorder, +predecessor_recorder, +and time_stamper. + +
+


+ + + + + +
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) +
Copyright © 2010Matthias Walter (xammy@xammy.homelinux.net)
Trustees of Indiana University
+ + + + + + diff --git a/doc/property_writer.html b/doc/property_writer.html index 8ce39189..fce17995 100644 --- a/doc/property_writer.html +++ b/doc/property_writer.html @@ -27,7 +27,7 @@ within an algorithm.

property_writer can be used with graph algorithms by -wrapping it with the algorithm specific adaptor, such as bfs_visitor and dfs_visitor. Also, this event visitor can be combined with other event visitors using @@ -74,9 +74,9 @@ href="../example/dave.cpp">examples/dave.cpp. PropertyMap A ReadablePropertyMap, +href="../../property_map/doc/ReadablePropertyMap.html">ReadablePropertyMap where the key_type is the vertex descriptor type or edge -descriptor of the graph (depending on the kind of event tag), and +descriptor of the graph (depending on the kind of event tag) and the value_type of the property is convertible to the value_type of the OutputIterator. @@ -145,7 +145,7 @@ template <class X, class Graph>
void operator()(X x, const Graph& g);
-This writs the property value for x to the output iterator.
+This writes the property value for x to the output iterator.
*out++ = get(pa, x); diff --git a/doc/random_layout.html b/doc/random_layout.html index 667d8d01..a0ad5324 100644 --- a/doc/random_layout.html +++ b/doc/random_layout.html @@ -82,7 +82,7 @@ IN/UTIL: RandomNumberGenerator& gen

A random number generator that will be used to place vertices. The type RandomNumberGenerator must model the NumberGenerator +href="../../random/doc/html/boost_random/reference.html#boost_random.reference.concepts.number_generator">NumberGenerator concept.
diff --git a/doc/table_of_contents.html b/doc/table_of_contents.html index 8333941c..438a07ae 100644 --- a/doc/table_of_contents.html +++ b/doc/table_of_contents.html @@ -93,6 +93,7 @@
  • distance_recorder
  • time_stamper
  • property_writer +
  • property_put
  • tsp_tour_visitor
  • tsp_tour_len_visitor
  • @@ -264,6 +265,8 @@
    1. metric_tsp_approx
    2. sequential_vertex_coloring +
    3. is_bipartite (including two-coloring of bipartite graphs) +
    4. find_odd_cycle
    diff --git a/doc/time_stamper.html b/doc/time_stamper.html index 6689af28..e2f69f23 100644 --- a/doc/time_stamper.html +++ b/doc/time_stamper.html @@ -74,9 +74,9 @@ The following example shows the usage of the time_stamper. TimeMap A WritablePropertyMap, +href="../../property_map/doc/WritablePropertyMap.html">WritablePropertyMap where the key_type is the vertex descriptor type or edge -descriptor of the graph (depending on the kind of event tag), and +descriptor of the graph (depending on the kind of event tag) and where the TimeT type is convertible to the value_type of the time property map. @@ -85,7 +85,7 @@ where the TimeT type is convertible to the TimeT -The type for the time counter, which should be convertible to the +The type for the time counter which should be convertible to the value_type of the time property map   diff --git a/doc/tsp_tour_len_visitor.html b/doc/tsp_tour_len_visitor.html index 8136ad14..4363a3ae 100644 --- a/doc/tsp_tour_len_visitor.html +++ b/doc/tsp_tour_len_visitor.html @@ -102,7 +102,7 @@ template <typename Graph, typename WeightMap, typename OutputIterator, typena tsp_tour_len_visitor<OutputIterator>
    make_tsp_tour_len_visitor(Graph const& g, OutIter iter, Length& l, WeightMap map) -Returns a tour_len_visitor that records the TSP tour in the OutputIterator parameter and the tour's length in the Length parameter. +Returns a tour_len_visitor that records the TSP tour in the OutputIterator parameter and the length of the tour in the Length parameter. diff --git a/doc/visitor_concepts.html b/doc/visitor_concepts.html index 4053282b..b68bd69c 100644 --- a/doc/visitor_concepts.html +++ b/doc/visitor_concepts.html @@ -40,6 +40,8 @@ the following visitor concepts:
  • Bellman Ford Visitor
  • A* Visitor
  • Event Visitor +
  • Planar Face Visitor +
  • TSP Tour Visitor diff --git a/example/Jamfile.v2 b/example/Jamfile.v2 index b57f8ef3..561612d0 100644 --- a/example/Jamfile.v2 +++ b/example/Jamfile.v2 @@ -20,3 +20,4 @@ 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 bipartite_example : bipartite_example.cpp ; diff --git a/example/bipartite_example.cpp b/example/bipartite_example.cpp new file mode 100644 index 00000000..b1a912e8 --- /dev/null +++ b/example/bipartite_example.cpp @@ -0,0 +1,115 @@ +/** + * + * Copyright (c) 2010 Matthias Walter (xammy@xammy.homelinux.net) + * + * Authors: Matthias Walter + * + * 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 + +using namespace boost; + +/// Example to test for bipartiteness and print the certificates. + +template +void print_bipartite (const Graph& g) +{ + typedef graph_traits traits; + typename traits::vertex_iterator vertex_iter, vertex_end; + + /// Most simple interface just tests for bipartiteness. + + bool bipartite = is_bipartite (g); + + if (bipartite) + { + typedef std::vector partition_t; + typedef vec_adj_list_vertex_id_map index_map_t; + typedef iterator_property_map partition_map_t; + + partition_t partition (num_vertices (g)); + partition_map_t partition_map (partition.begin (), get (vertex_index, g)); + + /// A second interface yields a bipartition in a color map, if the graph is bipartite. + + is_bipartite (g, get (vertex_index, g), partition_map); + + for (tie (vertex_iter, vertex_end) = vertices (g); vertex_iter != vertex_end; ++vertex_iter) + { + std::cout << "Vertex " << *vertex_iter << " has color " << (get (partition_map, *vertex_iter) == color_traits < + default_color_type>::white () ? "white" : "black") << std::endl; + } + } + else + { + typedef std::vector vertex_vector_t; + vertex_vector_t odd_cycle; + + /// A third interface yields an odd-cycle if the graph is not bipartite. + + find_odd_cycle (g, get (vertex_index, g), std::back_inserter (odd_cycle)); + + std::cout << "Odd cycle consists of the vertices:"; + for (size_t i = 0; i < odd_cycle.size (); ++i) + { + std::cout << " " << odd_cycle[i]; + } + std::cout << std::endl; + } +} + +int main (int argc, char **argv) +{ + typedef adjacency_list vector_graph_t; + typedef std::pair E; + + /** + * Create the graph drawn below. + * + * 0 - 1 - 2 + * | | + * 3 - 4 - 5 - 6 + * / \ / + * | 7 + * | | + * 8 - 9 - 10 + **/ + + E bipartite_edges[] = { E (0, 1), E (0, 4), E (1, 2), E (2, 6), E (3, 4), E (3, 8), E (4, 5), E (4, 7), E (5, 6), E ( + 6, 7), E (7, 10), E (8, 9), E (9, 10) }; + vector_graph_t bipartite_vector_graph (&bipartite_edges[0], + &bipartite_edges[0] + sizeof(bipartite_edges) / sizeof(E), 11); + + /** + * Create the graph drawn below. + * + * 2 - 1 - 0 + * | | + * 3 - 6 - 5 - 4 + * / \ / + * | 7 + * | / + * 8 ---- 9 + * + **/ + + E non_bipartite_edges[] = { E (0, 1), E (0, 4), E (1, 2), E (2, 6), E (3, 6), E (3, 8), E (4, 5), E (4, 7), E (5, 6), + E (6, 7), E (7, 9), E (8, 9) }; + vector_graph_t non_bipartite_vector_graph (&non_bipartite_edges[0], &non_bipartite_edges[0] + + sizeof(non_bipartite_edges) / sizeof(E), 10); + + /// Call test routine for a bipartite and a non-bipartite graph. + + print_bipartite (bipartite_vector_graph); + + print_bipartite (non_bipartite_vector_graph); + + return 0; +} diff --git a/include/boost/detail/algorithm.hpp b/include/boost/detail/algorithm.hpp index 252e9f46..2476a3ae 100644 --- a/include/boost/detail/algorithm.hpp +++ b/include/boost/detail/algorithm.hpp @@ -140,6 +140,12 @@ namespace boost { std::stable_sort(begin(c), end(c), p); } + template + typename Container::const_iterator find_if(const Container& c, Predicate p) + { + return find_if(begin(c), end(c), p); + } + template bool any_if(InputIterator first, InputIterator last, Predicate p) { diff --git a/include/boost/graph/adjacency_list.hpp b/include/boost/graph/adjacency_list.hpp index 625ab24d..1a24680f 100644 --- a/include/boost/graph/adjacency_list.hpp +++ b/include/boost/graph/adjacency_list.hpp @@ -1,6 +1,7 @@ //======================================================================= // Copyright 1997, 1998, 1999, 2000 University of Notre Dame. -// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek +// Copyright 2010 Thomas Claveirole +// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek, Thomas Claveirole // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at @@ -254,6 +255,16 @@ namespace boost { typedef disallow_parallel_edge_tag type; }; + template <> + struct parallel_edge_traits { + typedef allow_parallel_edge_tag type; + }; + + template <> + struct parallel_edge_traits { + typedef allow_parallel_edge_tag type; + }; + namespace detail { template struct is_random_access { enum { value = false}; diff --git a/include/boost/graph/astar_search.hpp b/include/boost/graph/astar_search.hpp index 4f956329..47474337 100644 --- a/include/boost/graph/astar_search.hpp +++ b/include/boost/graph/astar_search.hpp @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -147,7 +148,7 @@ namespace boost { template void examine_edge(Edge e, Graph& g) { if (m_compare(get(m_weight, e), m_zero)) - throw negative_edge(); + BOOST_THROW_EXCEPTION(negative_edge()); m_vis.examine_edge(e, g); } template @@ -238,14 +239,14 @@ namespace boost { AStarHeuristic h, AStarVisitor vis, PredecessorMap predecessor, CostMap cost, DistanceMap distance, WeightMap weight, - ColorMap color, VertexIndexMap /*index_map*/, + ColorMap color, VertexIndexMap index_map, CompareFunction compare, CombineFunction combine, CostInf /*inf*/, CostZero zero) { typedef typename graph_traits::vertex_descriptor Vertex; - typedef boost::vector_property_map IndexInHeapMap; - IndexInHeapMap index_in_heap; + typedef boost::vector_property_map IndexInHeapMap; + IndexInHeapMap index_in_heap(index_map); typedef d_ary_heap_indirect MutableQueue; MutableQueue Q(cost, index_in_heap, compare); diff --git a/include/boost/graph/bipartite.hpp b/include/boost/graph/bipartite.hpp new file mode 100644 index 00000000..90cff6fe --- /dev/null +++ b/include/boost/graph/bipartite.hpp @@ -0,0 +1,386 @@ +/** + * + * Copyright (c) 2010 Matthias Walter (xammy@xammy.homelinux.net) + * + * Authors: Matthias Walter + * + * 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) + * + */ + +#ifndef BOOST_GRAPH_BIPARTITE_HPP +#define BOOST_GRAPH_BIPARTITE_HPP + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { + + namespace detail { + + /** + * The bipartite_visitor_error is thrown if an edge cannot be colored. + * The witnesses are the edges incident vertices. + */ + + template + struct bipartite_visitor_error: std::exception + { + std::pair witnesses; + + bipartite_visitor_error (Vertex a, Vertex b) : + witnesses (a, b) + { + + } + + const char* what () const throw () + { + return "Graph is not bipartite."; + } + }; + + /** + * Functor which colors edges to be non-monochromatic. + */ + + template + struct bipartition_colorize + { + typedef on_tree_edge event_filter; + + bipartition_colorize (PartitionMap partition_map) : + partition_map_ (partition_map) + { + + } + + template + void operator() (Edge e, const Graph& g) + { + typedef typename graph_traits ::vertex_descriptor vertex_descriptor_t; + typedef color_traits ::value_type> color_traits; + + vertex_descriptor_t source_vertex = source (e, g); + vertex_descriptor_t target_vertex = target (e, g); + if (get (partition_map_, source_vertex) == color_traits::white ()) + put (partition_map_, target_vertex, color_traits::black ()); + else + put (partition_map_, target_vertex, color_traits::white ()); + } + + private: + PartitionMap partition_map_; + }; + + /** + * Creates a bipartition_colorize functor which colors edges + * to be non-monochromatic. + * + * @param partition_map Color map for the bipartition + * @return The functor. + */ + + template + inline bipartition_colorize colorize_bipartition (PartitionMap partition_map) + { + return bipartition_colorize (partition_map); + } + + /** + * Functor which tests an edge to be monochromatic. + */ + + template + struct bipartition_check + { + typedef on_back_edge event_filter; + + bipartition_check (PartitionMap partition_map) : + partition_map_ (partition_map) + { + + } + + template + void operator() (Edge e, const Graph& g) + { + typedef typename graph_traits ::vertex_descriptor vertex_descriptor_t; + + vertex_descriptor_t source_vertex = source (e, g); + vertex_descriptor_t target_vertex = target (e, g); + if (get (partition_map_, source_vertex) == get (partition_map_, target_vertex)) + throw bipartite_visitor_error (source_vertex, target_vertex); + } + + private: + PartitionMap partition_map_; + }; + + /** + * Creates a bipartition_check functor which raises an error if a + * monochromatic edge is found. + * + * @param partition_map The map for a bipartition. + * @return The functor. + */ + + template + inline bipartition_check check_bipartition (PartitionMap partition_map) + { + return bipartition_check (partition_map); + } + + /** + * Find the beginning of a common suffix of two sequences + * + * @param sequence1 Pair of bidirectional iterators defining the first sequence. + * @param sequence2 Pair of bidirectional iterators defining the second sequence. + * @return Pair of iterators pointing to the beginning of the common suffix. + */ + + template + inline std::pair reverse_mismatch (std::pair < + BiDirectionalIterator1, BiDirectionalIterator1> sequence1, std::pair sequence2) + { + if (sequence1.first == sequence1.second || sequence2.first == sequence2.second) + return std::make_pair (sequence1.first, sequence2.first); + + BiDirectionalIterator1 iter1 = sequence1.second; + BiDirectionalIterator2 iter2 = sequence2.second; + + while (true) + { + --iter1; + --iter2; + if (*iter1 != *iter2) + { + ++iter1; + ++iter2; + break; + } + if (iter1 == sequence1.first) + break; + if (iter2 == sequence2.first) + break; + } + + return std::make_pair (iter1, iter2); + } + + } + + /** + * Checks a given graph for bipartiteness and fills the given color map with + * white and black according to the bipartition. If the graph is not + * bipartite, the contents of the color map are undefined. Runs in linear + * time in the size of the graph, if access to the property maps is in + * constant time. + * + * @param graph The given graph. + * @param index_map An index map associating vertices with an index. + * @param partition_map A color map to fill with the bipartition. + * @return true if and only if the given graph is bipartite. + */ + + template + bool is_bipartite (const Graph& graph, const IndexMap index_map, PartitionMap partition_map) + { + /// General types and variables + typedef typename property_traits ::value_type partition_color_t; + typedef typename graph_traits ::vertex_descriptor vertex_descriptor_t; + typedef typename graph_traits ::vertex_iterator vertex_iterator_t; + + /// Declare dfs visitor + // detail::empty_recorder recorder; + // typedef detail::bipartite_visitor dfs_visitor_t; + // dfs_visitor_t dfs_visitor (partition_map, recorder); + + + /// Call dfs + try + { + depth_first_search (graph, vertex_index_map (index_map).visitor (make_dfs_visitor (std::make_pair ( + detail::colorize_bipartition (partition_map), std::make_pair (detail::check_bipartition (partition_map), + put_property (partition_map, color_traits ::white (), on_start_vertex ())))))); + + // depth_first_search (graph, vertex_index_map (index_map).visitor (dfs_visitor)); + } + catch (detail::bipartite_visitor_error error) + { + return false; + } + + return true; + } + + /** + * Checks a given graph for bipartiteness. + * + * @param graph The given graph. + * @param index_map An index map associating vertices with an index. + * @return true if and only if the given graph is bipartite. + */ + + template + bool is_bipartite (const Graph& graph, const IndexMap index_map) + { + typedef one_bit_color_map partition_map_t; + partition_map_t partition_map (num_vertices (graph), index_map); + + return is_bipartite (graph, index_map, partition_map); + } + + /** + * Checks a given graph for bipartiteness. The graph must + * have an internal vertex_index property. Runs in linear time in the + * size of the graph, if access to the property maps is in constant time. + * + * @param graph The given graph. + * @return true if and only if the given graph is bipartite. + */ + + template + bool is_bipartite (const Graph& graph) + { + return is_bipartite (graph, get (vertex_index, graph)); + } + + /** + * Checks a given graph for bipartiteness and fills a given color map with + * white and black according to the bipartition. If the graph is not + * bipartite, a sequence of vertices, producing an odd-cycle, is written to + * the output iterator. The final iterator value is returned. Runs in linear + * time in the size of the graph, if access to the property maps is in + * constant time. + * + * @param graph The given graph. + * @param index_map An index map associating vertices with an index. + * @param partition_map A color map to fill with the bipartition. + * @param result An iterator to write the odd-cycle vertices to. + * @return The final iterator value after writing. + */ + + template + OutputIterator find_odd_cycle (const Graph& graph, const IndexMap index_map, PartitionMap partition_map, + OutputIterator result) + { + /// General types and variables + typedef typename property_traits ::value_type partition_color_t; + typedef typename graph_traits ::vertex_descriptor vertex_descriptor_t; + typedef typename graph_traits ::vertex_iterator vertex_iterator_t; + vertex_iterator_t vertex_iter, vertex_end; + + /// Declare predecessor map + typedef std::vector predecessors_t; + typedef iterator_property_map predecessor_map_t; + typedef predecessor_recorder predecessor_recorder_t; + + predecessors_t predecessors (num_vertices (graph), graph_traits ::null_vertex ()); + predecessor_map_t predecessor_map (predecessors.begin (), index_map); + predecessor_recorder_t predecessor_recorder (predecessor_map); + + /// Initialize predecessor map + for (tie (vertex_iter, vertex_end) = vertices (graph); vertex_iter != vertex_end; ++vertex_iter) + { + put (predecessor_map, *vertex_iter, *vertex_iter); + } + + /// Call dfs + try + { + depth_first_search (graph, vertex_index_map (index_map).visitor (make_dfs_visitor (std::make_pair ( + detail::colorize_bipartition (partition_map), std::make_pair (detail::check_bipartition (partition_map), + std::make_pair (put_property (partition_map, color_traits ::white (), + on_start_vertex ()), record_predecessors (predecessor_map, on_tree_edge ()))))))); + } + catch (detail::bipartite_visitor_error error) + { + typedef std::vector path_t; + + path_t path1, path2; + vertex_descriptor_t next, current; + + /// First path + next = error.witnesses.first; + do + { + current = next; + path1.push_back (current); + next = predecessor_map[current]; + } + while (current != next); + + /// Second path + next = error.witnesses.second; + do + { + current = next; + path2.push_back (current); + next = predecessor_map[current]; + } + while (current != next); + + /// Find beginning of common suffix + std::pair mismatch = detail::reverse_mismatch ( + std::make_pair (path1.begin (), path1.end ()), std::make_pair (path2.begin (), path2.end ())); + + /// Copy the odd-length cycle + result = std::copy (path1.begin (), mismatch.first + 1, result); + return std::reverse_copy (path2.begin (), mismatch.second, result); + } + + return result; + } + + /** + * Checks a given graph for bipartiteness. If the graph is not bipartite, a + * sequence of vertices, producing an odd-cycle, is written to the output + * iterator. The final iterator value is returned. Runs in linear time in the + * size of the graph, if access to the property maps is in constant time. + * + * @param graph The given graph. + * @param index_map An index map associating vertices with an index. + * @param result An iterator to write the odd-cycle vertices to. + * @return The final iterator value after writing. + */ + + template + OutputIterator find_odd_cycle (const Graph& graph, const IndexMap index_map, OutputIterator result) + { + typedef one_bit_color_map partition_map_t; + partition_map_t partition_map (num_vertices (graph), index_map); + + return find_odd_cycle (graph, index_map, partition_map, result); + } + + /** + * Checks a given graph for bipartiteness. If the graph is not bipartite, a + * sequence of vertices, producing an odd-cycle, is written to the output + * iterator. The final iterator value is returned. The graph must have an + * internal vertex_index property. Runs in linear time in the size of the + * graph, if access to the property maps is in constant time. + * + * @param graph The given graph. + * @param result An iterator to write the odd-cycle vertices to. + * @return The final iterator value after writing. + */ + + template + OutputIterator find_odd_cycle (const Graph& graph, OutputIterator result) + { + return find_odd_cycle (graph, get (vertex_index, graph), result); + } +} + +#endif /// BOOST_GRAPH_BIPARTITE_HPP diff --git a/include/boost/graph/compressed_sparse_row_graph.hpp b/include/boost/graph/compressed_sparse_row_graph.hpp index 7b62b3b2..02adcd12 100644 --- a/include/boost/graph/compressed_sparse_row_graph.hpp +++ b/include/boost/graph/compressed_sparse_row_graph.hpp @@ -185,11 +185,11 @@ template class compressed_sparse_row_graph : public detail::indexed_vertex_properties + VertexProperty, Vertex, identity_property_map> { public: typedef detail::indexed_vertex_properties + VertexProperty, Vertex, identity_property_map> inherited_vertex_properties; public: @@ -728,11 +728,11 @@ template class compressed_sparse_row_graph : public detail::indexed_vertex_properties + VertexProperty, Vertex, identity_property_map> { public: typedef detail::indexed_vertex_properties + VertexProperty, Vertex, identity_property_map> inherited_vertex_properties; public: @@ -1394,24 +1394,6 @@ get_property(const BOOST_CSR_GRAPH_TYPE& g, Tag) return get_property_value(g.m_property, Tag()); } -// Add edge_index property map -template -struct csr_edge_index_map -{ - typedef Index value_type; - typedef Index reference; - typedef Descriptor key_type; - typedef readable_property_map_tag category; -}; - -template -inline Index -get(const csr_edge_index_map&, - const typename csr_edge_index_map::key_type& key) -{ - return key.idx; -} - template struct property_map { @@ -1422,16 +1404,24 @@ struct property_map template struct property_map { -private: - typedef typename graph_traits::edge_descriptor - edge_descriptor; - typedef csr_edge_index_map edge_index_type; - -public: - typedef edge_index_type type; + typedef detail::csr_edge_index_map type; typedef type const_type; }; +template +struct property_map +{ + typedef typename BOOST_CSR_GRAPH_TYPE::inherited_vertex_properties::vertex_map_type type; + typedef typename BOOST_CSR_GRAPH_TYPE::inherited_vertex_properties::const_vertex_map_type const_type; +}; + +template +struct property_map +{ + typedef typename BOOST_CSR_GRAPH_TYPE::forward_type::inherited_edge_properties::edge_map_type type; + typedef typename BOOST_CSR_GRAPH_TYPE::forward_type::inherited_edge_properties::const_edge_map_type const_type; +}; + template inline identity_property_map get(vertex_index_t, const BOOST_CSR_GRAPH_TYPE&) @@ -1464,6 +1454,88 @@ get(edge_index_t, const BOOST_CSR_GRAPH_TYPE&, return e.idx; } +template +inline typename property_map::type +get(vertex_bundle_t, BOOST_CSR_GRAPH_TYPE& g) +{ + return g.get_vertex_bundle(get(vertex_index, g)); +} + +template +inline typename property_map::const_type +get(vertex_bundle_t, const BOOST_CSR_GRAPH_TYPE& g) +{ + return g.get_vertex_bundle(get(vertex_index, g)); +} + +template +inline VertexProperty& +get(vertex_bundle_t, + BOOST_CSR_GRAPH_TYPE& g, Vertex v) +{ + return get(vertex_bundle, g)[v]; +} + +template +inline const VertexProperty& +get(vertex_bundle_t, + const BOOST_CSR_GRAPH_TYPE& g, Vertex v) +{ + return get(vertex_bundle, g)[v]; +} + +template +inline void +put(vertex_bundle_t, + BOOST_CSR_GRAPH_TYPE& g, + Vertex v, + const VertexProperty& val) +{ + put(get(vertex_bundle, g), v, val); +} + +template +inline typename property_map::type +get(edge_bundle_t, BOOST_CSR_GRAPH_TYPE& g) +{ + return g.m_forward.get_edge_bundle(get(edge_index, g)); +} + +template +inline typename property_map::const_type +get(edge_bundle_t, const BOOST_CSR_GRAPH_TYPE& g) +{ + return g.m_forward.get_edge_bundle(get(edge_index, g)); +} + +template +inline EdgeProperty& +get(edge_bundle_t, + BOOST_CSR_GRAPH_TYPE& g, + const typename BOOST_CSR_GRAPH_TYPE::edge_descriptor& e) +{ + return get(edge_bundle, g)[e]; +} + +template +inline const EdgeProperty& +get(edge_bundle_t, + const BOOST_CSR_GRAPH_TYPE& g, + const typename BOOST_CSR_GRAPH_TYPE::edge_descriptor& e) +{ + return get(edge_bundle, g)[e]; +} + +template +inline void +put(edge_bundle_t, + BOOST_CSR_GRAPH_TYPE& g, + const typename BOOST_CSR_GRAPH_TYPE::edge_descriptor& e, + const EdgeProperty& val) +{ + put(get(edge_bundle, g), e, val); +} + template inline typename property_map::type diff --git a/include/boost/graph/detail/adjacency_list.hpp b/include/boost/graph/detail/adjacency_list.hpp index 674942e1..d94bc1eb 100644 --- a/include/boost/graph/detail/adjacency_list.hpp +++ b/include/boost/graph/detail/adjacency_list.hpp @@ -1,7 +1,8 @@ // -*- c++ -*- //======================================================================= // Copyright 1997, 1998, 1999, 2000 University of Notre Dame. -// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek +// Copyright 2010 Thomas Claveirole +// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek, Thomas Claveirole // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at @@ -1633,6 +1634,7 @@ namespace boost { const Graph& g = static_cast(g_); return g_.edge_dispatch(g, u, v, Cat()); } + template inline std::pair @@ -1648,10 +1650,9 @@ namespace boost { typename Config::OutEdgeList& el = g.out_edge_list(u); typename Config::OutEdgeList::iterator first, last; typename Config::EdgeContainer fake_edge_container; - tie(first, last) = - std::equal_range(el.begin(), el.end(), - StoredEdge(v, fake_edge_container.end(), - &fake_edge_container)); + tie(first, last) = graph_detail:: + equal_range(el, StoredEdge(v, fake_edge_container.end(), + &fake_edge_container)); return std::make_pair(out_edge_iterator(first, u), out_edge_iterator(last, u)); } diff --git a/include/boost/graph/detail/array_binary_tree.hpp b/include/boost/graph/detail/array_binary_tree.hpp index 6f337e91..78755556 100644 --- a/include/boost/graph/detail/array_binary_tree.hpp +++ b/include/boost/graph/detail/array_binary_tree.hpp @@ -8,18 +8,18 @@ // http://www.boost.org/LICENSE_1_0.txt) //======================================================================= // -#ifndef ADSTL_ARRAY_BINARY_TREE_HPP -#define ADSTL_ARRAY_BINARY_TREE_HPP +#ifndef BOOST_ARRAY_BINARY_TREE_HPP +#define BOOST_ARRAY_BINARY_TREE_HPP #include #include #include -namespace adstl { - /* - Note: array_binary_tree is a completey balanced binary tree - */ +namespace boost { +/* + * Note: array_binary_tree is a completey balanced binary tree. + */ #if !defined BOOST_NO_STD_ITERATOR_TRAITS template #else @@ -45,18 +45,18 @@ public: : boost::iterator { // replace with iterator_adaptor implementation -JGS - + inline iterator() : i(0), n(0) { } inline iterator(const iterator& x) : r(x.r), i(x.i), n(x.n), id(x.id) { } inline iterator& operator=(const iterator& x) { - r = x.r; i = x.i; n = x.n; + r = x.r; i = x.i; n = x.n; /*egcs generate a warning*/ - id = x.id; + id = x.id; return *this; } - inline iterator(rep_iterator rr, - size_type ii, - size_type nn, + inline iterator(rep_iterator rr, + size_type ii, + size_type nn, const ID& _id) : r(rr), i(ii), n(nn), id(_id) { } inline array_binary_tree_node operator*() { return ArrayBinaryTreeNode(r, i, n, id); } @@ -64,7 +64,7 @@ public: inline iterator operator++(int) { iterator t = *this; ++(*this); return t; } inline bool operator==(const iterator& x) const { return i == x.i; } - inline bool operator!=(const iterator& x) const + inline bool operator!=(const iterator& x) const { return !(*this == x); } rep_iterator r; size_type i; @@ -75,13 +75,13 @@ public: inline children_type(const children_type& x) : r(x.r), i(x.i), n(x.n), id(x.id) { } inline children_type& operator=(const children_type& x) { - r = x.r; i = x.i; n = x.n; + r = x.r; i = x.i; n = x.n; /*egcs generate a warning*/ - id = x.id; + id = x.id; return *this; } inline children_type(rep_iterator rr, - size_type ii, + size_type ii, size_type nn, const ID& _id) : r(rr), i(ii), n(nn), id(_id) { } inline iterator begin() { return iterator(r, 2 * i + 1, n, id); } @@ -100,23 +100,23 @@ public: ID id; }; inline array_binary_tree_node() : i(0), n(0) { } - inline array_binary_tree_node(const array_binary_tree_node& x) + inline array_binary_tree_node(const array_binary_tree_node& x) : r(x.r), i(x.i), n(x.n), id(x.id) { } inline ArrayBinaryTreeNode& operator=(const ArrayBinaryTreeNode& x) { r = x.r; - i = x.i; - n = x.n; + i = x.i; + n = x.n; /*egcs generate a warning*/ - id = x.id; + id = x.id; return *this; } - inline array_binary_tree_node(rep_iterator start, - rep_iterator end, + inline array_binary_tree_node(rep_iterator start, + rep_iterator end, rep_iterator pos, const ID& _id) : r(start), i(pos - start), n(end - start), id(_id) { } - inline array_binary_tree_node(rep_iterator rr, - size_type ii, - size_type nn, const ID& _id) + inline array_binary_tree_node(rep_iterator rr, + size_type ii, + size_type nn, const ID& _id) : r(rr), i(ii), n(nn), id(_id) { } inline value_type& value() { return *(r + i); } inline const value_type& value() const { return *(r + i); } @@ -147,8 +147,8 @@ public: value() = tmp; i = x.i; } - inline const children_type children() const { - return children_type(r, i, n); + inline const children_type children() const { + return children_type(r, i, n); } inline size_type index() const { return i; } rep_iterator r; @@ -157,7 +157,7 @@ public: ID id; }; -template > struct compare_array_node { typedef typename RandomAccessContainer::value_type value_type; @@ -176,7 +176,6 @@ struct compare_array_node { Compare comp; }; +} // namespace boost -} /* namespace adstl */ - -#endif /* ADSTL_ARRAY_BINARY_TREE_H */ +#endif /* BOOST_ARRAY_BINARY_TREE_HPP */ diff --git a/include/boost/graph/detail/compressed_sparse_row_struct.hpp b/include/boost/graph/detail/compressed_sparse_row_struct.hpp index 6b4e3913..541b6dd0 100644 --- a/include/boost/graph/detail/compressed_sparse_row_struct.hpp +++ b/include/boost/graph/detail/compressed_sparse_row_struct.hpp @@ -54,6 +54,24 @@ namespace detail { template class csr_edge_descriptor; + // Add edge_index property map + template + struct csr_edge_index_map + { + typedef EdgeIndex value_type; + typedef EdgeIndex reference; + typedef csr_edge_descriptor key_type; + typedef readable_property_map_tag category; + }; + + template + inline EdgeIndex + get(const csr_edge_index_map&, + const csr_edge_descriptor& key) + { + return key.idx; + } + /** Compressed sparse row graph internal structure. * * Vertex and EdgeIndex should be unsigned integral types and should @@ -65,12 +83,14 @@ namespace detail { public detail::indexed_edge_properties< compressed_sparse_row_structure, EdgeProperty, - csr_edge_descriptor > { + csr_edge_descriptor, + csr_edge_index_map > { public: typedef detail::indexed_edge_properties< compressed_sparse_row_structure, EdgeProperty, - csr_edge_descriptor > + csr_edge_descriptor, + csr_edge_index_map > inherited_edge_properties; typedef Vertex vertices_size_type; @@ -110,6 +130,7 @@ namespace detail { source_pred, boost::make_property_map_function(global_to_local)); m_column.resize(m_rowstart.back()); + inherited_edge_properties::resize(m_rowstart.back()); boost::graph::detail::histogram_sort (sources_begin, sources_end, m_rowstart.begin(), numlocalverts, @@ -248,6 +269,7 @@ namespace detail { // Now targets is the correct vector (properly sorted by source) for // m_column m_column.swap(targets); + inherited_edge_properties::resize(m_rowstart.back()); } // Replace graph with sources and targets and edge properties given, sorting @@ -289,6 +311,7 @@ namespace detail { { m_rowstart.resize(numverts + 1); m_column.resize(numedges); + inherited_edge_properties::resize(numedges); EdgeIndex current_edge = 0; typedef typename boost::graph_traits::vertex_descriptor g_vertex; typedef typename boost::graph_traits::edge_descriptor g_edge; diff --git a/include/boost/graph/detail/indexed_properties.hpp b/include/boost/graph/detail/indexed_properties.hpp index 7fa1548e..e1f874b2 100644 --- a/include/boost/graph/detail/indexed_properties.hpp +++ b/include/boost/graph/detail/indexed_properties.hpp @@ -23,17 +23,24 @@ #include #include #include +#include #include namespace boost { namespace detail { -template +template class indexed_vertex_properties { public: typedef no_property vertex_property_type; typedef Property vertex_bundled; + typedef iterator_property_map< + typename std::vector::iterator, + IndexMap> vertex_map_type; + typedef iterator_property_map< + typename std::vector::const_iterator, + IndexMap> const_vertex_map_type; // Directly access a vertex or edge bundle Property& operator[](Descriptor v) @@ -42,6 +49,14 @@ public: const Property& operator[](Descriptor v) const { return m_vertex_properties[get(vertex_index, derived(), v)]; } + vertex_map_type get_vertex_bundle(const IndexMap& index_map = IndexMap()) { + return vertex_map_type(m_vertex_properties.begin(), index_map); + } + + const_vertex_map_type get_vertex_bundle(const IndexMap& index_map = IndexMap()) const { + return const_vertex_map_type(m_vertex_properties.begin(), index_map); + } + protected: // Default-construct with no property values indexed_vertex_properties() {} @@ -90,17 +105,23 @@ public: // should be private, but friend templates not portable std::vector m_vertex_properties; }; -template -class indexed_vertex_properties +template +class indexed_vertex_properties { struct secret {}; public: typedef no_property vertex_property_type; typedef void vertex_bundled; + typedef secret vertex_map_type; + typedef secret const_vertex_map_type; secret operator[](secret) { return secret(); } + vertex_map_type get_vertex_bundle() const { + return vertex_map_type(); + } + protected: // All operations do nothing. indexed_vertex_properties() { } @@ -112,13 +133,19 @@ public: void reserve(std::size_t) { } }; -template +template class indexed_edge_properties { public: typedef no_property edge_property_type; typedef Property edge_bundled; typedef Property edge_push_back_type; + typedef iterator_property_map< + typename std::vector::iterator, + IndexMap> edge_map_type; + typedef iterator_property_map< + typename std::vector::const_iterator, + IndexMap> const_edge_map_type; // Directly access a edge or edge bundle Property& operator[](Descriptor v) @@ -127,6 +154,14 @@ public: const Property& operator[](Descriptor v) const { return m_edge_properties[get(edge_index, derived(), v)]; } + edge_map_type get_edge_bundle(const IndexMap& index_map = IndexMap()) { + return edge_map_type(m_edge_properties.begin(), index_map); + } + + const_edge_map_type get_edge_bundle(const IndexMap& index_map = IndexMap()) const { + return const_edge_map_type(m_edge_properties.begin(), index_map); + } + protected: // Default-construct with no property values indexed_edge_properties() {} @@ -205,8 +240,8 @@ struct dummy_no_property_iterator std::ptrdiff_t distance_to(const dummy_no_property_iterator) const {return 0;} }; -template -class indexed_edge_properties +template +class indexed_edge_properties { struct secret {}; @@ -214,10 +249,16 @@ class indexed_edge_properties typedef no_property edge_property_type; typedef void edge_bundled; typedef void* edge_push_back_type; + typedef secret edge_map_type; + typedef secret const_edge_map_type; secret operator[](secret) { return secret(); } void write_by_index(std::size_t idx, const no_property& prop) {} + edge_map_type get_edge_bundle(const IndexMap& = IndexMap()) const { + return edge_map_type(); + } + protected: // All operations do nothing. indexed_edge_properties() { } diff --git a/include/boost/graph/detail/read_graphviz_new.hpp b/include/boost/graph/detail/read_graphviz_new.hpp index 215f9ef9..7c7986dc 100644 --- a/include/boost/graph/detail/read_graphviz_new.hpp +++ b/include/boost/graph/detail/read_graphviz_new.hpp @@ -89,26 +89,18 @@ namespace read_graphviz_detail { } // namespace read_graphviz_detail -// This is also in boost/graph/graphviz.hpp namespace detail { namespace graph { - BOOST_GRAPH_DECL bool read_graphviz(const std::string& str, boost::detail::graph::mutate_graph* mg); + BOOST_GRAPH_DECL bool read_graphviz_new(const std::string& str, boost::detail::graph::mutate_graph* mg); } // end namespace graph } // end namespace detail template -bool read_graphviz(const std::string& str, - MutableGraph& graph, boost::dynamic_properties& dp, - std::string const& node_id = "node_id") { +bool read_graphviz_new(const std::string& str, + MutableGraph& graph, boost::dynamic_properties& dp, + std::string const& node_id = "node_id") { boost::detail::graph::mutate_graph_impl mg(graph, dp, node_id); - return detail::graph::read_graphviz(str, &mg); -} - -template -bool read_graphviz(InputIter begin, InputIter end, - MutableGraph& graph, boost::dynamic_properties& dp, - std::string const& node_id = "node_id") { - return read_graphviz(std::string(begin, end), graph, dp, node_id); + return detail::graph::read_graphviz_new(str, &mg); } } // namespace boost diff --git a/include/boost/graph/detail/read_graphviz_spirit.hpp b/include/boost/graph/detail/read_graphviz_spirit.hpp index 815befe9..4e8b22e5 100644 --- a/include/boost/graph/detail/read_graphviz_spirit.hpp +++ b/include/boost/graph/detail/read_graphviz_spirit.hpp @@ -581,9 +581,9 @@ struct dot_skipper : public boost::spirit::classic::grammar } // namespace detail template -bool read_graphviz(MultiPassIterator begin, MultiPassIterator end, - MutableGraph& graph, dynamic_properties& dp, - std::string const& node_id = "node_id") { +bool read_graphviz_spirit(MultiPassIterator begin, MultiPassIterator end, + MutableGraph& graph, dynamic_properties& dp, + std::string const& node_id = "node_id") { using namespace boost; using namespace boost::spirit::classic; diff --git a/include/boost/graph/filtered_graph.hpp b/include/boost/graph/filtered_graph.hpp index 4c5f1783..30b34335 100644 --- a/include/boost/graph/filtered_graph.hpp +++ b/include/boost/graph/filtered_graph.hpp @@ -13,6 +13,7 @@ #include #include #include +#include #include namespace boost { diff --git a/include/boost/graph/graph_test.hpp b/include/boost/graph/graph_test.hpp index 554ddbad..77b11b6e 100644 --- a/include/boost/graph/graph_test.hpp +++ b/include/boost/graph/graph_test.hpp @@ -17,6 +17,8 @@ #include #include #include // for connects +#include +#include // UNDER CONSTRUCTION @@ -171,7 +173,7 @@ namespace boost { BOOST_CHECK(m == num_edges(g)); for (; p.first != p.second; ++p.first) { edge_t e = *p.first; - BOOST_CHECK(any_if(edge_set, connects(source(e, g), target(e, g), g))); + BOOST_CHECK(find_if(edge_set, connects(source(e, g), target(e, g), g)) != end(edge_set)); BOOST_CHECK(container_contains(vertex_set, source(e, g)) == true); BOOST_CHECK(container_contains(vertex_set, target(e, g)) == true); } @@ -196,8 +198,8 @@ namespace boost { for (k = vertex_set.begin(); k != vertex_set.end(); ++k) { p = edge(*j, *k, g); if (p.second == true) - BOOST_CHECK(any_if(edge_set, - connects(source(p.first, g), target(p.first, g), g)) == true); + BOOST_CHECK(find_if(edge_set, + connects(source(p.first, g), target(p.first, g), g)) != end(edge_set)); } } diff --git a/include/boost/graph/graphml.hpp b/include/boost/graph/graphml.hpp index 2193b4ce..b4955b88 100644 --- a/include/boost/graph/graphml.hpp +++ b/include/boost/graph/graphml.hpp @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -101,12 +102,16 @@ class mutate_graph_impl : public mutate_graph } catch (bad_lexical_cast) { - throw parse_error("invalid value \"" + value + "\" for key " + - name + " of type " + value_type); + BOOST_THROW_EXCEPTION( + parse_error("invalid value \"" + value + "\" for key " + + name + " of type " + value_type)); } if (!type_found) - throw parse_error("unrecognized type \"" + value_type + - "\" for key " + name); + { + BOOST_THROW_EXCEPTION( + parse_error("unrecognized type \"" + value_type + + "\" for key " + name)); + } } @@ -122,12 +127,16 @@ class mutate_graph_impl : public mutate_graph } catch (bad_lexical_cast) { - throw parse_error("invalid value \"" + value + "\" for key " + - name + " of type " + value_type); + BOOST_THROW_EXCEPTION( + parse_error("invalid value \"" + value + "\" for key " + + name + " of type " + value_type)); } if (!type_found) - throw parse_error("unrecognized type \"" + value_type + - "\" for key " + name); + { + BOOST_THROW_EXCEPTION( + parse_error("unrecognized type \"" + value_type + + "\" for key " + name)); + } } @@ -143,12 +152,16 @@ class mutate_graph_impl : public mutate_graph } catch (bad_lexical_cast) { - throw parse_error("invalid value \"" + value + "\" for key " + - name + " of type " + value_type); + BOOST_THROW_EXCEPTION( + parse_error("invalid value \"" + value + "\" for key " + + name + " of type " + value_type)); } if (!type_found) - throw parse_error("unrecognized type \"" + value_type + - "\" for key " + name); + { + BOOST_THROW_EXCEPTION( + parse_error("unrecognized type \"" + value_type + + "\" for key " + name)); + } } template diff --git a/include/boost/graph/graphviz.hpp b/include/boost/graph/graphviz.hpp index 52f3468a..a41116d0 100644 --- a/include/boost/graph/graphviz.hpp +++ b/include/boost/graph/graphviz.hpp @@ -25,6 +25,7 @@ #include #include #include +#include namespace boost { @@ -771,26 +772,7 @@ class mutate_graph_impl : public mutate_graph std::map bgl_edges; }; -BOOST_GRAPH_DECL -bool read_graphviz(std::istream& in, mutate_graph& graph); - -} } // end namespace detail::graph - -// Parse the passed stream as a GraphViz dot file. -template -bool read_graphviz(std::istream& in, MutableGraph& graph, - dynamic_properties& dp, - std::string const& node_id = "node_id") -{ - std::string data; - in >> std::noskipws; - std::copy(std::istream_iterator(in), - std::istream_iterator(), - std::back_inserter(data)); - return read_graphviz(data,graph,dp,node_id); -} - -} // namespace boost +} } } // end namespace boost::detail::graph #ifdef BOOST_GRAPH_USE_SPIRIT_PARSER # ifndef BOOST_GRAPH_READ_GRAPHVIZ_ITERATORS @@ -801,6 +783,54 @@ bool read_graphviz(std::istream& in, MutableGraph& graph, # include #endif // BOOST_GRAPH_USE_SPIRIT_PARSER +namespace boost { + +// Parse the passed string as a GraphViz dot file. +template +bool read_graphviz(const std::string& data, + MutableGraph& graph, + dynamic_properties& dp, + std::string const& node_id = "node_id") { +#ifdef BOOST_GRAPH_USE_SPIRIT_PARSER + return read_graphviz_spirit(data.begin(), data.end(), graph, dp, node_id); +#else // Non-Spirit parser + return read_graphviz_new(data,graph,dp,node_id); +#endif +} + +// Parse the passed iterator range as a GraphViz dot file. +template +bool read_graphviz(InputIterator user_first, + InputIterator user_last, + MutableGraph& graph, + dynamic_properties& dp, + std::string const& node_id = "node_id") { +#ifdef BOOST_GRAPH_USE_SPIRIT_PARSER + typedef InputIterator is_t; + typedef boost::spirit::classic::multi_pass iterator_t; + + iterator_t first(boost::spirit::classic::make_multi_pass(user_first)); + iterator_t last(boost::spirit::classic::make_multi_pass(user_last)); + + return read_graphviz_spirit(first, last, graph, dp, node_id); +#else // Non-Spirit parser + return read_graphviz_new(std::string(user_first, user_last), graph, dp, node_id); +#endif +} + +// Parse the passed stream as a GraphViz dot file. +template +bool read_graphviz(std::istream& in, MutableGraph& graph, + dynamic_properties& dp, + std::string const& node_id = "node_id") +{ + typedef std::istream_iterator is_t; + in >> std::noskipws; + return read_graphviz(is_t(in), is_t(), graph, dp, node_id); +} + +} // namespace boost + #ifdef BOOST_GRAPH_USE_MPI # include #endif diff --git a/include/boost/graph/gursoy_atun_layout.hpp b/include/boost/graph/gursoy_atun_layout.hpp index ed5e0509..b16a01f6 100644 --- a/include/boost/graph/gursoy_atun_layout.hpp +++ b/include/boost/graph/gursoy_atun_layout.hpp @@ -16,6 +16,7 @@ // http://springerlink.metapress.com/link.asp?id=pcu07ew5rhexp9yt #include +#include #include #include #include @@ -72,7 +73,7 @@ struct update_position_visitor { #endif if (get(node_distance, v) > distance_limit) - throw over_distance_limit(); + BOOST_THROW_EXCEPTION(over_distance_limit()); Point old_position = get(position_map, v); double distance = get(node_distance, v); double fraction = diff --git a/include/boost/graph/metric_tsp_approx.hpp b/include/boost/graph/metric_tsp_approx.hpp index 7c18b8e0..02709539 100644 --- a/include/boost/graph/metric_tsp_approx.hpp +++ b/include/boost/graph/metric_tsp_approx.hpp @@ -35,7 +35,7 @@ #include #include #include - +#include namespace boost { @@ -287,7 +287,7 @@ namespace boost bool found; tie(e, found) = lookup_edge(previous_, v, g); if(!found) { - throw not_complete(); + BOOST_THROW_EXCEPTION(not_complete()); } tourlen_ += wmap_[e]; diff --git a/include/boost/graph/one_bit_color_map.hpp b/include/boost/graph/one_bit_color_map.hpp new file mode 100644 index 00000000..95a9604f --- /dev/null +++ b/include/boost/graph/one_bit_color_map.hpp @@ -0,0 +1,103 @@ +// Copyright (C) 2005-2010 The Trustees of Indiana University. + +// 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) + +// Authors: Jeremiah Willcock +// Douglas Gregor +// Andrew Lumsdaine + +// One bit per color property map (gray and black are the same, green is not +// supported) + +#ifndef BOOST_ONE_BIT_COLOR_MAP_HPP +#define BOOST_ONE_BIT_COLOR_MAP_HPP + +#include +#include +#include +#include +#include +#include + +namespace boost { + +enum one_bit_color_type { + one_bit_white = 0, + one_bit_not_white = 1 +}; + +template <> +struct color_traits +{ + static one_bit_color_type white() { return one_bit_white; } + static one_bit_color_type gray() { return one_bit_not_white; } + static one_bit_color_type black() { return one_bit_not_white; } +}; + + +template +struct one_bit_color_map +{ + BOOST_STATIC_CONSTANT(int, bits_per_char = std::numeric_limits::digits); + std::size_t n; + IndexMap index; + shared_array data; + + typedef typename property_traits::key_type key_type; + typedef one_bit_color_type value_type; + typedef void reference; + typedef read_write_property_map_tag category; + + explicit one_bit_color_map(std::size_t n, const IndexMap& index = IndexMap()) + : n(n), index(index), data(new unsigned char[(n + bits_per_char - 1) / bits_per_char]) + { + // Fill to white + std::fill(data.get(), data.get() + (n + bits_per_char - 1) / bits_per_char, 0); + } +}; + +template +inline one_bit_color_type +get(const one_bit_color_map& pm, + typename property_traits::key_type key) +{ + BOOST_STATIC_CONSTANT(int, bits_per_char = one_bit_color_map::bits_per_char); + typename property_traits::value_type i = get(pm.index, key); + assert ((std::size_t)i < pm.n); + return one_bit_color_type((pm.data.get()[i / bits_per_char] >> (i % bits_per_char)) & 1); +} + +template +inline void +put(const one_bit_color_map& pm, + typename property_traits::key_type key, + one_bit_color_type value) +{ + BOOST_STATIC_CONSTANT(int, bits_per_char = one_bit_color_map::bits_per_char); + typename property_traits::value_type i = get(pm.index, key); + assert ((std::size_t)i < pm.n); + assert (value >= 0 && value < 2); + std::size_t byte_num = i / bits_per_char; + std::size_t bit_position = (i % bits_per_char); + pm.data.get()[byte_num] = + (unsigned char) + ((pm.data.get()[byte_num] & ~(1 << bit_position)) + | (value << bit_position)); +} + +template +inline one_bit_color_map +make_one_bit_color_map(std::size_t n, const IndexMap& index_map) +{ + return one_bit_color_map(n, index_map); +} + +} // end namespace boost + +#endif // BOOST_ONE_BIT_COLOR_MAP_HPP + +#ifdef BOOST_GRAPH_USE_MPI +# include +#endif diff --git a/include/boost/graph/topological_sort.hpp b/include/boost/graph/topological_sort.hpp index 9a7f6eb8..08baf69b 100644 --- a/include/boost/graph/topological_sort.hpp +++ b/include/boost/graph/topological_sort.hpp @@ -16,6 +16,7 @@ #include #include #include +#include namespace boost { @@ -37,7 +38,7 @@ namespace boost { : m_iter(_iter) { } template - void back_edge(const Edge&, Graph&) { throw not_a_dag(); } + void back_edge(const Edge&, Graph&) { BOOST_THROW_EXCEPTION(not_a_dag()); } template void finish_vertex(const Vertex& u, Graph&) { *m_iter++ = u; } diff --git a/include/boost/graph/two_bit_color_map.hpp b/include/boost/graph/two_bit_color_map.hpp index 1a3336bd..9a3872fd 100644 --- a/include/boost/graph/two_bit_color_map.hpp +++ b/include/boost/graph/two_bit_color_map.hpp @@ -16,7 +16,9 @@ #include #include #include +#include #include +#include namespace boost { @@ -44,40 +46,46 @@ struct two_bit_color_map IndexMap index; shared_array data; + BOOST_STATIC_CONSTANT(int, bits_per_char = std::numeric_limits::digits); + BOOST_STATIC_CONSTANT(int, elements_per_char = bits_per_char / 2); typedef typename property_traits::key_type key_type; typedef two_bit_color_type value_type; typedef void reference; typedef read_write_property_map_tag category; explicit two_bit_color_map(std::size_t n, const IndexMap& index = IndexMap()) - : n(n), index(index), data(new unsigned char[(n + 3) / 4]) + : n(n), index(index), data(new unsigned char[(n + elements_per_char - 1) / elements_per_char]) { // Fill to white - std::fill(data.get(), data.get() + (n + 3) / 4, 0); + std::fill(data.get(), data.get() + (n + elements_per_char - 1) / elements_per_char, 0); } }; template inline two_bit_color_type get(const two_bit_color_map& pm, - typename two_bit_color_map::key_type key) + typename property_traits::key_type key) { + BOOST_STATIC_CONSTANT(int, elements_per_char = two_bit_color_map::elements_per_char); typename property_traits::value_type i = get(pm.index, key); assert ((std::size_t)i < pm.n); - return two_bit_color_type((pm.data.get()[i / 4] >> ((i % 4) * 2)) & 3); + std::size_t byte_num = i / elements_per_char; + std::size_t bit_position = ((i % elements_per_char) * 2); + return two_bit_color_type((pm.data.get()[byte_num] >> bit_position) & 3); } template inline void put(const two_bit_color_map& pm, - typename two_bit_color_map::key_type key, + typename property_traits::key_type key, two_bit_color_type value) { + BOOST_STATIC_CONSTANT(int, elements_per_char = two_bit_color_map::elements_per_char); typename property_traits::value_type i = get(pm.index, key); assert ((std::size_t)i < pm.n); assert (value >= 0 && value < 4); - std::size_t byte_num = i / 4; - std::size_t bit_position = ((i % 4) * 2); + std::size_t byte_num = i / elements_per_char; + std::size_t bit_position = ((i % elements_per_char) * 2); pm.data.get()[byte_num] = (unsigned char) ((pm.data.get()[byte_num] & ~(3 << bit_position)) diff --git a/include/boost/graph/visitors.hpp b/include/boost/graph/visitors.hpp index 1091f101..f986c96c 100644 --- a/include/boost/graph/visitors.hpp +++ b/include/boost/graph/visitors.hpp @@ -251,6 +251,52 @@ namespace boost { return property_writer(pa, out); } + //======================================================================== + // property_put + + /** + * Functor which just sets a given value to a vertex or edge in a property map. + */ + + template + struct property_put + { + typedef EventTag event_filter; + + property_put (PropertyMap property_map, + typename property_traits ::value_type value) : + property_map_ (property_map), value_ (value) + {} + + template + void operator() (VertexOrEdge v, const Graph& g) + { + put (property_map_, v, value_); + } + + private: + PropertyMap property_map_; + typename property_traits ::value_type value_; + }; + + /** + * Creates a property_put functor which just sets a given value to a vertex or edge. + * + * @param property_map Given writeable property map + * @param value Fixed value of the map + * @param tag Event Filter + * @return The functor. + */ + + template + inline property_put + put_property (PropertyMap property_map, + typename property_traits ::value_type value, + EventTag tag) + { + return property_put (property_map, value); + } + #define BOOST_GRAPH_EVENT_STUB(Event,Kind) \ typedef ::boost::Event Event##_type; \ template \ diff --git a/include/boost/pending/container_traits.hpp b/include/boost/pending/container_traits.hpp index 571eedb1..72651d58 100644 --- a/include/boost/pending/container_traits.hpp +++ b/include/boost/pending/container_traits.hpp @@ -1,4 +1,6 @@ // (C) Copyright Jeremy Siek 2004 +// (C) Copyright Thomas Claveirole 2010 +// (C) Copyright Ignacy Gawedzki 2010 // 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) @@ -17,19 +19,8 @@ #include #include #include - -#if !defined BOOST_NO_HASH -# ifdef BOOST_HASH_SET_HEADER -# include BOOST_HASH_SET_HEADER -# else -# include -# endif -# ifdef BOOST_HASH_MAP_HEADER -# include BOOST_HASH_MAP_HEADER -# else -# include -# endif -#endif +#include +#include #if !defined BOOST_NO_SLIST # ifdef BOOST_SLIST_HEADER @@ -273,34 +264,87 @@ namespace boost { namespace graph_detail { // hash_set, hash_map + struct unordered_set_tag : + virtual public simple_associative_container_tag, + virtual public unique_associative_container_tag + { }; + + struct unordered_multiset_tag : + virtual public simple_associative_container_tag, + virtual public multiple_associative_container_tag + { }; + + + struct unordered_map_tag : + virtual public pair_associative_container_tag, + virtual public unique_associative_container_tag + { }; + + struct unordered_multimap_tag : + virtual public pair_associative_container_tag, + virtual public multiple_associative_container_tag + { }; + + #ifndef BOOST_NO_HASH #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION template - struct container_traits< BOOST_STD_EXTENSION_NAMESPACE::hash_set > { - typedef set_tag category; - typedef stable_tag iterator_stability; // is this right? + struct container_traits< boost::unordered_set > { + typedef unordered_set_tag category; + typedef unstable_tag iterator_stability; }; template - struct container_traits< BOOST_STD_EXTENSION_NAMESPACE::hash_map > { - typedef map_tag category; - typedef stable_tag iterator_stability; // is this right? + struct container_traits< boost::unordered_map > { + typedef unordered_map_tag category; + typedef unstable_tag iterator_stability; + }; + template + struct container_traits< boost::unordered_multiset > { + typedef unordered_multiset_tag category; + typedef unstable_tag iterator_stability; + }; + template + struct container_traits< boost::unordered_multimap > { + typedef unordered_multimap_tag category; + typedef unstable_tag iterator_stability; }; #endif template - set_tag container_category(const BOOST_STD_EXTENSION_NAMESPACE::hash_set&) - { return set_tag(); } + unordered_set_tag + container_category(const boost::unordered_set&) + { return unordered_set_tag(); } template - map_tag container_category(const BOOST_STD_EXTENSION_NAMESPACE::hash_map&) - { return map_tag(); } + unordered_map_tag + container_category(const boost::unordered_map&) + { return unordered_map_tag(); } template - stable_tag iterator_stability(const BOOST_STD_EXTENSION_NAMESPACE::hash_set&) - { return stable_tag(); } + unstable_tag iterator_stability(const boost::unordered_set&) + { return unstable_tag(); } template - stable_tag iterator_stability(const BOOST_STD_EXTENSION_NAMESPACE::hash_map&) - { return stable_tag(); } + unstable_tag iterator_stability(const boost::unordered_map&) + { return unstable_tag(); } + template + unordered_multiset_tag + container_category(const boost::unordered_multiset&) + { return unordered_multiset_tag(); } + + template + unordered_multimap_tag + container_category(const boost::unordered_multimap&) + { return unordered_multimap_tag(); } + + template + unstable_tag + iterator_stability(const boost::unordered_multiset&) + { return unstable_tag(); } + + template + unstable_tag + iterator_stability(const boost::unordered_multimap&) + { return unstable_tag(); } #endif @@ -414,6 +458,37 @@ namespace boost { namespace graph_detail { return push_dispatch(c, v, container_category(c)); } + // Equal range + template + std::pair + equal_range_dispatch(Container& c, + const LessThanComparable& value, + container_tag) + { + // c must be sorted for std::equal_range to behave properly. + return std::equal_range(c.begin(), c.end(), value); + } + + template + std::pair + equal_range_dispatch(AssociativeContainer& c, + const LessThanComparable& value, + associative_container_tag) + { + return c.equal_range(value); + } + + template + std::pair + equal_range(Container& c, + const LessThanComparable& value) + { + return equal_range_dispatch(c, value, + graph_detail::container_category(c)); + } + }} // namespace boost::graph_detail #if BOOST_WORKAROUND(BOOST_MSVC, < 1300) diff --git a/include/boost/pending/indirect_cmp.hpp b/include/boost/pending/indirect_cmp.hpp index 5e866561..638625ce 100644 --- a/include/boost/pending/indirect_cmp.hpp +++ b/include/boost/pending/indirect_cmp.hpp @@ -65,7 +65,7 @@ namespace boost { inline indirect_pmap(const ReadablePropertyMap& df) : d(df) { } - inline bool operator()(const K& u) const { + inline T operator()(const K& u) const { return get(d, u); } protected: diff --git a/include/boost/pending/mutable_queue.hpp b/include/boost/pending/mutable_queue.hpp index a4e2050d..82cfdd81 100644 --- a/include/boost/pending/mutable_queue.hpp +++ b/include/boost/pending/mutable_queue.hpp @@ -23,20 +23,20 @@ namespace boost { // The mutable queue whose elements are indexed - // + // // This adaptor provides a special kind of priority queue that has // and update operation. This allows the ordering of the items to // change. After the ordering criteria for item x changes, one must // call the Q.update(x) - // + // // In order to efficiently find x in the queue, a functor must be // provided to map value_type to a unique ID, which the // mutable_queue will then use to map to the location of the // item. The ID's generated must be between 0 and N, where N is the // value passed to the constructor of mutable_queue - template , + template , class Comp = std::less, class ID = identity_property_map > class mutable_queue { @@ -46,23 +46,23 @@ namespace boost { protected: typedef typename RandomAccessContainer::iterator iterator; #if !defined BOOST_NO_STD_ITERATOR_TRAITS - typedef adstl::array_binary_tree_node Node; + typedef array_binary_tree_node Node; #else - typedef adstl::array_binary_tree_node Node; + typedef array_binary_tree_node Node; #endif - typedef adstl::compare_array_node Compare; + typedef compare_array_node Compare; typedef std::vector IndexArray; public: typedef Compare value_compare; typedef ID id_generator; - mutable_queue(size_type n, const Comp& x, const ID& _id) + mutable_queue(size_type n, const Comp& x, const ID& _id) : index_array(n), comp(x), id(_id) { - c.reserve(n); + c.reserve(n); } template - mutable_queue(ForwardIterator first, ForwardIterator last, - const Comp& x, const ID& _id) + mutable_queue(ForwardIterator first, ForwardIterator last, + const Comp& x, const ID& _id) : index_array(std::distance(first, last)), comp(x), id(_id) { while( first != last ) { @@ -72,7 +72,7 @@ namespace boost { } bool empty() const { return c.empty(); } - + void pop() { value_type tmp = c.back(); c.back() = c.front(); @@ -86,7 +86,7 @@ namespace boost { c.pop_back(); Node node(c.begin(), c.end(), c.begin(), id); - down_heap(node, comp, index_array); + down_heap(node, comp, index_array); } void push(const IndexedType& x) { c.push_back(x); @@ -120,7 +120,7 @@ namespace boost { bool test() { return std::is_heap(c.begin(), c.end(), Comp()); } -#endif +#endif protected: IndexArray index_array; diff --git a/src/graphml.cpp b/src/graphml.cpp index 300b65fa..4f9677df 100644 --- a/src/graphml.cpp +++ b/src/graphml.cpp @@ -13,6 +13,7 @@ #define BOOST_GRAPH_SOURCE #include #include +#include #include #include #include @@ -62,7 +63,7 @@ public: else if (for_ == "port") kind = port_key; else if (for_ == "endpoint") kind = endpoint_key; else if (for_ == "all") kind = all_key; - else throw parse_error("Attribute for is not valid: " + for_); + else {BOOST_THROW_EXCEPTION(parse_error("Attribute for is not valid: " + for_));} m_keys[id] = kind; m_key_name[id] = name; m_key_type[id] = type; @@ -97,7 +98,11 @@ public: std::string local_directed = edge.second.get(path("/directed"), ""); bool is_directed = (local_directed == "" ? default_directed : local_directed == "true"); if (is_directed != m_g.is_directed()) { - if (is_directed) throw directed_graph_error(); else throw undirected_graph_error(); + if (is_directed) { + BOOST_THROW_EXCEPTION(directed_graph_error()); + } else { + BOOST_THROW_EXCEPTION(undirected_graph_error()); + } } size_t old_edges_size = m_edge.size(); handle_edge(source, target); @@ -164,8 +169,9 @@ private: any edge; bool added; tie(edge, added) = m_g.do_add_edge(source, target); - if (!added) - throw bad_parallel_edge(u, v); + if (!added) { + BOOST_THROW_EXCEPTION(bad_parallel_edge(u, v)); + } size_t e = m_edge.size(); m_edge.push_back(edge); diff --git a/src/read_graphviz_new.cpp b/src/read_graphviz_new.cpp index 7da57788..9e87ca23 100644 --- a/src/read_graphviz_new.cpp +++ b/src/read_graphviz_new.cpp @@ -793,7 +793,7 @@ namespace read_graphviz_detail { namespace detail { namespace graph { - BOOST_GRAPH_DECL bool read_graphviz(const std::string& str, boost::detail::graph::mutate_graph* mg) { + BOOST_GRAPH_DECL bool read_graphviz_new(const std::string& str, boost::detail::graph::mutate_graph* mg) { read_graphviz_detail::parser_result parsed_file; read_graphviz_detail::parse_graphviz_from_string(str, parsed_file, mg->is_directed()); read_graphviz_detail::translate_results_to_graph(parsed_file, mg); diff --git a/src/read_graphviz_spirit.cpp b/src/read_graphviz_spirit.cpp deleted file mode 100644 index 7fcdc280..00000000 --- a/src/read_graphviz_spirit.cpp +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright 2004-5 Trustees of Indiana University - -// Use, modification and distribution is subject to 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) - -// -// read_graphviz_spirit.hpp - -// Initialize a model of the BGL's MutableGraph concept and an associated -// collection of property maps using a graph expressed in the GraphViz -// DOT Language. -// -// Based on the grammar found at: -// http://www.graphviz.org/cvs/doc/info/lang.html -// -// See documentation for this code at: -// http://www.boost.org/libs/graph/doc/read-graphviz.html -// - -// Authors: Ronald Garcia and Douglas Gregor -// - -#define BOOST_GRAPH_SOURCE - -#ifndef BOOST_GRAPH_READ_GRAPHVIZ_ITERATORS -# define BOOST_GRAPH_READ_GRAPHVIZ_ITERATORS -#endif -#include -#include - -namespace boost { namespace detail { namespace graph { - -#if 0 -BOOST_GRAPH_DECL -bool read_graphviz(std::istream& in, mutate_graph& graph) -{ - using namespace boost; - - typedef std::istream_iterator is_t; - - std::string str((is_t(in)), is_t()); - - return read_graphviz(str.begin(), str.end()); -} -#endif - -} } } // end namespace boost::detail::graph diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 1aa5bc8d..b3262fcc 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -36,6 +36,7 @@ test-suite graph_test : [ run bellman-test.cpp ] [ run betweenness_centrality_test.cpp : 100 ] [ run bidir_remove_edge.cpp ] + [ run bipartite_test.cpp ] [ run csr_graph_test.cpp : : : : : release ] [ run dag_longest_paths.cpp ] [ run dfs.cpp ../../test/build//boost_test_exec_monitor ] @@ -53,7 +54,7 @@ test-suite graph_test : [ run graphviz_test.cpp /boost/test//boost_test_exec_monitor/static ../build//boost_graph - ../../regex/build//boost_regex ] + ../../regex/build//boost_regex : --log_level=all ] [ run metis_test.cpp : $(METIS_INPUT_FILE) ] [ run gursoy_atun_layout_test.cpp ] [ run layout_test.cpp : : : always_show_run_output intel:off ] diff --git a/test/bipartite_test.cpp b/test/bipartite_test.cpp new file mode 100644 index 00000000..30ab5c72 --- /dev/null +++ b/test/bipartite_test.cpp @@ -0,0 +1,189 @@ +/** + * + * Copyright (c) 2010 Matthias Walter (xammy@xammy.homelinux.net) + * + * Authors: Matthias Walter + * + * 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 +#include + +/// Verifies a 2-coloring + +template +void check_two_coloring (const Graph& g, const ColorMap color_map) +{ + typedef boost::graph_traits traits; + typename traits::edge_iterator edge_iter, edge_end; + + for (boost::tie (edge_iter, edge_end) = boost::edges (g); edge_iter != edge_end; ++edge_iter) + { + typename traits::vertex_descriptor source, target; + source = boost::source (*edge_iter, g); + target = boost::target (*edge_iter, g); + BOOST_REQUIRE (boost::get(color_map, source) != boost::get(color_map, target)); + } +} + +/// Tests for a vertex sequence to define an odd cycle + +template +void check_odd_cycle (const Graph& g, RandomAccessIterator first, RandomAccessIterator beyond) +{ + typedef boost::graph_traits traits; + + typename traits::vertex_descriptor first_vertex, current_vertex, last_vertex; + + BOOST_CHECK ((beyond - first) % 2 == 1); + + // std::cout << "odd_cycle: " << int(*first) << std::endl; + + for (first_vertex = current_vertex = *first++; first != beyond; ++first) + { + // std::cout << "odd_cycle: " << int(*first) << std::endl; + + last_vertex = current_vertex; + current_vertex = *first; + + BOOST_REQUIRE (boost::lookup_edge (current_vertex, last_vertex, g).second); + } + + BOOST_REQUIRE (boost::lookup_edge (first_vertex, current_vertex, g).second); +} + +/// Call the is_bipartite and find_odd_cycle functions and verify their results. + +template +void check_bipartite (const Graph& g, IndexMap index_map, bool is_bipartite) +{ + typedef boost::graph_traits traits; + typedef std::vector partition_t; + typedef std::vector vertex_vector_t; + typedef boost::iterator_property_map partition_map_t; + + partition_t partition (boost::num_vertices (g)); + partition_map_t partition_map (partition.begin (), index_map); + + vertex_vector_t odd_cycle (boost::num_vertices (g)); + + bool first_result = boost::is_bipartite (g, index_map, partition_map); + + BOOST_REQUIRE (first_result == boost::is_bipartite(g, index_map)); + + if (first_result) + check_two_coloring (g, partition_map); + + BOOST_CHECK (first_result == is_bipartite); + + typename vertex_vector_t::iterator second_first = odd_cycle.begin (); + typename vertex_vector_t::iterator second_beyond = boost::find_odd_cycle (g, index_map, partition_map, second_first); + + if (is_bipartite) + { + BOOST_CHECK (second_beyond == second_first); + check_two_coloring (g, partition_map); + } + else + { + check_odd_cycle (g, second_first, second_beyond); + } + + second_beyond = boost::find_odd_cycle (g, index_map, second_first); + if (is_bipartite) + { + BOOST_CHECK (second_beyond == second_first); + } + else + { + check_odd_cycle (g, second_first, second_beyond); + } +} + +int test_main (int argc, char **argv) +{ + typedef boost::adjacency_list vector_graph_t; + typedef boost::adjacency_list list_graph_t; + typedef std::pair E; + + typedef std::map ::vertex_descriptor, size_t> index_map_t; + typedef boost::associative_property_map index_property_map_t; + + /** + * Create the graph drawn below. + * + * 0 - 1 - 2 + * | | + * 3 - 4 - 5 - 6 + * / \ / + * | 7 + * | | + * 8 - 9 - 10 + **/ + + E bipartite_edges[] = { E (0, 1), E (0, 4), E (1, 2), E (2, 6), E (3, 4), E (3, 8), E (4, 5), E (4, 7), E (5, 6), E ( + 6, 7), E (7, 10), E (8, 9), E (9, 10) }; + vector_graph_t bipartite_vector_graph (&bipartite_edges[0], + &bipartite_edges[0] + sizeof(bipartite_edges) / sizeof(E), 11); + list_graph_t + bipartite_list_graph (&bipartite_edges[0], &bipartite_edges[0] + sizeof(bipartite_edges) / sizeof(E), 11); + + /** + * Create the graph drawn below. + * + * 2 - 1 - 0 + * | | + * 3 - 6 - 5 - 4 + * / \ / + * | 7 + * | / + * 8 ---- 9 + * + **/ + + E non_bipartite_edges[] = { E (0, 1), E (0, 4), E (1, 2), E (2, 6), E (3, 4), E (3, 8), E (4, 5), E (4, 7), E (5, 6), + E (6, 7), E (7, 9), E (8, 9) }; + vector_graph_t non_bipartite_vector_graph (&non_bipartite_edges[0], &non_bipartite_edges[0] + + sizeof(non_bipartite_edges) / sizeof(E), 10); + list_graph_t non_bipartite_list_graph (&non_bipartite_edges[0], &non_bipartite_edges[0] + sizeof(non_bipartite_edges) + / sizeof(E), 10); + + /// Create index maps + + index_map_t bipartite_index_map, non_bipartite_index_map; + boost::graph_traits ::vertex_iterator vertex_iter, vertex_end; + size_t i = 0; + for (boost::tie (vertex_iter, vertex_end) = boost::vertices (bipartite_list_graph); vertex_iter != vertex_end; ++vertex_iter) + { + bipartite_index_map[*vertex_iter] = i++; + } + index_property_map_t bipartite_index_property_map = index_property_map_t (bipartite_index_map); + + i = 0; + for (boost::tie (vertex_iter, vertex_end) = boost::vertices (non_bipartite_list_graph); vertex_iter != vertex_end; ++vertex_iter) + { + non_bipartite_index_map[*vertex_iter] = i++; + } + index_property_map_t non_bipartite_index_property_map = index_property_map_t (non_bipartite_index_map); + + /// Call real checks + + check_bipartite (bipartite_vector_graph, boost::get (boost::vertex_index, bipartite_vector_graph), true); + check_bipartite (bipartite_list_graph, bipartite_index_property_map, true); + + check_bipartite (non_bipartite_vector_graph, boost::get (boost::vertex_index, non_bipartite_vector_graph), false); + check_bipartite (non_bipartite_list_graph, non_bipartite_index_property_map, false); + + /// Test some more interfaces + + BOOST_REQUIRE (is_bipartite (bipartite_vector_graph)); + BOOST_REQUIRE (!is_bipartite (non_bipartite_vector_graph)); + + return 0; +} diff --git a/test/csr_graph_test.cpp b/test/csr_graph_test.cpp index 6e8f3fbf..327ea793 100644 --- a/test/csr_graph_test.cpp +++ b/test/csr_graph_test.cpp @@ -19,6 +19,7 @@ #include #include #include +#include // for ignore_unused_variable_warning #include #include #include @@ -43,10 +44,15 @@ struct VertexData int index; }; -typedef boost::compressed_sparse_row_graph +struct EdgeData +{ + int index_e; +}; + +typedef boost::compressed_sparse_row_graph CSRGraphT; -typedef boost::compressed_sparse_row_graph +typedef boost::compressed_sparse_row_graph BidirCSRGraphT; template @@ -423,6 +429,27 @@ int test_main(int argc, char* argv[]) std::cout << "Testing CSR graph built from unsorted edges" << std::endl; std::pair unsorted_edges[] = {std::make_pair(5, 0), std::make_pair(3, 2), std::make_pair(4, 1), std::make_pair(4, 0), std::make_pair(0, 2), std::make_pair(5, 2)}; CSRGraphT g(boost::edges_are_unsorted, unsorted_edges, unsorted_edges + sizeof(unsorted_edges) / sizeof(*unsorted_edges), 6); + + // Test vertex and edge bundle access + boost::ignore_unused_variable_warning( + (VertexData&)get(get(boost::vertex_bundle, g), vertex(0, g))); + boost::ignore_unused_variable_warning( + (const VertexData&)get(get(boost::vertex_bundle, (const CSRGraphT&)g), vertex(0, g))); + boost::ignore_unused_variable_warning( + (VertexData&)get(boost::vertex_bundle, g, vertex(0, g))); + boost::ignore_unused_variable_warning( + (const VertexData&)get(boost::vertex_bundle, (const CSRGraphT&)g, vertex(0, g))); + put(boost::vertex_bundle, g, vertex(0, g), VertexData()); + boost::ignore_unused_variable_warning( + (EdgeData&)get(get(boost::edge_bundle, g), *edges(g).first)); + boost::ignore_unused_variable_warning( + (const EdgeData&)get(get(boost::edge_bundle, (const CSRGraphT&)g), *edges(g).first)); + boost::ignore_unused_variable_warning( + (EdgeData&)get(boost::edge_bundle, g, *edges(g).first)); + boost::ignore_unused_variable_warning( + (const EdgeData&)get(boost::edge_bundle, (const CSRGraphT&)g, *edges(g).first)); + put(boost::edge_bundle, g, *edges(g).first, EdgeData()); + CSRGraphT g2(boost::edges_are_unsorted_multi_pass, unsorted_edges, unsorted_edges + sizeof(unsorted_edges) / sizeof(*unsorted_edges), 6); graph_test(g); graph_test(g2); @@ -439,7 +466,7 @@ int test_main(int argc, char* argv[]) // Test building a graph using add_edges on unsorted lists CSRGraphT g3(boost::edges_are_unsorted, unsorted_edges, unsorted_edges, 6); // Empty range add_edges(unsorted_edges, unsorted_edges + 3, g3); - boost::no_property edge_data[3]; + EdgeData edge_data[3]; add_edges(unsorted_edges + 3, unsorted_edges + 6, edge_data, edge_data + 3, g3); graph_test(g3); assert_graphs_equal(g, boost::identity_property_map(), diff --git a/test/graphviz_test.cpp b/test/graphviz_test.cpp index d78b637b..64c04ae9 100644 --- a/test/graphviz_test.cpp +++ b/test/graphviz_test.cpp @@ -194,7 +194,7 @@ int test_main(int, char*[]) { gs_t gs("graph { a nodE [mass = 7.7] c e [mass = 6.66] }"); try { test_graph(gs,3,masses,weight_map_t()); - BOOST_ERROR("Failed to throw boost::directed_graph_error."); + BOOST_ERROR("Failed to throw boost::undirected_graph_error."); } catch (boost::undirected_graph_error&) {} } diff --git a/test/metric_tsp_approx.cpp b/test/metric_tsp_approx.cpp index 14e52794..e813bd33 100644 --- a/test/metric_tsp_approx.cpp +++ b/test/metric_tsp_approx.cpp @@ -92,8 +92,8 @@ void testScalability(unsigned numpts) typedef vector< Vertex > Container; mt19937 rng(time(0)); - uniform_int<> range(0.01, (numpts * 2)); - variate_generator > + uniform_real<> range(0.01, (numpts * 2)); + variate_generator > pnt_gen(rng, range); PointSet points;