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;