diff --git a/build/Jamfile.v2 b/build/Jamfile.v2 index 19cb65f1..6bf7f5bd 100644 --- a/build/Jamfile.v2 +++ b/build/Jamfile.v2 @@ -21,6 +21,7 @@ lib boost_graph # Without these flags, MSVC 7.1 and 8.0 crash # User reports that VC++ 8.0 does not fail anymore, so that is removed msvc-7.1:-GR- + sun:no : : ; diff --git a/doc/DFSVisitor.html b/doc/DFSVisitor.html index f81f616f..a018257b 100644 --- a/doc/DFSVisitor.html +++ b/doc/DFSVisitor.html @@ -150,6 +150,15 @@ undirected graph this method is never called. +Finish Edge +vis.finish_edge(e, g) +void + +This is invoked on each non-tree edge as well as on each tree edge after +finish_vertex has been called on its target vertex. + + + Finish Vertex vis.finish_vertex(u, g) void diff --git a/doc/cycle_canceling.html b/doc/cycle_canceling.html new file mode 100644 index 00000000..63cecf05 --- /dev/null +++ b/doc/cycle_canceling.html @@ -0,0 +1,223 @@ + + + +Boost Graph Library: Cycle Canceling for Min Cost Max Flow + +C++ Boost + +
+ +

+cycle_canceling +

+ +
+// named parameter version
+template <class Graph, class P, class T, class R>
+void cycle_canceling(
+        Graph &g, 
+        const bgl_named_params<P, T, R> & params  = all defaults)
+
+// non-named parameter version
+template <class Graph, class Pred, class Distance, class Reversed, class ResidualCapacity, class Weight>
+void cycle_canceling(const Graph & g, Weight weight, Reversed rev, ResidualCapacity residual_capacity, Pred pred, Distance distance) 
+
+ +

+The cycle_canceling() function calculates the minimum cost flow of a network with given flow. See Section Network +Flow Algorithms for a description of maximum flow. +For given flow values f(u,v) function minimizes flow cost in such a way, that for each v in V the + sum u in V f(v,u) is preserved. Particularly if the input flow was the maximum flow, the function produces min cost max flow. + + + The function calculates the flow values f(u,v) for all (u,v) in +E, which are returned in the form of the residual capacity +r(u,v) = c(u,v) - f(u,v). + +

+There are several special requirements on the input graph and property +map parameters for this algorithm. First, the directed graph +G=(V,E) that represents the network must be augmented to +include the reverse edge for every edge in E. That is, the +input graph should be Gin = (V,{E U +ET}). The ReverseEdgeMap argument rev +must map each edge in the original graph to its reverse edge, that is +(u,v) -> (v,u) for all (u,v) in E. +The WeightMap has to map each edge from ET to -weight of its reversed edge. +Note that edges from E can have negative weights. +

+If weights in the graph are nonnegative, the +successive_shortest_path_nonnegative_weights() +might be better choice for min cost max flow. + +

+The algorithm is described in Network Flows. + +

+In each round algorithm augments the negative cycle (in terms of weight) in the residual graph. +If there is no negative cycle in the network, the cost is optimized. + +

+Note that, although we mention capacity in the problem description, the actual algorithm doesn't have to now it. + +

+In order to find the cost of the result flow use: +find_flow_cost(). + + +

Where Defined

+ +

+boost/graph/successive_shortest_path_nonnegative_weights.hpp + +

+ +

Parameters

+ +IN: Graph& g +
+ A directed graph. The + graph's type must be a model of VertexListGraph and IncidenceGraph For each edge + (u,v) in the graph, the reverse edge (v,u) must also + be in the graph. +
+ +

Named Parameters

+ + +IN/OUT: residual_capacity_map(ResidualCapacityEdgeMap res) +
+ This maps edges to their residual capacity. The type must be a model + of a mutable Lvalue Property + Map. The key type of the map must be the graph's edge descriptor + type.
+ Default: get(edge_residual_capacity, g) +
+ +IN: reverse_edge_map(ReverseEdgeMap rev) +
+ An edge property map that maps every edge (u,v) in the graph + to the reverse edge (v,u). The map must be a model of + constant Lvalue + Property Map. The key type of the map must be the graph's edge + descriptor type.
+ Default: get(edge_reverse, g) +
+ +IN: weight_map(WeightMap w) +
+ The weight (also know as ``length'' or ``cost'') of each edge in the + graph. The WeightMap type must be a model of Readable Property + Map. The key type for this property map must be the edge + descriptor of the graph. The value type for the weight map must be + Addable with the distance map's value type.
+ Default: get(edge_weight, g)
+
+ +UTIL: predecessor_map(PredEdgeMap pred) +
+ Use by the algorithm to store augmenting paths. The map must be a + model of mutable Lvalue Property Map. + The key type must be the graph's vertex descriptor type and the + value type must be the graph's edge descriptor type.
+ + Default: an + iterator_property_map created from a std::vector + of edge descriptors of size num_vertices(g) and + using the i_map for the index map. +
+ +UTIL: distance_map(DistanceMap d_map) +
+ The shortest path weight from the source vertex s to each + vertex in the graph g is recorded in this property map. The + shortest path weight is the sum of the edge weights along the + shortest path. The type DistanceMap must be a model of Read/Write + Property Map. The vertex descriptor type of the graph needs to + be usable as the key type of the distance map. + + Default: + iterator_property_map created from a + std::vector of the WeightMap's value type of size + num_vertices(g) and using the i_map for the index + map.
+ +
+ +IN: vertex_index_map(VertexIndexMap i_map) +
+ Maps each vertex of the graph to a unique integer in the range + [0, num_vertices(g)). This property map is only needed + if the default for the distance or predecessor map is used. + The vertex index map must be a model of Readable Property + Map. The key type of the map must be the graph's vertex + descriptor type.
+ Default: get(vertex_index, g) + Note: if you use this default, make sure your graph has + an internal vertex_index property. For example, + adjacenty_list with VertexList=listS does + not have an internal vertex_index property. +
+ +

Complexity

+In the integer capacity and weight case, if C is the initial cost of the flow, then the complexity is O(C * |V| * |E|), +where O(|E|* |V|) is the complexity of the bellman ford shortest paths algorithm and C is upper bound on number of iteration. +In many real world cases number of iterations is much smaller than C. + + +

Example

+ +The program in example/cycle_canceling_example.cpp. + + +

See Also

+ +successive_shortest_path_nonnegative_weights()
+find_flow_cost(). + +
+
+ + +
Copyright © 2013 +Piotr Wygocki, University of Warsaw (wygos at mimuw.edu.pl) +
+ + + + + + + + + + + + diff --git a/doc/depth_first_search.html b/doc/depth_first_search.html index e217972a..b0057f7d 100644 --- a/doc/depth_first_search.html +++ b/doc/depth_first_search.html @@ -107,6 +107,7 @@ DFS-VISIT(G, u) ... else if (color[v] = BLACK) ... + ... end for color[u] := BLACK f_time[u] := time := time + 1 @@ -140,6 +141,8 @@ examine edge (u,v) - (u,v) is a cross or forward edge - +finish edge (u,v) +- finish vertex u - @@ -266,6 +269,9 @@ The time complexity is O(E + V).
  • vis.forward_or_cross_edge(e, g) is invoked on forward or cross edges in the graph. In an undirected graph this method is never called. + +
  • vis.finish_edge(e, g) is invoked on the non-tree edges in + the graph as well as on each tree edge after its target vertex is finished.
  • vis.finish_vertex(u, g) is invoked on a vertex after all of its out edges have been added to the search tree and all of diff --git a/doc/dijkstra_shortest_paths_no_color_map.html b/doc/dijkstra_shortest_paths_no_color_map.html index b65d333f..c7202b68 100644 --- a/doc/dijkstra_shortest_paths_no_color_map.html +++ b/doc/dijkstra_shortest_paths_no_color_map.html @@ -124,11 +124,12 @@ DIJKSTRA(G, s, w) if (w(u,v) + d[u] < d[v]) d[v] := w(u,v) + d[u] p[v] := u - DECREASE-KEY(Q, v) + if (d[v] was originally infinity) + INSERT(Q, v) + else + DECREASE-KEY(Q, v) else ... - if (d[v] was originally infinity) - INSERT(Q, v) end for end while return (d, p) @@ -146,10 +147,11 @@ examine edge (u,v) edge (u,v) relaxed +discover vertex v + edge (u,v) not relaxed -discover vertex v finish vertex u diff --git a/doc/edge_coloring.html b/doc/edge_coloring.html new file mode 100644 index 00000000..7febb469 --- /dev/null +++ b/doc/edge_coloring.html @@ -0,0 +1,98 @@ + + + + + +Boost Graph Library: Edge Coloring + +C++ Boost + +
    + +

    + +edge_coloring +

    + + +

    +

    + + + + + + + + + + +
    Graphs:undirected, loop-free
    Properties:color
    Complexity:time: O(|E| |V|)
    +
    + + +
    +  template <class Graph, class ColorMap>
    +  typename boost::property_traits::value_type
    +  edge_coloring(const Graph &g, ColorMap color);
    +
    + +

    Computes an edge coloring for the vertices in the graph, using +an algorithm proposed by Mista et al. []. Given edges ordered +e1, e2, ..., en it assignes a +colors c1, c2, ..., cn in a way +that no vertex connects with 2 edges of the same color. Furthermore +at most m + 1 colors are used. + + + +

    Where defined

    +boost/graph/edge_coloring.hpp + +

    Parameters

    + +IN: const Graph& g +
    + The graph object on which the algorithm will be applied. The type + Graph must be a model of + Edge List Graph and Incidence + Graph. +
    + +OUT: ColorMap color +
    + This property map records the colors of each edges. It must be a + model of + Read/Write Property Map whose key type is the same as the edge + descriptor type of the graph and whose value type is an integral type + that can store all values smaller or equal to m. +
    + + +

    Example

    + +See example/king_ordering.cpp. + +

    See Also

    + +sequential vertex ordering. + +
    +
    + + +
    Copyright © 2013 +Maciej Piechotka (uzytkownik2@gmail.com) +
    + + + diff --git a/doc/find_flow_cost.html b/doc/find_flow_cost.html new file mode 100644 index 00000000..7f839cf9 --- /dev/null +++ b/doc/find_flow_cost.html @@ -0,0 +1,139 @@ + + + +Boost Graph Library: Find Flow Cost + +C++ Boost + +
    + +

    +find_flow_cost +

    + +
    +// named parameter version
    +template <class Graph>
    +typename property_traits<typename property_map < Graph, edge_capacity_t >::type>::value_type
    +find_flow_cost(const Graph & g,
    +        const bgl_named_params<P, T, R> & params  = all defaults)
    +
    +// non-named parameter version
    +template<class Graph, class Capacity, class ResidualCapacity, class Weight>
    +typename property_traits<typename property_map < Graph, edge_capacity_t >::type>::value_type
    +find_flow_cost(const Graph & g, Capacity capacity, ResidualCapacity residual_capacity, Weight weight) 
    +
    + +

    +The find_flow_cost() function calculates the minimum cost maximum flow value of a network and given flow. See Section Network +Flow Algorithms for a description of maximum flow. +The function calculates the cost from the flow values f(u,v) for (u,v) in +E, which are passed in the form of the residual capacity +r(u,v) = c(u,v) - f(u,v). + +

    +In order to compute the min cost max flow use : +successive_shortest_path_nonnegative_weights() or +cycle_canceling(). + +

    Where Defined

    + +

    +boost/graph/successive_shortest_path_nonnegative_weights.hpp + +

    + +

    Parameters

    + +IN: const Graph& g +
    + A directed graph. The + graph's type must be a model of VertexListGraph and IncidenceGraph For each edge + (u,v) in the graph, the reverse edge (v,u) must also + be in the graph. +
    +

    Named Parameters

    + + +IN: capacity_map(CapacityEdgeMap cap) +
    + The edge capacity property map. The type must be a model of a + constant Lvalue Property Map. The + key type of the map must be the graph's edge descriptor type.
    + Default: get(edge_capacity, g) +
    + +IN: residual_capacity_map(ResidualCapacityEdgeMap res) +
    + This maps edges to their residual capacity. The type must be a model + of a mutable Lvalue Property + Map. The key type of the map must be the graph's edge descriptor + type.
    + Default: get(edge_residual_capacity, g) +
    + + +IN: weight_map(WeightMap w_map) +
    + The weight or ``cost'' of each edge in the graph. + The type WeightMap must be a model of + Readable Property Map. The edge descriptor type of + the graph needs to be usable as the key type for the weight + map. The value type for this map must be + the same as the value type of the distance map.
    + Default: get(edge_weight, g)
    + +
    + +

    Complexity

    +The complexity is O(|E|), + +

    Example

    + +The function is used in the successive_shortest_path_nonnegative_weights example. The program in example/successive_shortest_path_nonnegative_weights_example.cpp. + +

    See Also

    + +cycle_canceling()
    +successive_shortest_path_nonnegative_weights(). + +
    +
    + + +
    Copyright © 2013 +Piotr Wygocki, University of Warsaw (wygos at mimuw.edu.pl) +
    + + + + + + + + + + + + diff --git a/doc/graph_theory_review.html b/doc/graph_theory_review.html index e811d297..33a6d2cd 100644 --- a/doc/graph_theory_review.html +++ b/doc/graph_theory_review.html @@ -552,6 +552,9 @@ f(u,v). The edges with r(u,v) > 0 are residual edges The maximum flow problem is to determine the maximum possible value for |f| and the corresponding flow values for every vertex pair in the graph. +

    +The minimum cost maximum flow problem is to determine the maximum flow which minimizes sum(u,v) in E +cost(u,v) * f(u,v) .

    A flow network is shown in Figure diff --git a/doc/hawick_circuits.html b/doc/hawick_circuits.html new file mode 100644 index 00000000..5fabcf7c --- /dev/null +++ b/doc/hawick_circuits.html @@ -0,0 +1,58 @@ +

    + +

    C++ Boost

    + +

    hawick_circuits

    + +
    template <typename Graph, typename Visitor, typename VertexIndexMap>
    +void hawick_circuits(Graph const& graph, Visitor visitor, VertexIndexMap const& vim = get(vertex_index, graph));
    +
    +template <typename Graph, typename Visitor, typename VertexIndexMap>
    +void hawick_unique_circuits(Graph const& graph, Visitor visitor, VertexIndexMap const& vim = get(vertex_index, graph));
    +
    + +

    Enumerate all the elementary circuits in a directed multigraph. Specifically, +self-loops and redundant circuits caused by parallel edges are enumerated too. +hawick_unique_circuits may be used if redundant circuits caused by parallel +edges are not desired.

    + +

    The algorithm is described in detail in +http://www.massey.ac.nz/~kahawick/cstn/013/cstn-013.pdf.

    + +

    Where defined

    + +

    #include <boost/graph/hawick_circuits.hpp>

    + +

    Parameters

    + +

    IN: Graph const& graph

    + +
    +

    The graph on which the algorithm is to be performed. It must be a model of + the VertexListGraph and AdjacencyGraph concepts.

    +
    + +

    IN: Visitor visitor

    + +
    +

    The visitor that will be notified on each circuit found by the algorithm. + The visitor.cycle(circuit, graph) expression must be valid, with circuit + being a const-reference to a random access sequence of vertex_descriptors.

    + +

    For example, if a circuit u -> v -> w -> u exists in the graph, the + visitor will be called with a sequence consisting of (u, v, w).

    +
    + +

    IN: VertexIndexMap const& vim = get(vertex_index, graph)

    + +
    +

    A model of the ReadablePropertyMap concept mapping each vertex_descriptor + to an integer in the range [0, num_vertices(graph)). It defaults to using + the vertex index map provided by the graph.

    +
    + +
    + + diff --git a/doc/hawick_circuits.md b/doc/hawick_circuits.md new file mode 100644 index 00000000..828a71b9 --- /dev/null +++ b/doc/hawick_circuits.md @@ -0,0 +1,53 @@ + + +![C++ Boost](../../../boost.png) + +# `hawick_circuits` + + template + void hawick_circuits(Graph const& graph, Visitor visitor, VertexIndexMap const& vim = get(vertex_index, graph)); + + template + void hawick_unique_circuits(Graph const& graph, Visitor visitor, VertexIndexMap const& vim = get(vertex_index, graph)); + +Enumerate all the elementary circuits in a directed multigraph. Specifically, +self-loops and redundant circuits caused by parallel edges are enumerated too. +`hawick_unique_circuits` may be used if redundant circuits caused by parallel +edges are not desired. + +The algorithm is described in detail in +. + + +### Where defined + +[`#include `](../../../boost/graph/hawick_circuits.hpp) + + +### Parameters + +__IN:__ `Graph const& graph` + +> The graph on which the algorithm is to be performed. It must be a model of +> the `VertexListGraph` and `AdjacencyGraph` concepts. + +__IN:__ `Visitor visitor` + +> The visitor that will be notified on each circuit found by the algorithm. +> The `visitor.cycle(circuit, graph)` expression must be valid, with `circuit` +> being a `const`-reference to a random access sequence of `vertex_descriptor`s. +> +> For example, if a circuit `u -> v -> w -> u` exists in the graph, the +> visitor will be called with a sequence consisting of `(u, v, w)`. + +__IN:__ `VertexIndexMap const& vim = get(vertex_index, graph)` + +> A model of the `ReadablePropertyMap` concept mapping each `vertex_descriptor` +> to an integer in the range `[0, num_vertices(graph))`. It defaults to using +> the vertex index map provided by the `graph`. + + +------------------------------------------------------------------------------ + diff --git a/doc/successive_shortest_path_nonnegative_weights.html b/doc/successive_shortest_path_nonnegative_weights.html new file mode 100644 index 00000000..d6d53be2 --- /dev/null +++ b/doc/successive_shortest_path_nonnegative_weights.html @@ -0,0 +1,264 @@ + + + +Boost Graph Library: Successive Shortest Path for Min Cost Max Flow + +C++ Boost + +
    + +

    +successive_shortest_path_nonnegative_weights +

    + +
    +// named parameter version
    +template <class Graph, class P, class T, class R>
    +void successive_shortest_path_nonnegative_weights(
    +        Graph &g, 
    +        typename graph_traits<Graph>::vertex_descriptor s, 
    +        typename graph_traits<Graph>::vertex_descriptor t,
    +        const bgl_named_params<P, T, R> & params  = all defaults)
    +
    +// non-named parameter version
    +template <class Graph, class Capacity, class ResidualCapacity, class Reversed, class Pred, class Weight, class Distance, class Distance2, class VertexIndex>
    +void successive_shortest_path_nonnegative_weights(
    +        const Graph & g, 
    +        typename graph_traits<Graph>::vertex_descriptor s, 
    +        typename graph_traits<Graph>::vertex_descriptor t,
    +        Capacity capacity,
    +        ResidualCapacity residual_capacity,
    +        Weight weight, 
    +        Reversed rev,
    +        VertexIndex index,
    +        Pred pred, 
    +        Distance distance,
    +        Distance2 distance_prev) 
    +
    + +

    +The successive_shortest_path_nonnegative_weights() function calculates the minimum cost maximum flow of a network. See Section Network +Flow Algorithms for a description of maximum flow. + The function calculates the flow values f(u,v) for all (u,v) in +E, which are returned in the form of the residual capacity +r(u,v) = c(u,v) - f(u,v). + +

    +There are several special requirements on the input graph and property +map parameters for this algorithm. First, the directed graph +G=(V,E) that represents the network must be augmented to +include the reverse edge for every edge in E. That is, the +input graph should be Gin = (V,{E U +ET}). The ReverseEdgeMap argument rev +must map each edge in the original graph to its reverse edge, that is +(u,v) -> (v,u) for all (u,v) in E. The +CapacityEdgeMap argument cap must map each edge in +E to a positive number, and each edge in ET +to 0. The WeightMap has to map each edge from E to nonnegative number, and each edge from ET to -weight of its reversed edge. + +

    +The algorithm is described in Network Flows. + +

    +This algorithm starts with empty flow and in each round augments the shortest path (in terms of weight) in the residual graph. + +

    +In order to find the cost of the result flow use: +find_flow_cost(). + +

    Where Defined

    + +

    +boost/graph/successive_shortest_path_nonnegative_weights.hpp + +

    + +

    Parameters

    + +IN: Graph& g +
    + A directed graph. The + graph's type must be a model of VertexListGraph and IncidenceGraph For each edge + (u,v) in the graph, the reverse edge (v,u) must also + be in the graph. +
    + +IN: vertex_descriptor s +
    + The source vertex for the flow network graph. +
    + +IN: vertex_descriptor t +
    + The sink vertex for the flow network graph. +
    + +

    Named Parameters

    + + +IN: capacity_map(CapacityEdgeMap cap) +
    + The edge capacity property map. The type must be a model of a + constant Lvalue Property Map. The + key type of the map must be the graph's edge descriptor type.
    + Default: get(edge_capacity, g) +
    + +OUT: residual_capacity_map(ResidualCapacityEdgeMap res) +
    + This maps edges to their residual capacity. The type must be a model + of a mutable Lvalue Property + Map. The key type of the map must be the graph's edge descriptor + type.
    + Default: get(edge_residual_capacity, g) +
    + +IN: reverse_edge_map(ReverseEdgeMap rev) +
    + An edge property map that maps every edge (u,v) in the graph + to the reverse edge (v,u). The map must be a model of + constant Lvalue + Property Map. The key type of the map must be the graph's edge + descriptor type.
    + Default: get(edge_reverse, g) +
    + +IN: weight_map(WeightMap w_map) +
    + The weight or ``cost'' of each edge in the graph. The weights + must all be non-negative, and the algorithm will throw a + negative_edge + exception if one of the edges is negative. + The type WeightMap must be a model of + Readable Property Map. The edge descriptor type of + the graph needs to be usable as the key type for the weight + map. The value type for this map must be + the same as the value type of the distance map.
    + Default: get(edge_weight, g)
    + +
    + +UTIL: predecessor_map(PredEdgeMap pred) +
    + Use by the algorithm to store augmenting paths. The map must be a + model of mutable Lvalue Property Map. + The key type must be the graph's vertex descriptor type and the + value type must be the graph's edge descriptor type.
    + + Default: an + iterator_property_map created from a std::vector + of edge descriptors of size num_vertices(g) and + using the i_map for the index map. +
    + +UTIL: distance_map(DistanceMap d_map) +
    + The shortest path weight from the source vertex s to each + vertex in the graph g is recorded in this property map. The + shortest path weight is the sum of the edge weights along the + shortest path. The type DistanceMap must be a model of Read/Write + Property Map. The vertex descriptor type of the graph needs to + be usable as the key type of the distance map. + + Default: + iterator_property_map created from a + std::vector of the WeightMap's value type of size + num_vertices(g) and using the i_map for the index + map.
    + +
    + +UTIL: distance_map2(DistanceMap2 d_map2) +
    + The shortest path computation in iteration nr k uses distances computed in iteration k. + The type DistanceMap2 must be a model of Read/Write + Property Map. The vertex descriptor type of the graph needs to + be usable as the key type of the distance map. + + Default: + iterator_property_map created from a + std::vector of the WeightMap's value type of size + num_vertices(g) and using the i_map for the index + map.
    + +
    + +IN: vertex_index_map(VertexIndexMap i_map) +
    + Maps each vertex of the graph to a unique integer in the range + [0, num_vertices(g)). This property map is only needed + if the default for the distance or distance2 or predecessor map is used. + The vertex index map must be a model of Readable Property + Map. The key type of the map must be the graph's vertex + descriptor type.
    + Default: get(vertex_index, g) + Note: if you use this default, make sure your graph has + an internal vertex_index property. For example, + adjacenty_list with VertexList=listS does + not have an internal vertex_index property. +
    + + +

    Complexity

    +In the integer capacity case, if U is the value of the max flow, then the complexity is O(U * (|E| + |V|*log|V|)), +where O(|E| + |V|*log|V|) is the complexity of the dijkstra algorithm and U is upper bound on number of iteration. +In many real world cases number of iterations is much smaller than U. + + +

    Example

    + +The program in example/successive_shortest_path_nonnegative_weights_example.cpp. + +

    See Also

    + +cycle_canceling()
    +find_flow_cost(). + +
    +
    + + +
    Copyright © 2013 +Piotr Wygocki, University of Warsaw (wygos at mimuw.edu.pl) +
    + + + + + + + + + + + + diff --git a/doc/table_of_contents.html b/doc/table_of_contents.html index 0fd36e8e..9e0e9ec7 100644 --- a/doc/table_of_contents.html +++ b/doc/table_of_contents.html @@ -214,6 +214,12 @@
  • boykov_kolmogorov_max_flow
  • edmonds_maximum_cardinality_matching +
  • Minimum Cost Maximum Flow Algorithms +
      +
    1. cycle_canceling +
    2. successive_shortest_path_nonnegative_weights +
    3. find_flow_cost
    4. +
  • Minimum Cut Algorithms
    1. stoer_wagner_min_cut @@ -284,10 +290,12 @@
    2. Miscellaneous Algorithms
      1. metric_tsp_approx
      2. -
      3. sequential_vertex_coloring -
      4. is_bipartite (including two-coloring of bipartite graphs) -
      5. find_odd_cycle -
      6. maximum_adjacency_search +
      7. sequential_vertex_coloring
      8. +
      9. edge_coloring
      10. +
      11. is_bipartite (including two-coloring of bipartite graphs)
      12. +
      13. find_odd_cycle
      14. +
      15. maximum_adjacency_search
      16. +
      17. hawick_circuits (find all circuits of a directed graph)
    3. diff --git a/doc/undirected_dfs.html b/doc/undirected_dfs.html index ffbefa28..78def89b 100644 --- a/doc/undirected_dfs.html +++ b/doc/undirected_dfs.html @@ -7,7 +7,7 @@ http://www.boost.org/LICENSE_1_0.txt) --> -Boost Graph Library: Depth-First Search +Boost Graph Library: Undirected Depth-First Search G, u) call DFS-VISIT(G, v) else if (vcolor[v] = GRAY and ec = WHITE) ... + ... end for vcolor[u] := BLACK f_time[u] := time := time + 1 @@ -152,6 +153,8 @@ examine edge (u,v) (u,v) is a back edge - - +finish edge (u,v) +- finish vertex u - @@ -291,6 +294,9 @@ The time complexity is O(E + V).
    4. vis.back_edge(e, g) is invoked on the back edges in the graph. +
    5. vis.finish_edge(e, g) is invoked on the back edges in + the graph as well as on each tree edge after its target vertex is finished. +
    6. vis.finish_vertex(u, g) is invoked on a vertex after all of its out edges have been added to the search tree and all of the adjacent vertices have been discovered (but before their diff --git a/example/Jamfile.v2 b/example/Jamfile.v2 index ce155c67..13cdf75f 100644 --- a/example/Jamfile.v2 +++ b/example/Jamfile.v2 @@ -50,4 +50,8 @@ exe subgraph_properties : subgraph_properties.cpp ; exe vf2_sub_graph_iso_example : vf2_sub_graph_iso_example.cpp ; exe vf2_sub_graph_iso_multi_example : vf2_sub_graph_iso_multi_example.cpp ; exe sloan_ordering : sloan_ordering.cpp ; +exe hawick_circuits : hawick_circuits.cpp ; +exe edge_coloring : edge_coloring.cpp ; +exe successive_shortest_path_nonnegative_weights_example : successive_shortest_path_nonnegative_weights_example.cpp ; +exe cycle_canceling_example : cycle_canceling_example.cpp ; diff --git a/example/astar-cities.cpp b/example/astar-cities.cpp index c18cd41e..48b3260f 100644 --- a/example/astar-cities.cpp +++ b/example/astar-cities.cpp @@ -118,7 +118,6 @@ int main(int argc, char **argv) typedef property_map::type WeightMap; typedef mygraph_t::vertex_descriptor vertex; typedef mygraph_t::edge_descriptor edge_descriptor; - typedef mygraph_t::vertex_iterator vertex_iterator; typedef std::pair edge; // specify data @@ -196,7 +195,8 @@ int main(int argc, char **argv) (g, start, distance_heuristic (locations, goal), - predecessor_map(&p[0]).distance_map(&d[0]). + predecessor_map(make_iterator_property_map(p.begin(), get(vertex_index, g))). + distance_map(make_iterator_property_map(d.begin(), get(vertex_index, g))). visitor(astar_goal_visitor(goal))); diff --git a/example/bfs-example.cpp b/example/bfs-example.cpp index 0f340ccf..0436204c 100644 --- a/example/bfs-example.cpp +++ b/example/bfs-example.cpp @@ -54,15 +54,18 @@ main() #endif // Typedefs - typedef graph_traits < graph_t >::vertex_descriptor Vertex; typedef graph_traits < graph_t >::vertices_size_type Size; - typedef Size* Iiter; // a vector to hold the discover time property for each vertex std::vector < Size > dtime(num_vertices(g)); + typedef + iterator_property_map::iterator, + property_map::const_type> + dtime_pm_type; + dtime_pm_type dtime_pm(dtime.begin(), get(vertex_index, g)); Size time = 0; - bfs_time_visitor < Size * >vis(&dtime[0], time); + bfs_time_visitor < dtime_pm_type >vis(dtime_pm, time); breadth_first_search(g, vertex(s, g), visitor(vis)); // Use std::sort to order the vertices by their discover time @@ -70,7 +73,7 @@ main() integer_range < int >range(0, N); std::copy(range.begin(), range.end(), discover_order.begin()); std::sort(discover_order.begin(), discover_order.end(), - indirect_cmp < Iiter, std::less < Size > >(&dtime[0])); + indirect_cmp < dtime_pm_type, std::less < Size > >(dtime_pm)); std::cout << "order of discovery: "; for (int i = 0; i < N; ++i) diff --git a/example/bfs-example2.cpp b/example/bfs-example2.cpp index d7cb2dd2..bc5d92ab 100644 --- a/example/bfs-example2.cpp +++ b/example/bfs-example2.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include @@ -30,6 +31,7 @@ public: struct VertexProps { boost::default_color_type color; std::size_t discover_time; + unsigned int index; }; int @@ -63,9 +65,7 @@ main() #endif // Typedefs - typedef graph_traits::vertex_descriptor Vertex; typedef graph_traits::vertices_size_type Size; - typedef Size* Iiter; Size time = 0; typedef property_map::type dtime_map_t; @@ -76,17 +76,28 @@ main() // a vector to hold the discover time property for each vertex std::vector < Size > dtime(num_vertices(g)); + typedef + iterator_property_map::iterator, + property_map::type> + dtime_pm_type; graph_traits::vertex_iterator vi, vi_end; std::size_t c = 0; - for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi, ++c) + for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi, ++c) { dtime[c] = dtime_map[*vi]; + put(&VertexProps::index, g, *vi, c); + } + dtime_pm_type dtime_pm(dtime.begin(), get(&VertexProps::index, g)); // Use std::sort to order the vertices by their discover time std::vector::vertices_size_type > discover_order(N); integer_range < int >range(0, N); std::copy(range.begin(), range.end(), discover_order.begin()); std::sort(discover_order.begin(), discover_order.end(), - indirect_cmp < Iiter, std::less < Size > >(&dtime[0])); + make_indirect_cmp( + std::less(), + make_iterator_property_map( + dtime.begin(), + typed_identity_property_map()))); std::cout << "order of discovery: "; for (int i = 0; i < N; ++i) diff --git a/example/canonical_ordering.cpp b/example/canonical_ordering.cpp index 129af6ac..94798425 100644 --- a/example/canonical_ordering.cpp +++ b/example/canonical_ordering.cpp @@ -64,7 +64,8 @@ int main(int argc, char** argv) std::vector embedding(num_vertices(g)); if (boyer_myrvold_planarity_test(boyer_myrvold_params::graph = g, boyer_myrvold_params::embedding = - &embedding[0] + make_iterator_property_map( + embedding.begin(), get(vertex_index, g)) ) ) std::cout << "Input graph is planar" << std::endl; @@ -75,7 +76,10 @@ int main(int argc, char** argv) ordering_storage_t; ordering_storage_t ordering; - planar_canonical_ordering(g, &embedding[0], std::back_inserter(ordering)); + planar_canonical_ordering(g, + make_iterator_property_map( + embedding.begin(), get(vertex_index, g)), + std::back_inserter(ordering)); ordering_storage_t::iterator oi, oi_end; oi_end = ordering.end(); diff --git a/example/cycle_canceling_example.cpp b/example/cycle_canceling_example.cpp new file mode 100644 index 00000000..46e85f14 --- /dev/null +++ b/example/cycle_canceling_example.cpp @@ -0,0 +1,28 @@ +//======================================================================= +// Copyright 2013 University of Warsaw. +// Authors: Piotr Wygocki +// +// 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 "../test/min_cost_max_flow_utils.hpp" + + +int main() { + boost::SampleGraph::vertex_descriptor s,t; + boost::SampleGraph::Graph g; + boost::SampleGraph::getSampleGraph(g, s, t); + + boost::edmonds_karp_max_flow(g, s, t); + boost::cycle_canceling(g); + + int cost = boost::find_flow_cost(g); + assert(cost == 29); + return 0; +} + diff --git a/example/dfs-example.cpp b/example/dfs-example.cpp index efb2b57e..0117b81d 100644 --- a/example/dfs-example.cpp +++ b/example/dfs-example.cpp @@ -58,15 +58,17 @@ main() graph_t g(edge_array, edge_array + sizeof(edge_array) / sizeof(E), N); #endif - // Typedefs - typedef boost::graph_traits < graph_t >::vertex_descriptor Vertex; - typedef size_type* Iiter; - // discover time and finish time properties std::vector < size_type > dtime(num_vertices(g)); std::vector < size_type > ftime(num_vertices(g)); + typedef + iterator_property_map::iterator, + property_map::const_type> + time_pm_type; + time_pm_type dtime_pm(dtime.begin(), get(vertex_index, g)); + time_pm_type ftime_pm(ftime.begin(), get(vertex_index, g)); size_type t = 0; - dfs_time_visitor < size_type * >vis(&dtime[0], &ftime[0], t); + dfs_time_visitor < time_pm_type >vis(dtime_pm, ftime_pm, t); depth_first_search(g, visitor(vis)); @@ -75,7 +77,7 @@ main() integer_range < size_type > r(0, N); std::copy(r.begin(), r.end(), discover_order.begin()); std::sort(discover_order.begin(), discover_order.end(), - indirect_cmp < Iiter, std::less < size_type > >(&dtime[0])); + indirect_cmp < time_pm_type, std::less < size_type > >(dtime_pm)); std::cout << "order of discovery: "; int i; for (i = 0; i < N; ++i) @@ -84,7 +86,7 @@ main() std::vector < size_type > finish_order(N); std::copy(r.begin(), r.end(), finish_order.begin()); std::sort(finish_order.begin(), finish_order.end(), - indirect_cmp < Iiter, std::less < size_type > >(&ftime[0])); + indirect_cmp < time_pm_type, std::less < size_type > >(ftime_pm)); std::cout << std::endl << "order of finish: "; for (i = 0; i < N; ++i) std::cout << name[finish_order[i]] << " "; diff --git a/example/dfs.cpp b/example/dfs.cpp index 9dd13da8..e68ba39a 100644 --- a/example/dfs.cpp +++ b/example/dfs.cpp @@ -27,12 +27,18 @@ Tree edge: 0 --> 2 Tree edge: 2 --> 1 Back edge: 1 --> 1 + Finish edge: 1 --> 1 Tree edge: 1 --> 3 Back edge: 3 --> 1 + Finish edge: 3 --> 1 Tree edge: 3 --> 4 Back edge: 4 --> 0 + Finish edge: 4 --> 0 Back edge: 4 --> 1 + Finish edge: 4 --> 1 Forward or cross edge: 2 --> 3 + Finish edge: 2 --> 3 + Finish edge: 0 --> 2 1 10 3 8 2 9 @@ -69,6 +75,12 @@ struct edge_categorizer : public dfs_visitor { << " --> " << target(e, G) << endl; Base::forward_or_cross_edge(e, G); } + template + void finish_edge(Edge e, Graph& G) { + cout << "Finish edge: " << source(e, G) << + " --> " << target(e, G) << endl; + Base::finish_edge(e, G); + } }; template edge_categorizer diff --git a/example/dfs.expected b/example/dfs.expected index 84aa0c45..b0da6de4 100644 --- a/example/dfs.expected +++ b/example/dfs.expected @@ -1,12 +1,18 @@ Tree edge: 0 --> 2 Tree edge: 2 --> 1 Back edge: 1 --> 1 +Finish edge: 1 --> 1 Tree edge: 1 --> 3 Back edge: 3 --> 1 +Finish edge: 3 --> 1 Tree edge: 3 --> 4 Back edge: 4 --> 0 +Finish edge: 4 --> 0 Back edge: 4 --> 1 +Finish edge: 4 --> 1 Forward or cross edge: 2 --> 3 +Finish edge: 2 --> 3 +Finish edge: 0 --> 2 1 10 3 8 2 9 diff --git a/example/dijkstra-example-listS.cpp b/example/dijkstra-example-listS.cpp index d02e9347..500f9811 100644 --- a/example/dijkstra-example-listS.cpp +++ b/example/dijkstra-example-listS.cpp @@ -26,7 +26,6 @@ main(int, char *[]) property > > >, property > graph_t; - typedef graph_traits::edge_descriptor edge_descriptor; typedef std::pair Edge; const int num_nodes = 5; diff --git a/example/dijkstra-example.cpp b/example/dijkstra-example.cpp index 5f1ef4bd..269d2570 100644 --- a/example/dijkstra-example.cpp +++ b/example/dijkstra-example.cpp @@ -22,7 +22,6 @@ main(int, char *[]) typedef adjacency_list < listS, vecS, directedS, no_property, property < edge_weight_t, int > > graph_t; typedef graph_traits < graph_t >::vertex_descriptor vertex_descriptor; - typedef graph_traits < graph_t >::edge_descriptor edge_descriptor; typedef std::pair Edge; const int num_nodes = 5; diff --git a/example/dijkstra-no-color-map-example.cpp b/example/dijkstra-no-color-map-example.cpp index 9a1a1c3e..14d196d9 100644 --- a/example/dijkstra-no-color-map-example.cpp +++ b/example/dijkstra-no-color-map-example.cpp @@ -26,7 +26,6 @@ main(int, char *[]) typedef adjacency_list < listS, vecS, directedS, no_property, property < edge_weight_t, int > > graph_t; typedef graph_traits < graph_t >::vertex_descriptor vertex_descriptor; - typedef graph_traits < graph_t >::edge_descriptor edge_descriptor; typedef std::pair Edge; const int num_nodes = 5; diff --git a/example/edge_coloring.cpp b/example/edge_coloring.cpp new file mode 100644 index 00000000..81a8a38d --- /dev/null +++ b/example/edge_coloring.cpp @@ -0,0 +1,70 @@ +//======================================================================= +// Copyright 2013 Maciej Piechotka +// Authors: Maciej Piechotka +// +// 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 + +/* + Sample output + Colored using 5 colors + a-d: 4 + a-f: 0 + b-c: 2 + b-e: 3 + b-g: 1 + b-j: 0 + c-d: 0 + c-e: 1 + d-f: 2 + d-i: 1 + e-g: 4 + f-g: 3 + f-h: 1 + g-h: 0 +*/ + +int main(int, char *[]) +{ + using namespace boost; + using namespace std; + typedef adjacency_list Graph; + + typedef std::pair Pair; + Pair edges[14] = { Pair(0,3), //a-d + Pair(0,5), //a-f + Pair(1,2), //b-c + Pair(1,4), //b-e + Pair(1,6), //b-g + Pair(1,9), //b-j + Pair(2,3), //c-d + Pair(2,4), //c-e + Pair(3,5), //d-f + Pair(3,8), //d-i + Pair(4,6), //e-g + Pair(5,6), //f-g + Pair(5,7), //f-h + Pair(6,7) }; //g-h + + Graph G(10); + + for (size_t i = 0; i < sizeof(edges)/sizeof(edges[0]); i++) + add_edge(edges[i].first, edges[i].second, G).first; + + size_t colors = edge_coloring(G, get(edge_bundle, G)); + + cout << "Colored using " << colors << " colors" << endl; + for (size_t i = 0; i < sizeof(edges)/sizeof(edges[0]); i++) { + cout << " " << (char)('a' + edges[i].first) << "-" << (char)('a' + edges[i].second) << ": " << G[edge(edges[i].first, edges[i].second, G).first] << endl; + } + + return 0; +} + diff --git a/example/hawick_circuits.cpp b/example/hawick_circuits.cpp new file mode 100644 index 00000000..b29467b9 --- /dev/null +++ b/example/hawick_circuits.cpp @@ -0,0 +1,96 @@ +// Copyright Louis Dionne 2013 + +// 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) + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +template +struct cycle_printer +{ + cycle_printer(OutputStream& stream) + : os(stream) + { } + + template + void cycle(Path const& p, Graph const& g) + { + if (p.empty()) + return; + + // Get the property map containing the vertex indices + // so we can print them. + typedef typename boost::property_map< + Graph, boost::vertex_index_t + >::const_type IndexMap; + + IndexMap indices = get(boost::vertex_index, g); + + // Iterate over path printing each vertex that forms the cycle. + typename Path::const_iterator i, before_end = boost::prior(p.end()); + for (i = p.begin(); i != before_end; ++i) { + os << get(indices, *i) << " "; + } + os << get(indices, *i) << '\n'; + } + OutputStream& os; +}; + + +// VertexPairIterator is an iterator over pairs of whitespace separated +// vertices `u` and `v` representing a directed edge from `u` to `v`. +template +void build_graph(Graph& graph, unsigned int const nvertices, + VertexPairIterator first, VertexPairIterator last) { + typedef boost::graph_traits Traits; + typedef typename Traits::vertex_descriptor vertex_descriptor; + std::map vertices; + + for (unsigned int i = 0; i < nvertices; ++i) + vertices[i] = add_vertex(graph); + + for (; first != last; ++first) { + unsigned int u = *first++; + + BOOST_ASSERT_MSG(first != last, + "there is a lonely vertex at the end of the edge list"); + + unsigned int v = *first; + + BOOST_ASSERT_MSG(vertices.count(u) == 1 && vertices.count(v) == 1, + "specified a vertex over the number of vertices in the graph"); + + add_edge(vertices[u], vertices[v], graph); + } + BOOST_ASSERT(num_vertices(graph) == nvertices); +} + + +int main(int argc, char const* argv[]) { + if (argc < 2) { + std::cout << "usage: " << argv[0] << " num_vertices < input\n"; + return EXIT_FAILURE; + } + + unsigned int num_vertices = boost::lexical_cast(argv[1]); + std::istream_iterator first_vertex(std::cin), last_vertex; + boost::directed_graph<> graph; + build_graph(graph, num_vertices, first_vertex, last_vertex); + + cycle_printer visitor(std::cout); + boost::hawick_circuits(graph, visitor); + + return EXIT_SUCCESS; +} diff --git a/example/implicit_graph.cpp b/example/implicit_graph.cpp index 5461d3dc..9b42e4d6 100644 --- a/example/implicit_graph.cpp +++ b/example/implicit_graph.cpp @@ -527,10 +527,16 @@ int main (int argc, char const *argv[]) { vertex_descriptor source = 0; std::vector pred(num_vertices(g)); std::vector dist(num_vertices(g)); + iterator_property_map::iterator, + property_map::const_type> + pred_pm(pred.begin(), get(vertex_index, g)); + iterator_property_map::iterator, + property_map::const_type> + dist_pm(dist.begin(), get(vertex_index, g)); dijkstra_shortest_paths(g, source, - predecessor_map(&pred[0]). - distance_map(&dist[0]) ); + predecessor_map(pred_pm). + distance_map(dist_pm) ); std::cout << "Dijkstra search from vertex " << source << std::endl; for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) { diff --git a/example/mcgregor_subgraphs_example.cpp b/example/mcgregor_subgraphs_example.cpp index 35a3b693..543259fc 100644 --- a/example/mcgregor_subgraphs_example.cpp +++ b/example/mcgregor_subgraphs_example.cpp @@ -76,11 +76,7 @@ int main (int argc, char *argv[]) { property >, property > Graph; - typedef graph_traits::vertex_descriptor Vertex; - typedef graph_traits::edge_descriptor Edge; - typedef property_map::type VertexNameMap; - typedef property_map::type EdgeNameMap; // Test maximum and unique variants on known graphs Graph graph_simple1, graph_simple2; diff --git a/example/stoer_wagner.cpp b/example/stoer_wagner.cpp index e710078b..09f13006 100644 --- a/example/stoer_wagner.cpp +++ b/example/stoer_wagner.cpp @@ -27,7 +27,6 @@ int main() typedef boost::adjacency_list > undirected_graph; - typedef boost::graph_traits::vertex_descriptor vertex_descriptor; typedef boost::property_map::type weight_map_type; typedef boost::property_traits::value_type weight_type; diff --git a/example/subgraph.cpp b/example/subgraph.cpp index a28a6cab..289ae54d 100644 --- a/example/subgraph.cpp +++ b/example/subgraph.cpp @@ -41,7 +41,6 @@ int main(int,char*[]) { using namespace boost; - typedef adjacency_list_traits Traits; typedef subgraph< adjacency_list, property > > Graph; diff --git a/example/successive_shortest_path_nonnegative_weights_example.cpp b/example/successive_shortest_path_nonnegative_weights_example.cpp new file mode 100644 index 00000000..0edc3710 --- /dev/null +++ b/example/successive_shortest_path_nonnegative_weights_example.cpp @@ -0,0 +1,30 @@ +//======================================================================= +// Copyright 2013 University of Warsaw. +// Authors: Piotr Wygocki +// +// 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 "../test/min_cost_max_flow_utils.hpp" + + +int main() { + boost::SampleGraph::vertex_descriptor s,t; + boost::SampleGraph::Graph g; + boost::SampleGraph::getSampleGraph(g, s, t); + + boost::successive_shortest_path_nonnegative_weights(g, s, t); + + int cost = boost::find_flow_cost(g); + assert(cost == 29); + + return 0; +} + + + diff --git a/include/boost/graph/bellman_ford_shortest_paths.hpp b/include/boost/graph/bellman_ford_shortest_paths.hpp index e102d922..7873067a 100644 --- a/include/boost/graph/bellman_ford_shortest_paths.hpp +++ b/include/boost/graph/bellman_ford_shortest_paths.hpp @@ -102,8 +102,6 @@ namespace boost { typedef typename GTraits::vertex_descriptor Vertex; BOOST_CONCEPT_ASSERT(( ReadWritePropertyMapConcept )); BOOST_CONCEPT_ASSERT(( ReadablePropertyMapConcept )); - typedef typename property_traits::value_type D_value; - typedef typename property_traits::value_type W_value; typename GTraits::edge_iterator i, end; diff --git a/include/boost/graph/betweenness_centrality.hpp b/include/boost/graph/betweenness_centrality.hpp index a4de1753..d596d5a2 100644 --- a/include/boost/graph/betweenness_centrality.hpp +++ b/include/boost/graph/betweenness_centrality.hpp @@ -296,7 +296,6 @@ namespace detail { namespace graph { ShortestPaths shortest_paths) { typedef typename graph_traits::vertex_iterator vertex_iterator; - typedef typename graph_traits::edge_iterator edge_iterator; typedef typename graph_traits::vertex_descriptor vertex_descriptor; // Initialize centrality @@ -421,7 +420,6 @@ namespace detail { namespace graph { VertexIndexMap vertex_index) { typedef typename graph_traits::degree_size_type degree_size_type; - typedef typename graph_traits::vertex_descriptor vertex_descriptor; typedef typename graph_traits::edge_descriptor edge_descriptor; typedef typename mpl::if_c<(is_same::value), @@ -457,7 +455,6 @@ namespace detail { namespace graph { VertexIndexMap vertex_index) { typedef typename graph_traits::degree_size_type degree_size_type; - typedef typename graph_traits::vertex_descriptor vertex_descriptor; typedef typename graph_traits::edge_descriptor edge_descriptor; typedef typename mpl::if_c<(is_same::value), diff --git a/include/boost/graph/bipartite.hpp b/include/boost/graph/bipartite.hpp index b917c607..74316fd5 100644 --- a/include/boost/graph/bipartite.hpp +++ b/include/boost/graph/bipartite.hpp @@ -198,7 +198,6 @@ namespace boost { /// 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; diff --git a/include/boost/graph/breadth_first_search.hpp b/include/boost/graph/breadth_first_search.hpp index 18bc24f5..b0d10ad5 100644 --- a/include/boost/graph/breadth_first_search.hpp +++ b/include/boost/graph/breadth_first_search.hpp @@ -64,7 +64,6 @@ namespace boost { BOOST_CONCEPT_ASSERT(( IncidenceGraphConcept )); typedef graph_traits GTraits; typedef typename GTraits::vertex_descriptor Vertex; - typedef typename GTraits::edge_descriptor Edge; BOOST_CONCEPT_ASSERT(( BFSVisitorConcept )); BOOST_CONCEPT_ASSERT(( ReadWritePropertyMapConcept )); typedef typename property_traits::value_type ColorValue; @@ -248,8 +247,7 @@ namespace boost { ColorMap color, BFSVisitor vis, const bgl_named_params& params, - BOOST_GRAPH_ENABLE_IF_MODELS(VertexListGraph, vertex_list_graph_tag, - void)* = 0) + boost::mpl::false_) { typedef graph_traits Traits; // Buffer default @@ -271,8 +269,7 @@ namespace boost { ColorMap color, BFSVisitor vis, const bgl_named_params& params, - BOOST_GRAPH_ENABLE_IF_MODELS(DistributedGraph, distributed_graph_tag, - void)* = 0); + boost::mpl::true_); #endif // BOOST_GRAPH_USE_MPI //------------------------------------------------------------------------- @@ -293,7 +290,11 @@ namespace boost { (g, s, color, choose_param(get_param(params, graph_visitor), make_bfs_visitor(null_visitor())), - params); + params, + boost::mpl::bool_< + boost::is_base_and_derived< + distributed_graph_tag, + typename graph_traits::traversal_category>::value>()); } }; @@ -316,7 +317,11 @@ namespace boost { g, vertex_index)), choose_param(get_param(params, graph_visitor), make_bfs_visitor(null_vis)), - params); + params, + boost::mpl::bool_< + boost::is_base_and_derived< + distributed_graph_tag, + typename graph_traits::traversal_category>::value>()); } }; diff --git a/include/boost/graph/chrobak_payne_drawing.hpp b/include/boost/graph/chrobak_payne_drawing.hpp index 4d026986..0e1f0525 100644 --- a/include/boost/graph/chrobak_payne_drawing.hpp +++ b/include/boost/graph/chrobak_payne_drawing.hpp @@ -73,7 +73,6 @@ namespace boost { typedef typename graph_traits::vertex_descriptor vertex_t; - typedef typename graph_traits::edge_descriptor edge_t; typedef typename graph_traits::vertex_iterator vertex_iterator_t; typedef typename PlanarEmbedding::value_type::const_iterator edge_permutation_iterator_t; diff --git a/include/boost/graph/closeness_centrality.hpp b/include/boost/graph/closeness_centrality.hpp index 44d478ab..3ddf284b 100644 --- a/include/boost/graph/closeness_centrality.hpp +++ b/include/boost/graph/closeness_centrality.hpp @@ -123,7 +123,6 @@ all_closeness_centralities(const Graph& g, typedef typename property_traits::value_type DistanceMap; BOOST_CONCEPT_ASSERT(( ReadablePropertyMapConcept )); BOOST_CONCEPT_ASSERT(( WritablePropertyMapConcept )); - typedef typename property_traits::value_type Distance; typedef typename property_traits::value_type Centrality; typename graph_traits::vertex_iterator i, end; @@ -147,7 +146,6 @@ all_closeness_centralities(const Graph& g, BOOST_CONCEPT_ASSERT(( ReadablePropertyMapConcept )); typedef typename property_traits::value_type DistanceMap; BOOST_CONCEPT_ASSERT(( ReadablePropertyMapConcept )); - typedef typename property_traits::value_type Distance; typedef typename property_traits::value_type Result; all_closeness_centralities(g, dist, cent, measure_closeness(g, DistanceMap())); diff --git a/include/boost/graph/compressed_sparse_row_graph.hpp b/include/boost/graph/compressed_sparse_row_graph.hpp index de3234a0..7b91d4d6 100644 --- a/include/boost/graph/compressed_sparse_row_graph.hpp +++ b/include/boost/graph/compressed_sparse_row_graph.hpp @@ -192,6 +192,11 @@ class compressed_sparse_row_graph > inherited_vertex_properties; + // Some tests to prevent use of "void" is a property type (as was done in some test cases): + BOOST_STATIC_ASSERT((!is_same::value)); + BOOST_STATIC_ASSERT((!is_same::value)); + BOOST_STATIC_ASSERT((!is_same::value)); + public: // For Property Graph typedef GraphProperty graph_property_type; diff --git a/include/boost/graph/connected_components.hpp b/include/boost/graph/connected_components.hpp index 076b2a68..9279110f 100644 --- a/include/boost/graph/connected_components.hpp +++ b/include/boost/graph/connected_components.hpp @@ -86,7 +86,7 @@ namespace boost { typedef typename graph_traits::vertex_descriptor Vertex; BOOST_CONCEPT_ASSERT(( WritablePropertyMapConcept )); - typedef typename boost::graph_traits::directed_category directed; + // typedef typename boost::graph_traits::directed_category directed; // BOOST_STATIC_ASSERT((boost::is_same::value)); typedef typename property_traits::value_type comp_type; diff --git a/include/boost/graph/core_numbers.hpp b/include/boost/graph/core_numbers.hpp index 33764c4f..9384f5d6 100644 --- a/include/boost/graph/core_numbers.hpp +++ b/include/boost/graph/core_numbers.hpp @@ -316,7 +316,6 @@ namespace boost { core_numbers(Graph& g, CoreMap c, EdgeWeightMap wm, VertexIndexMap vim, CoreNumVisitor vis) { - typedef typename graph_traits::vertices_size_type size_type; detail::compute_in_degree_map(g,c,wm); return detail::core_numbers_dispatch(g,c,wm,vim,vis); } diff --git a/include/boost/graph/cuthill_mckee_ordering.hpp b/include/boost/graph/cuthill_mckee_ordering.hpp index 52dc982a..e16595c6 100644 --- a/include/boost/graph/cuthill_mckee_ordering.hpp +++ b/include/boost/graph/cuthill_mckee_ordering.hpp @@ -75,7 +75,6 @@ namespace boost { { //create queue, visitor...don't forget namespaces! - typedef typename property_traits::value_type ds_type; typedef typename graph_traits::vertex_descriptor Vertex; typedef typename boost::sparse::sparse_ordering_queue queue; typedef typename detail::bfs_rcm_visitor Visitor; @@ -137,7 +136,6 @@ namespace boost { return permutation; typedef typename boost::graph_traits::vertex_descriptor Vertex; - typedef typename boost::graph_traits::vertex_iterator VerIter; typedef typename property_traits::value_type ColorValue; typedef color_traits Color; @@ -172,7 +170,6 @@ namespace boost { if (boost::graph::has_no_vertices(G)) return permutation; - typedef out_degree_property_map DegreeMap; std::vector colors(num_vertices(G)); return cuthill_mckee_ordering(G, permutation, make_iterator_property_map(&colors[0], diff --git a/include/boost/graph/cycle_canceling.hpp b/include/boost/graph/cycle_canceling.hpp new file mode 100644 index 00000000..46a4b864 --- /dev/null +++ b/include/boost/graph/cycle_canceling.hpp @@ -0,0 +1,181 @@ +//======================================================================= +// Copyright 2013 University of Warsaw. +// Authors: Piotr Wygocki +// +// 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) +//======================================================================= +// +// +//This algorithm is described in "Network Flows: Theory, Algorithms, and Applications" +// by Ahuja, Magnanti, Orlin. + +#ifndef BOOST_GRAPH_CYCLE_CANCELING_HPP +#define BOOST_GRAPH_CYCLE_CANCELING_HPP + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { + + +namespace detail { + +template +class RecordEdgeMapAndCycleVertex + : public bellman_visitor > { + typedef edge_predecessor_recorder PredRec; +public: + RecordEdgeMapAndCycleVertex(PredEdgeMap pred, Vertex & v) : + bellman_visitor(PredRec(pred)), m_v(v), m_pred(pred) {} + + template + void edge_not_minimized(Edge e, const Graph & g) const { + typename graph_traits::vertices_size_type n = num_vertices(g) + 1; + + //edge e is not minimized but does not have to be on the negative weight cycle + //to find vertex on negative wieight cycle we move n+1 times backword in the PredEdgeMap graph. + while(n > 0) { + e = get(m_pred, source(e, g)); + --n; + } + m_v = source(e, g); + } +private: + Vertex & m_v; + PredEdgeMap m_pred; +}; + +} //detail + + +template +void cycle_canceling(const Graph &g, Weight weight, Reversed rev, ResidualCapacity residual_capacity, Pred pred, Distance distance) { + typedef filtered_graph > ResGraph; + ResGraph gres = detail::residual_graph(g, residual_capacity); + + typedef graph_traits ResGTraits; + typedef graph_traits GTraits; + typedef typename ResGTraits::edge_descriptor edge_descriptor; + typedef typename ResGTraits::vertex_descriptor vertex_descriptor; + + typename GTraits::vertices_size_type N = num_vertices(g); + + BGL_FORALL_VERTICES_T(v, g, Graph) { + put(pred, v, edge_descriptor()); + put(distance, v, 0); + } + + vertex_descriptor cycleStart; + while(!bellman_ford_shortest_paths(gres, N, + weight_map(weight). + distance_map(distance). + visitor(detail::RecordEdgeMapAndCycleVertex(pred, cycleStart)))) { + + detail::augment(g, cycleStart, cycleStart, pred, residual_capacity, rev); + + BGL_FORALL_VERTICES_T(v, g, Graph) { + put(pred, v, edge_descriptor()); + put(distance, v, 0); + } + } +} + + +//in this namespace argument dispatching takes place +namespace detail { + +template +void cycle_canceling_dispatch2( + const Graph &g, + Weight weight, + Reversed rev, + ResidualCapacity residual_capacity, + Pred pred, + Distance dist, + const bgl_named_params& params) { + cycle_canceling(g, weight, rev, residual_capacity, pred, dist); +} + +//setting default distance map +template +void cycle_canceling_dispatch2( + Graph &g, + Weight weight, + Reversed rev, + ResidualCapacity residual_capacity, + Pred pred, + param_not_found, + const bgl_named_params& params) { + typedef typename property_traits::value_type D; + + std::vector d_map(num_vertices(g)); + + cycle_canceling(g, weight, rev, residual_capacity, pred, + make_iterator_property_map(d_map.begin(), choose_const_pmap(get_param(params, vertex_index), g, vertex_index))); +} + +template +void cycle_canceling_dispatch1( + Graph &g, + Weight weight, + Reversed rev, + ResidualCapacity residual_capacity, + Pred pred, + const bgl_named_params& params) { + cycle_canceling_dispatch2(g, weight, rev,residual_capacity, pred, + get_param(params, vertex_distance), params); +} + +//setting default predecessors map +template +void cycle_canceling_dispatch1( + Graph &g, + Weight weight, + Reversed rev, + ResidualCapacity residual_capacity, + param_not_found, + const bgl_named_params& params) { + typedef typename graph_traits::edge_descriptor edge_descriptor; + std::vector p_map(num_vertices(g)); + + cycle_canceling_dispatch2(g, weight, rev, residual_capacity, + make_iterator_property_map(p_map.begin(), choose_const_pmap(get_param(params, vertex_index), g, vertex_index)), + get_param(params, vertex_distance), params); +} + +}//detail + +template +void cycle_canceling(Graph &g, + const bgl_named_params& params) { + cycle_canceling_dispatch1(g, + choose_const_pmap(get_param(params, edge_weight), g, edge_weight), + choose_const_pmap(get_param(params, edge_reverse), g, edge_reverse), + choose_pmap(get_param(params, edge_residual_capacity), + g, edge_residual_capacity), + get_param(params, vertex_predecessor), + params); +} + +template +void cycle_canceling(Graph &g) { + bgl_named_params params(0); + cycle_canceling(g, params); +} + + +} + +#endif /* BOOST_GRAPH_CYCLE_CANCELING_HPP */ + diff --git a/include/boost/graph/depth_first_search.hpp b/include/boost/graph/depth_first_search.hpp index 34d73a2f..b002d367 100644 --- a/include/boost/graph/depth_first_search.hpp +++ b/include/boost/graph/depth_first_search.hpp @@ -21,8 +21,10 @@ #include #include #include +#include #include #include +#include #include #include @@ -41,6 +43,7 @@ namespace boost { vis.tree_edge(e, g); vis.back_edge(e, g); vis.forward_or_cross_edge(e, g); + // vis.finish_edge(e, g); // Optional for user vis.finish_vertex(u, g); } private: @@ -57,6 +60,25 @@ namespace boost { bool operator()(const T&, const T2&) const { return false; } }; + BOOST_TTI_HAS_MEMBER_FUNCTION(finish_edge) + + template struct do_call_finish_edge { + template + static void call_finish_edge(Vis& vis, const E& e, const G& g) { + vis.finish_edge(e, g); + } + }; + + template <> struct do_call_finish_edge { + template + static void call_finish_edge(Vis&, const E&, const G&) {} + }; + + template + void call_finish_edge(Vis& vis, const E& e, const G& g) { // Only call if method exists + do_call_finish_edge::value>::call_finish_edge(vis, e, g); + } + // Define BOOST_RECURSIVE_DFS to use older, recursive version. // It is retained for a while in order to perform performance @@ -85,36 +107,35 @@ namespace boost { BOOST_CONCEPT_ASSERT(( IncidenceGraphConcept )); BOOST_CONCEPT_ASSERT(( DFSVisitorConcept )); typedef typename graph_traits::vertex_descriptor Vertex; + typedef typename graph_traits::edge_descriptor Edge; BOOST_CONCEPT_ASSERT(( ReadWritePropertyMapConcept )); typedef typename property_traits::value_type ColorValue; BOOST_CONCEPT_ASSERT(( ColorValueConcept )); typedef color_traits Color; typedef typename graph_traits::out_edge_iterator Iter; - typedef std::pair > VertexInfo; + typedef std::pair, std::pair > > VertexInfo; + boost::optional src_e; Iter ei, ei_end; std::vector stack; // Possible optimization for vector //stack.reserve(num_vertices(g)); - typedef typename unwrap_reference::type TF; - put(color, u, Color::gray()); vis.discover_vertex(u, g); boost::tie(ei, ei_end) = out_edges(u, g); - // Variable is needed to workaround a borland bug. - TF& fn = static_cast(func); - if (fn(u, g)) { + if (func(u, g)) { // If this vertex terminates the search, we push empty range - stack.push_back(std::make_pair(u, std::make_pair(ei_end, ei_end))); + stack.push_back(std::make_pair(u, std::make_pair(boost::optional(), std::make_pair(ei_end, ei_end)))); } else { - stack.push_back(std::make_pair(u, std::make_pair(ei, ei_end))); + stack.push_back(std::make_pair(u, std::make_pair(boost::optional(), std::make_pair(ei, ei_end)))); } while (!stack.empty()) { VertexInfo& back = stack.back(); u = back.first; - boost::tie(ei, ei_end) = back.second; + src_e = back.second.first; + boost::tie(ei, ei_end) = back.second.second; stack.pop_back(); while (ei != ei_end) { Vertex v = target(*ei, g); @@ -122,24 +143,28 @@ namespace boost { ColorValue v_color = get(color, v); if (v_color == Color::white()) { vis.tree_edge(*ei, g); - stack.push_back(std::make_pair(u, std::make_pair(++ei, ei_end))); + src_e = *ei; + stack.push_back(std::make_pair(u, std::make_pair(src_e, std::make_pair(++ei, ei_end)))); u = v; put(color, u, Color::gray()); vis.discover_vertex(u, g); boost::tie(ei, ei_end) = out_edges(u, g); - if (fn(u, g)) { + if (func(u, g)) { ei = ei_end; } - } else if (v_color == Color::gray()) { - vis.back_edge(*ei, g); - ++ei; } else { - vis.forward_or_cross_edge(*ei, g); + if (v_color == Color::gray()) { + vis.back_edge(*ei, g); + } else { + vis.forward_or_cross_edge(*ei, g); + } + call_finish_edge(vis, *ei, g); ++ei; } } put(color, u, Color::black()); vis.finish_vertex(u, g); + if (src_e) call_finish_edge(vis, src_e.get(), g); } } @@ -164,10 +189,7 @@ namespace boost { put(color, u, Color::gray()); vis.discover_vertex(u, g); - typedef typename unwrap_reference::type TF; - // Variable is needed to workaround a borland bug. - TF& fn = static_cast(func); - if (!fn(u, g)) + if (!func(u, g)) for (boost::tie(ei, ei_end) = out_edges(u, g); ei != ei_end; ++ei) { Vertex v = target(*ei, g); vis.examine_edge(*ei, g); ColorValue v_color = get(color, v); @@ -175,6 +197,7 @@ namespace boost { depth_first_visit_impl(g, v, vis, color, func); } else if (v_color == Color::gray()) vis.back_edge(*ei, g); else vis.forward_or_cross_edge(*ei, g); + call_finish_edge(vis, *ei, g); } put(color, u, Color::black()); vis.finish_vertex(u, g); } @@ -259,6 +282,10 @@ namespace boost { void forward_or_cross_edge(Edge u, const Graph& g) { invoke_visitors(m_vis, u, g, ::boost::on_forward_or_cross_edge()); } + template + void finish_edge(Edge u, const Graph& g) { + invoke_visitors(m_vis, u, g, ::boost::on_finish_edge()); + } template void finish_vertex(Vertex u, const Graph& g) { invoke_visitors(m_vis, u, g, ::boost::on_finish_vertex()); @@ -271,6 +298,7 @@ namespace boost { BOOST_GRAPH_EVENT_STUB(on_tree_edge,dfs) BOOST_GRAPH_EVENT_STUB(on_back_edge,dfs) BOOST_GRAPH_EVENT_STUB(on_forward_or_cross_edge,dfs) + BOOST_GRAPH_EVENT_STUB(on_finish_edge,dfs) BOOST_GRAPH_EVENT_STUB(on_finish_vertex,dfs) protected: diff --git a/include/boost/graph/detail/adjacency_list.hpp b/include/boost/graph/detail/adjacency_list.hpp index dd27ecd4..a99ec265 100644 --- a/include/boost/graph/detail/adjacency_list.hpp +++ b/include/boost/graph/detail/adjacency_list.hpp @@ -806,7 +806,6 @@ namespace boost { typedef typename EdgeList::value_type StoredEdge; typename EdgeList::iterator i = el.find(StoredEdge(v)), end = el.end(); - BOOST_ASSERT ((i != end)); if (i != end) { g.m_edges.erase((*i).get_iter()); el.erase(i); diff --git a/include/boost/graph/detail/augment.hpp b/include/boost/graph/detail/augment.hpp new file mode 100644 index 00000000..3b20dcc4 --- /dev/null +++ b/include/boost/graph/detail/augment.hpp @@ -0,0 +1,63 @@ +//======================================================================= +// Copyright 2013 University of Warsaw. +// Authors: Piotr Wygocki +// +// 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_AUGMENT_HPP +#define BOOST_GRAPH_AUGMENT_HPP + +#include + +namespace boost { +namespace detail { + +template +filtered_graph > +residual_graph(const Graph& g, ResCapMap residual_capacity) { + return filtered_graph > + (g, is_residual_edge(residual_capacity)); +} + +template +inline void +augment(const Graph& g, + typename graph_traits::vertex_descriptor src, + typename graph_traits::vertex_descriptor sink, + PredEdgeMap p, + ResCapMap residual_capacity, + RevEdgeMap reverse_edge) +{ + typename graph_traits::edge_descriptor e; + typename graph_traits::vertex_descriptor u; + typedef typename property_traits::value_type FlowValue; + + // find minimum residual capacity along the augmenting path + FlowValue delta = (std::numeric_limits::max)(); + e = get(p, sink); + do { + BOOST_USING_STD_MIN(); + delta = min BOOST_PREVENT_MACRO_SUBSTITUTION(delta, get(residual_capacity, e)); + u = source(e, g); + e = get(p, u); + } while (u != src); + + // push delta units of flow along the augmenting path + e = get(p, sink); + do { + put(residual_capacity, e, get(residual_capacity, e) - delta); + put(residual_capacity, get(reverse_edge, e), get(residual_capacity, get(reverse_edge, e)) + delta); + u = source(e, g); + e = get(p, u); + } while (u != src); +} + +} // namespace detail +} //namespace boost + +#endif /* BOOST_GRAPH_AUGMENT_HPP */ + diff --git a/include/boost/graph/dijkstra_shortest_paths.hpp b/include/boost/graph/dijkstra_shortest_paths.hpp index 45bac7df..10e40f82 100644 --- a/include/boost/graph/dijkstra_shortest_paths.hpp +++ b/include/boost/graph/dijkstra_shortest_paths.hpp @@ -118,6 +118,7 @@ namespace boost { struct dijkstra_bfs_visitor { typedef typename property_traits::value_type D; + typedef typename property_traits::value_type W; dijkstra_bfs_visitor(UniformCostVisitor vis, UpdatableQueue& Q, WeightMap w, PredecessorMap p, DistanceMap d, @@ -159,13 +160,39 @@ namespace boost { void examine_vertex(Vertex u, Graph& g) { m_vis.examine_vertex(u, g); } template void examine_edge(Edge e, Graph& g) { - // Comparison needs to be more complicated because distance and weight - // types may not be the same; see bug 8398 - // (https://svn.boost.org/trac/boost/ticket/8398) - D source_dist = get(m_distance, source(e, g)); - if (m_compare(m_combine(source_dist, get(m_weight, e)), source_dist)) + // Test for negative-weight edges: + // + // Reasons that other comparisons do not work: + // + // m_compare(e_weight, D(0)): + // m_compare only needs to work on distances, not weights, and those + // types do not need to be the same (bug 8398, + // https://svn.boost.org/trac/boost/ticket/8398). + // m_compare(m_combine(source_dist, e_weight), source_dist): + // if m_combine is project2nd (as in prim_minimum_spanning_tree), + // this test will claim that the edge weight is negative whenever + // the edge weight is less than source_dist, even if both of those + // are positive (bug 9012, + // https://svn.boost.org/trac/boost/ticket/9012). + // m_compare(m_combine(e_weight, source_dist), source_dist): + // would fix project2nd issue, but documentation only requires that + // m_combine be able to take a distance and a weight (in that order) + // and return a distance. + + // W e_weight = get(m_weight, e); + // sd_plus_ew = source_dist + e_weight. + // D sd_plus_ew = m_combine(source_dist, e_weight); + // sd_plus_2ew = source_dist + 2 * e_weight. + // D sd_plus_2ew = m_combine(sd_plus_ew, e_weight); + // The test here is equivalent to e_weight < 0 if m_combine has a + // cancellation law, but always returns false when m_combine is a + // projection operator. + if (m_compare(m_combine(m_zero, get(m_weight, e)), m_zero)) boost::throw_exception(negative_edge()); + // End of test for negative-weight edges. + m_vis.examine_edge(e, g); + } template void black_target(Edge, Graph&) { } @@ -255,6 +282,31 @@ namespace boost { }; } + // Call breadth first search with default color map. + template + inline void + dijkstra_shortest_paths_no_init + (const Graph& g, + SourceInputIter s_begin, SourceInputIter s_end, + PredecessorMap predecessor, DistanceMap distance, WeightMap weight, + IndexMap index_map, + Compare compare, Combine combine, DistZero zero, + DijkstraVisitor vis) + { + typedef + detail::default_color_map_generator + ColorMapHelper; + typedef typename ColorMapHelper::type ColorMap; + ColorMap color = + ColorMapHelper::build(g, index_map); + dijkstra_shortest_paths_no_init( g, s_begin, s_end, predecessor, distance, weight, + index_map, compare, combine, zero, vis, + color); + } + // Call breadth first search with default color map. template - ColorMapHelper; - typedef typename ColorMapHelper::type ColorMap; - ColorMap color = - ColorMapHelper::build(g, index_map); - dijkstra_shortest_paths_no_init( g, s, predecessor, distance, weight, - index_map, compare, combine, zero, vis, - color); + dijkstra_shortest_paths_no_init(g, &s, &s + 1, predecessor, distance, + weight, index_map, compare, combine, zero, + vis); } // Call breadth first search - template inline void dijkstra_shortest_paths_no_init (const Graph& g, - typename graph_traits::vertex_descriptor s, + SourceInputIter s_begin, SourceInputIter s_end, PredecessorMap predecessor, DistanceMap distance, WeightMap weight, IndexMap index_map, Compare compare, Combine combine, DistZero zero, @@ -309,7 +355,7 @@ namespace boost { PredecessorMap, DistanceMap, Combine, Compare> bfs_vis(vis, Q, weight, predecessor, distance, combine, compare, zero); - breadth_first_visit(g, s, Q, bfs_vis, color); + breadth_first_visit(g, s_begin, s_end, Q, bfs_vis, color); return; } #endif // BOOST_GRAPH_DIJKSTRA_TESTING @@ -334,7 +380,49 @@ namespace boost { PredecessorMap, DistanceMap, Combine, Compare> bfs_vis(vis, Q, weight, predecessor, distance, combine, compare, zero); - breadth_first_visit(g, s, Q, bfs_vis, color); + breadth_first_visit(g, s_begin, s_end, Q, bfs_vis, color); + } + + // Call breadth first search + template + inline void + dijkstra_shortest_paths_no_init + (const Graph& g, + typename graph_traits::vertex_descriptor s, + PredecessorMap predecessor, DistanceMap distance, WeightMap weight, + IndexMap index_map, + Compare compare, Combine combine, DistZero zero, + DijkstraVisitor vis, ColorMap color) + { + dijkstra_shortest_paths_no_init(g, &s, &s + 1, predecessor, distance, + weight, index_map, compare, combine, + zero, vis, color); + } + + // Initialize distances and call breadth first search with default color map + template + inline void + dijkstra_shortest_paths + (const VertexListGraph& g, + SourceInputIter s_begin, SourceInputIter s_end, + PredecessorMap predecessor, DistanceMap distance, WeightMap weight, + IndexMap index_map, + Compare compare, Combine combine, DistInf inf, DistZero zero, + DijkstraVisitor vis, + const bgl_named_params& + BOOST_GRAPH_ENABLE_IF_MODELS_PARM(VertexListGraph,vertex_list_graph_tag)) + { + boost::two_bit_color_map color(num_vertices(g), index_map); + dijkstra_shortest_paths(g, s_begin, s_end, predecessor, distance, weight, + index_map, compare, combine, inf, zero, vis, + color); } // Initialize distances and call breadth first search with default color map @@ -354,9 +442,39 @@ namespace boost { const bgl_named_params& BOOST_GRAPH_ENABLE_IF_MODELS_PARM(VertexListGraph,vertex_list_graph_tag)) { - boost::two_bit_color_map color(num_vertices(g), index_map); - dijkstra_shortest_paths(g, s, predecessor, distance, weight, index_map, - compare, combine, inf, zero, vis, + dijkstra_shortest_paths(g, &s, &s + 1, predecessor, distance, weight, + index_map, compare, combine, inf, zero, vis); + } + + // Initialize distances and call breadth first search + template + inline void + dijkstra_shortest_paths + (const VertexListGraph& g, + SourceInputIter s_begin, SourceInputIter s_end, + PredecessorMap predecessor, DistanceMap distance, WeightMap weight, + IndexMap index_map, + Compare compare, Combine combine, DistInf inf, DistZero zero, + DijkstraVisitor vis, ColorMap color) + { + typedef typename property_traits::value_type ColorValue; + typedef color_traits Color; + typename graph_traits::vertex_iterator ui, ui_end; + for (boost::tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui) { + vis.initialize_vertex(*ui, g); + put(distance, *ui, inf); + put(predecessor, *ui, *ui); + put(color, *ui, Color::white()); + } + for (SourceInputIter it = s_begin; it != s_end; ++it) { + put(distance, *it, zero); + } + + dijkstra_shortest_paths_no_init(g, s_begin, s_end, predecessor, distance, + weight, index_map, compare, combine, zero, vis, color); } @@ -374,19 +492,30 @@ namespace boost { Compare compare, Combine combine, DistInf inf, DistZero zero, DijkstraVisitor vis, ColorMap color) { - typedef typename property_traits::value_type ColorValue; - typedef color_traits Color; - typename graph_traits::vertex_iterator ui, ui_end; - for (boost::tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui) { - vis.initialize_vertex(*ui, g); - put(distance, *ui, inf); - put(predecessor, *ui, *ui); - put(color, *ui, Color::white()); - } - put(distance, s, zero); + dijkstra_shortest_paths(g, &s, &s + 1, predecessor, distance, weight, + index_map, compare, combine, inf, zero, + vis, color); + } - dijkstra_shortest_paths_no_init(g, s, predecessor, distance, weight, - index_map, compare, combine, zero, vis, color); + // Initialize distances and call breadth first search + template + inline void + dijkstra_shortest_paths + (const VertexListGraph& g, + SourceInputIter s_begin, SourceInputIter s_end, + PredecessorMap predecessor, DistanceMap distance, WeightMap weight, + IndexMap index_map, + Compare compare, Combine combine, DistInf inf, DistZero zero, + DijkstraVisitor vis) + { + dijkstra_shortest_paths(g, s_begin, s_end, predecessor, distance, + weight, index_map, + compare, combine, inf, zero, vis, + no_named_parameters()); } // Initialize distances and call breadth first search @@ -403,9 +532,9 @@ namespace boost { Compare compare, Combine combine, DistInf inf, DistZero zero, DijkstraVisitor vis) { - dijkstra_shortest_paths(g, s, predecessor, distance, weight, index_map, - compare, combine, inf, zero, vis, - no_named_parameters()); + dijkstra_shortest_paths(g, &s, &s + 1, predecessor, distance, + weight, index_map, + compare, combine, inf, zero, vis); } namespace detail { diff --git a/include/boost/graph/dijkstra_shortest_paths_no_color_map.hpp b/include/boost/graph/dijkstra_shortest_paths_no_color_map.hpp index c5ce6b6d..b1a9ef58 100644 --- a/include/boost/graph/dijkstra_shortest_paths_no_color_map.hpp +++ b/include/boost/graph/dijkstra_shortest_paths_no_color_map.hpp @@ -41,7 +41,6 @@ namespace boost { { typedef typename graph_traits::vertex_descriptor Vertex; typedef typename property_traits::value_type Distance; - typedef typename property_traits::value_type Weight; typedef indirect_cmp DistanceIndirectCompare; DistanceIndirectCompare @@ -92,7 +91,6 @@ namespace boost { } // Examine neighbors of min_vertex - typedef typename graph_traits::edge_descriptor Edge; BGL_FORALL_OUTEDGES_T(min_vertex, current_edge, graph, Graph) { visitor.examine_edge(current_edge, graph); diff --git a/include/boost/graph/edge_coloring.hpp b/include/boost/graph/edge_coloring.hpp new file mode 100644 index 00000000..8eb79ad4 --- /dev/null +++ b/include/boost/graph/edge_coloring.hpp @@ -0,0 +1,196 @@ +//======================================================================= +// Copyright 2013 Maciej Piechotka +// Authors: Maciej Piechotka +// +// 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_EDGE_COLORING_HPP +#define BOOST_GRAPH_EDGE_COLORING_HPP + +#include +#include +#include +#include +#include +#include + +/* This algorithm is to find coloring of an edges + + Reference: + + Misra, J., & Gries, D. (1992). A constructive proof of Vizing's + theorem. In Information Processing Letters. +*/ + +namespace boost { + namespace detail { + template + bool + is_free(const Graph &g, + ColorMap color, + typename boost::graph_traits::vertex_descriptor u, + typename boost::property_traits::value_type free_color) + { + typedef typename boost::property_traits::value_type color_t; + if (free_color == (std::numeric_limits::max)()) + return false; + BGL_FORALL_OUTEDGES_T(u, e, g, Graph) { + if (get(color, e) == free_color) { + return false; + } + } + return true; + } + + template + std::vector::vertex_descriptor> + maximal_fan(const Graph &g, + ColorMap color, + typename boost::graph_traits::vertex_descriptor x, + typename boost::graph_traits::vertex_descriptor y) + { + typedef typename boost::graph_traits::vertex_descriptor vertex_t; + std::vector fan; + fan.push_back(y); + bool extended; + do { + extended = false; + BGL_FORALL_OUTEDGES_T(x, e, g, Graph) { + vertex_t v = target(e, g); + if (is_free(g, color, fan.back(), get(color, e)) && + std::find(fan.begin(), fan.end(), v) == fan.end()) { + fan.push_back(v); + extended = true; + } + } + } while(extended); + return fan; + } + template + typename boost::property_traits::value_type + find_free_color(const Graph &g, + ColorMap color, + typename boost::graph_traits::vertex_descriptor u) + { + typename boost::property_traits::value_type c = 0; + while (!is_free(g, color, u, c)) c++; + return c; + } + + template + void + invert_cd_path(const Graph &g, + ColorMap color, + typename boost::graph_traits::vertex_descriptor x, + typename boost::graph_traits::edge_descriptor eold, + typename boost::property_traits::value_type c, + typename boost::property_traits::value_type d) + { + put(color, eold, d); + BGL_FORALL_OUTEDGES_T(x, e, g, Graph) { + if (get(color, e) == d && e != eold) { + invert_cd_path(g, color, target(e, g), e, d, c); + return; + } + } + } + + template + void + invert_cd_path(const Graph &g, + ColorMap color, + typename boost::graph_traits::vertex_descriptor x, + typename boost::property_traits::value_type c, + typename boost::property_traits::value_type d) + { + BGL_FORALL_OUTEDGES_T(x, e, g, Graph) { + if (get(color, e) == d) { + invert_cd_path(g, color, target(e, g), e, d, c); + return; + } + } + } + + template + void + rotate_fan(const Graph &g, + ColorMap color, + typename boost::graph_traits::vertex_descriptor x, + ForwardIterator begin, + ForwardIterator end) + { + typedef typename boost::graph_traits::edge_descriptor edge_t; + if (begin == end) { + return; + } + edge_t previous = edge(x, *begin, g).first; + for (begin++; begin != end; begin++) { + edge_t current = edge(x, *begin, g).first; + put(color, previous, get(color, current)); + previous = current; + } + } + + template + class find_free_in_fan + { + public: + find_free_in_fan(const Graph &graph, + const ColorMap color, + typename boost::property_traits::value_type d) + : graph(graph), + color(color), + d(d) {} + bool operator()(const typename boost::graph_traits::vertex_descriptor u) const { + return is_free(graph, color, u, d); + } + private: + const Graph &graph; + const ColorMap color; + const typename boost::property_traits::value_type d; + }; + } + + template + typename boost::property_traits::value_type + color_edge(const Graph &g, + ColorMap color, + typename boost::graph_traits::edge_descriptor e) + { + typedef typename boost::graph_traits::vertex_descriptor vertex_t; + typedef typename boost::property_traits::value_type color_t; + typedef typename std::vector::iterator fan_iterator; + using namespace detail; + vertex_t x = source(e, g), y = target(e, g); + std::vector fan = maximal_fan(g, color, x, y); + color_t c = find_free_color(g, color, x); + color_t d = find_free_color(g, color, fan.back()); + invert_cd_path(g, color, x, c, d); + fan_iterator w = std::find_if(fan.begin(), + fan.end(), + find_free_in_fan(g, color, d)); + rotate_fan(g, color, x, fan.begin(), w + 1); + put(color, edge(x, *w, g).first, d); + return (std::max)(c, d); + } + + template + typename boost::property_traits::value_type + edge_coloring(const Graph &g, + ColorMap color) + { + typedef typename boost::property_traits::value_type color_t; + BGL_FORALL_EDGES_T(e, g, Graph) { + put(color, e, (std::numeric_limits::max)()); + } + color_t colors = 0; + BGL_FORALL_EDGES_T(e, g, Graph) { + colors = (std::max)(colors, color_edge(g, color, e) + 1); + } + return colors; + } +} + +#endif diff --git a/include/boost/graph/edmonds_karp_max_flow.hpp b/include/boost/graph/edmonds_karp_max_flow.hpp index 8f86fb20..377e6f14 100644 --- a/include/boost/graph/edmonds_karp_max_flow.hpp +++ b/include/boost/graph/edmonds_karp_max_flow.hpp @@ -151,7 +151,6 @@ namespace boost { const bgl_named_params& params, param_not_found) { - typedef typename graph_traits::edge_descriptor edge_descriptor; typedef typename graph_traits::vertices_size_type size_type; size_type n = is_default_param(get_param(params, vertex_color)) ? num_vertices(g) : 1; diff --git a/include/boost/graph/find_flow_cost.hpp b/include/boost/graph/find_flow_cost.hpp new file mode 100644 index 00000000..e4d6f404 --- /dev/null +++ b/include/boost/graph/find_flow_cost.hpp @@ -0,0 +1,52 @@ +//======================================================================= +// Copyright 2013 University of Warsaw. +// Authors: Piotr Wygocki +// +// 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_FIND_FLOW_COST_HPP +#define BOOST_GRAPH_FIND_FLOW_COST_HPP + +#include + +namespace boost { + +template +typename property_traits::type>::value_type +find_flow_cost(const Graph & g, Capacity capacity, ResidualCapacity residual_capacity, Weight weight) { + typedef typename property_traits::const_type>::value_type Cost; + + Cost cost = 0; + BGL_FORALL_EDGES_T(e, g, Graph) { + if(get(capacity, e) > Cost(0)) { + cost += (get(capacity, e) - get(residual_capacity, e)) * get(weight, e); + } + } + return cost; +} + +template +typename property_traits::type>::value_type +find_flow_cost(const Graph & g, + const bgl_named_params& params) { + return find_flow_cost(g, + choose_const_pmap(get_param(params, edge_capacity), g, edge_capacity), + choose_const_pmap(get_param(params, edge_residual_capacity), + g, edge_residual_capacity), + choose_const_pmap(get_param(params, edge_weight), g, edge_weight)); +} + +template +typename property_traits::type>::value_type +find_flow_cost(const Graph &g) { + bgl_named_params params(0); + return find_flow_cost(g, params); +} + + +} //boost + +#endif /* BOOST_GRAPH_FIND_FLOW_COST_HPP */ + diff --git a/include/boost/graph/fruchterman_reingold.hpp b/include/boost/graph/fruchterman_reingold.hpp index bab353f3..01d080a4 100644 --- a/include/boost/graph/fruchterman_reingold.hpp +++ b/include/boost/graph/fruchterman_reingold.hpp @@ -282,7 +282,6 @@ fruchterman_reingold_force_directed_layout Cooling cool, DisplacementMap displacement) { - typedef typename Topology::point_type Point; typedef typename graph_traits::vertex_iterator vertex_iterator; typedef typename graph_traits::vertex_descriptor vertex_descriptor; typedef typename graph_traits::edge_iterator edge_iterator; diff --git a/include/boost/graph/graph_traits.hpp b/include/boost/graph/graph_traits.hpp index ceb0c2ac..a1c27483 100644 --- a/include/boost/graph/graph_traits.hpp +++ b/include/boost/graph/graph_traits.hpp @@ -166,7 +166,13 @@ namespace boost { struct edge_list_graph_tag { }; struct adjacency_matrix_tag { }; - /** @name Taversal Category Traits + // Parallel traversal_category tags + struct distributed_graph_tag { }; + struct distributed_vertex_list_graph_tag { }; + struct distributed_edge_list_graph_tag { }; +#define BOOST_GRAPH_SEQUENTIAL_TRAITS_DEFINES_DISTRIBUTED_TAGS // Disable these from external versions of PBGL + + /** @name Traversal Category Traits * These traits classify graph types by their supported methods of * vertex and edge traversal. */ diff --git a/include/boost/graph/graph_utility.hpp b/include/boost/graph/graph_utility.hpp index ba1fe3d8..e772b640 100644 --- a/include/boost/graph/graph_utility.hpp +++ b/include/boost/graph/graph_utility.hpp @@ -237,8 +237,6 @@ namespace boost { template bool is_adj_dispatch(Graph& g, Vertex a, Vertex b, bidirectional_tag) { - typedef typename graph_traits::edge_descriptor - edge_descriptor; typename graph_traits::adjacency_iterator vi, viend, adj_found; boost::tie(vi, viend) = adjacent_vertices(a, g); @@ -265,8 +263,6 @@ namespace boost { template bool is_adj_dispatch(Graph& g, Vertex a, Vertex b, directed_tag) { - typedef typename graph_traits::edge_descriptor - edge_descriptor; typename graph_traits::adjacency_iterator vi, viend, found; boost::tie(vi, viend) = adjacent_vertices(a, g); #if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 && defined(__SGI_STL_PORT) diff --git a/include/boost/graph/gursoy_atun_layout.hpp b/include/boost/graph/gursoy_atun_layout.hpp index 9269c4b0..9f050e1b 100644 --- a/include/boost/graph/gursoy_atun_layout.hpp +++ b/include/boost/graph/gursoy_atun_layout.hpp @@ -208,9 +208,6 @@ void gursoy_atun_refine(const VertexListAndIncidenceGraph& graph, typedef typename graph_traits::vertex_iterator vertex_iterator; - typedef typename graph_traits::vertex_descriptor - vertex_descriptor; - typedef typename Topology::point_type point_type; vertex_iterator i, iend; double diameter_ratio = (double)diameter_final / diameter_initial; double learning_constant_ratio = @@ -230,6 +227,7 @@ void gursoy_atun_refine(const VertexListAndIncidenceGraph& graph, vertex_index_map); for (int round = 0; round < nsteps; ++round) { double part_done = (double)round / (nsteps - 1); + // fprintf(stderr, "%2d%% done\n", int(rint(part_done * 100.))); int diameter = (int)(diameter_initial * pow(diameter_ratio, part_done)); double learning_constant = learning_constant_initial * pow(learning_constant_ratio, part_done); diff --git a/include/boost/graph/hawick_circuits.hpp b/include/boost/graph/hawick_circuits.hpp new file mode 100644 index 00000000..93c12b5c --- /dev/null +++ b/include/boost/graph/hawick_circuits.hpp @@ -0,0 +1,381 @@ +// Copyright Louis Dionne 2013 + +// 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) + +#ifndef BOOST_GRAPH_HAWICK_CIRCUITS_HPP +#define BOOST_GRAPH_HAWICK_CIRCUITS_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include // for boost::tie +#include +#include +#include +#include // for std::pair +#include + + +namespace boost { +namespace hawick_circuits_detail { +//! @internal Functor returning all the vertices adjacent to a vertex. +struct get_all_adjacent_vertices { + template + struct result; + + template + struct result { + private: + typedef typename remove_reference::type RawGraph; + typedef graph_traits Traits; + typedef typename Traits::adjacency_iterator AdjacencyIterator; + + public: + typedef std::pair type; + }; + + template + typename result< + get_all_adjacent_vertices(BOOST_FWD_REF(Vertex), BOOST_FWD_REF(Graph)) + >::type + operator()(BOOST_FWD_REF(Vertex) v, BOOST_FWD_REF(Graph) g) const { + return adjacent_vertices(boost::forward(v), + boost::forward(g)); + } +}; + +//! @internal Functor returning a set of the vertices adjacent to a vertex. +struct get_unique_adjacent_vertices { + template + struct result; + + template + struct result { + typedef std::set::type> type; + }; + + template + typename result::type + operator()(Vertex v, Graph const& g) const { + typedef typename result< + get_unique_adjacent_vertices(Vertex, Graph const&) + >::type Set; + return Set(adjacent_vertices(v, g).first, + adjacent_vertices(v, g).second); + } +}; + +//! @internal +//! Return whether a container contains a given value. +//! This is not meant as a general purpose membership testing function; it +//! would have to be more clever about possible optimizations. +template +bool contains(Container const& c, Value const& v) { + return std::find(boost::begin(c), boost::end(c), v) != boost::end(c); +} + +/*! + * @internal + * Algorithm finding all the cycles starting from a given vertex. + * + * The search is only done in the subgraph induced by the starting vertex + * and the vertices with an index higher than the starting vertex. + */ +template < + typename Graph, + typename Visitor, + typename VertexIndexMap, + typename Stack, + typename ClosedMatrix, + typename GetAdjacentVertices +> +struct hawick_circuits_from { +private: + typedef graph_traits Traits; + typedef typename Traits::vertex_descriptor Vertex; + typedef typename Traits::edge_descriptor Edge; + typedef typename Traits::vertices_size_type VerticesSize; + typedef typename property_traits::value_type VertexIndex; + + typedef typename result_of< + GetAdjacentVertices(Vertex, Graph const&) + >::type AdjacentVertices; + typedef typename range_iterator::type AdjacencyIterator; + + // The one_bit_color_map starts all white, i.e. not blocked. + // Since we make that assumption (I looked at the implementation, but + // I can't find anything that documents this behavior), we're gonna + // assert it in the constructor. + typedef one_bit_color_map BlockedMap; + typedef typename property_traits::value_type BlockedColor; + + static BlockedColor blocked_false_color() + { return color_traits::white(); } + + static BlockedColor blocked_true_color() + { return color_traits::black(); } + + // This is used by the constructor to secure the assumption + // documented above. + bool blocked_map_starts_all_unblocked() const { + BOOST_FOREACH(Vertex v, vertices(graph_)) + if (is_blocked(v)) + return false; + return true; + } + + // This is only used in the constructor to make sure the optimization of + // sharing data structures between iterations does not break the code. + bool all_closed_rows_are_empty() const { + BOOST_FOREACH(typename ClosedMatrix::reference row, closed_) + if (!row.empty()) + return false; + return true; + } + +public: + hawick_circuits_from(Graph const& graph, Visitor& visitor, + VertexIndexMap const& vim, + Stack& stack, ClosedMatrix& closed, + VerticesSize n_vertices) + : graph_(graph), visitor_(visitor), vim_(vim), stack_(stack), + closed_(closed), blocked_(n_vertices, vim_) + { + BOOST_ASSERT(blocked_map_starts_all_unblocked()); + + // Since sharing the data structures between iterations is + // just an optimization, it must always be equivalent to + // constructing new ones in this constructor. + BOOST_ASSERT(stack_.empty()); + BOOST_ASSERT(closed_.size() == n_vertices); + BOOST_ASSERT(all_closed_rows_are_empty()); + } + +private: + //! @internal Return the index of a given vertex. + VertexIndex index_of(Vertex v) const { + return get(vim_, v); + } + + + //! @internal Return whether a vertex `v` is closed to a vertex `u`. + bool is_closed_to(Vertex u, Vertex v) const { + typedef typename ClosedMatrix::const_reference VertexList; + VertexList closed_to_u = closed_[index_of(u)]; + return contains(closed_to_u, v); + } + + //! @internal Close a vertex `v` to a vertex `u`. + void close_to(Vertex u, Vertex v) { + BOOST_ASSERT(!is_closed_to(u, v)); + closed_[index_of(u)].push_back(v); + } + + + //! @internal Return whether a given vertex is blocked. + bool is_blocked(Vertex v) const { + return get(blocked_, v) == blocked_true_color(); + } + + //! @internal Block a given vertex. + void block(Vertex v) { + put(blocked_, v, blocked_true_color()); + } + + //! @internal Unblock a given vertex. + void unblock(Vertex u) { + typedef typename ClosedMatrix::reference VertexList; + + put(blocked_, u, blocked_false_color()); + VertexList closed_to_u = closed_[index_of(u)]; + + while (!closed_to_u.empty()) { + Vertex const w = closed_to_u.back(); + closed_to_u.pop_back(); + if (is_blocked(w)) + unblock(w); + } + BOOST_ASSERT(closed_to_u.empty()); + } + + //! @internal Main procedure as described in the paper. + bool circuit(Vertex start, Vertex v) { + bool found_circuit = false; + stack_.push_back(v); + block(v); + + // Cache some values that are used more than once in the function. + VertexIndex const index_of_start = index_of(start); + AdjacentVertices const adj_vertices = GetAdjacentVertices()(v, graph_); + AdjacencyIterator const w_end = boost::end(adj_vertices); + + for (AdjacencyIterator w_it = boost::begin(adj_vertices); + w_it != w_end; + ++w_it) + { + Vertex const w = *w_it; + // Since we're only looking in the subgraph induced by `start` + // and the vertices with an index higher than `start`, we skip + // any vertex that does not satisfy that. + if (index_of(w) < index_of_start) + continue; + + // If the last vertex is equal to `start`, we have a circuit. + else if (w == start) { + // const_cast to ensure the visitor does not modify the stack + visitor_.cycle(const_cast(stack_), graph_); + found_circuit = true; + } + + // If `w` is not blocked, we continue searching further down the + // same path for a cycle with `w` in it. + else if (!is_blocked(w) && circuit(start, w)) + found_circuit = true; + } + + if (found_circuit) + unblock(v); + else + for (AdjacencyIterator w_it = boost::begin(adj_vertices); + w_it != w_end; + ++w_it) + { + Vertex const w = *w_it; + // Like above, we skip vertices that are not in the subgraph + // we're considering. + if (index_of(w) < index_of_start) + continue; + + // If `v` is not closed to `w`, we make it so. + if (!is_closed_to(w, v)) + close_to(w, v); + } + + BOOST_ASSERT(v == stack_.back()); + stack_.pop_back(); + return found_circuit; + } + +public: + void operator()(Vertex start) { + circuit(start, start); + } + +private: + Graph const& graph_; + Visitor& visitor_; + VertexIndexMap const& vim_; + Stack& stack_; + ClosedMatrix& closed_; + BlockedMap blocked_; +}; + +template < + typename GetAdjacentVertices, + typename Graph, typename Visitor, typename VertexIndexMap +> +void call_hawick_circuits(Graph const& graph, + Visitor /* by value */ visitor, + VertexIndexMap const& vertex_index_map) { + typedef graph_traits Traits; + typedef typename Traits::vertex_descriptor Vertex; + typedef typename Traits::vertices_size_type VerticesSize; + typedef typename Traits::vertex_iterator VertexIterator; + + typedef std::vector Stack; + typedef std::vector > ClosedMatrix; + + typedef hawick_circuits_from< + Graph, Visitor, VertexIndexMap, Stack, ClosedMatrix, + GetAdjacentVertices + > SubAlgorithm; + + VerticesSize const n_vertices = num_vertices(graph); + Stack stack; stack.reserve(n_vertices); + ClosedMatrix closed(n_vertices); + + VertexIterator start, last; + for (boost::tie(start, last) = vertices(graph); start != last; ++start) { + // Note1: The sub algorithm may NOT be reused once it has been called. + + // Note2: We reuse the Stack and the ClosedMatrix (after clearing them) + // in each iteration to avoid redundant destruction and construction. + // It would be strictly equivalent to have these as member variables + // of the sub algorithm. + SubAlgorithm sub_algo(graph, visitor, vertex_index_map, + stack, closed, n_vertices); + sub_algo(*start); + stack.clear(); + typename ClosedMatrix::iterator row, last_row = closed.end(); + for (row = closed.begin(); row != last_row; ++row) + row->clear(); + } +} + +template +void call_hawick_circuits(Graph const& graph, BOOST_FWD_REF(Visitor) visitor) { + call_hawick_circuits( + graph, boost::forward(visitor), get(vertex_index, graph) + ); +} +} // end namespace hawick_circuits_detail + +//! Enumerate all the elementary circuits in a directed multigraph. +template +void hawick_circuits(BOOST_FWD_REF(Graph) graph, + BOOST_FWD_REF(Visitor) visitor, + BOOST_FWD_REF(VertexIndexMap) vertex_index_map) { + hawick_circuits_detail::call_hawick_circuits< + hawick_circuits_detail::get_all_adjacent_vertices + >( + boost::forward(graph), + boost::forward(visitor), + boost::forward(vertex_index_map) + ); +} + +template +void hawick_circuits(BOOST_FWD_REF(Graph) graph, + BOOST_FWD_REF(Visitor) visitor) { + hawick_circuits_detail::call_hawick_circuits< + hawick_circuits_detail::get_all_adjacent_vertices + >(boost::forward(graph), boost::forward(visitor)); +} + +/*! + * Same as `boost::hawick_circuits`, but duplicate circuits caused by parallel + * edges will not be considered. Each circuit will be considered only once. + */ +template +void hawick_unique_circuits(BOOST_FWD_REF(Graph) graph, + BOOST_FWD_REF(Visitor) visitor, + BOOST_FWD_REF(VertexIndexMap) vertex_index_map) { + hawick_circuits_detail::call_hawick_circuits< + hawick_circuits_detail::get_unique_adjacent_vertices + >( + boost::forward(graph), + boost::forward(visitor), + boost::forward(vertex_index_map) + ); +} + +template +void hawick_unique_circuits(BOOST_FWD_REF(Graph) graph, + BOOST_FWD_REF(Visitor) visitor) { + hawick_circuits_detail::call_hawick_circuits< + hawick_circuits_detail::get_unique_adjacent_vertices + >(boost::forward(graph), boost::forward(visitor)); +} +} // end namespace boost + +#endif // !BOOST_GRAPH_HAWICK_CIRCUITS_HPP diff --git a/include/boost/graph/is_straight_line_drawing.hpp b/include/boost/graph/is_straight_line_drawing.hpp index c471cde8..a4bd8ff5 100644 --- a/include/boost/graph/is_straight_line_drawing.hpp +++ b/include/boost/graph/is_straight_line_drawing.hpp @@ -106,11 +106,8 @@ namespace boost { typedef typename graph_traits::vertex_descriptor vertex_t; - typedef typename graph_traits::vertex_iterator vertex_iterator_t; typedef typename graph_traits::edge_descriptor edge_t; typedef typename graph_traits::edge_iterator edge_iterator_t; - typedef typename graph_traits::edges_size_type e_size_t; - typedef typename graph_traits::vertices_size_type v_size_t; typedef std::size_t x_coord_t; typedef std::size_t y_coord_t; diff --git a/include/boost/graph/king_ordering.hpp b/include/boost/graph/king_ordering.hpp index 9d9a438f..29e7ac97 100644 --- a/include/boost/graph/king_ordering.hpp +++ b/include/boost/graph/king_ordering.hpp @@ -37,7 +37,6 @@ namespace boost { typename graph_traits::out_edge_iterator ei, ei_end; Vertex v, w; - typedef typename std::deque::iterator iterator; typedef typename std::deque::reverse_iterator reverse_iterator; reverse_iterator rend = Qptr->rend()-index_begin; @@ -86,8 +85,6 @@ namespace boost { //this function replaces pop_heap, and tracks state information template void percolate_down(int offset){ - typedef typename std::deque::reverse_iterator reverse_iterator; - int heap_last = index_begin + offset; int heap_first = Qptr->size() - 1; @@ -267,7 +264,6 @@ namespace boost { return permutation; typedef typename boost::graph_traits::vertex_descriptor Vertex; - typedef typename boost::graph_traits::vertex_iterator VerIter; typedef typename property_traits::value_type ColorValue; typedef color_traits Color; @@ -302,7 +298,6 @@ namespace boost { if (has_no_vertices(G)) return permutation; - typedef out_degree_property_map DegreeMap; std::vector colors(num_vertices(G)); return king_ordering(G, permutation, make_iterator_property_map(&colors[0], index_map, diff --git a/include/boost/graph/kruskal_min_spanning_tree.hpp b/include/boost/graph/kruskal_min_spanning_tree.hpp index 4d0c7efc..b7e81577 100644 --- a/include/boost/graph/kruskal_min_spanning_tree.hpp +++ b/include/boost/graph/kruskal_min_spanning_tree.hpp @@ -102,7 +102,6 @@ namespace boost { { typedef typename graph_traits::vertices_size_type size_type; typedef typename graph_traits::vertex_descriptor vertex_t; - typedef typename property_map::type index_map_t; if (num_vertices(g) == 0) return; // Nothing to do in this case typename graph_traits::vertices_size_type n = num_vertices(g); diff --git a/include/boost/graph/maximum_adjacency_search.hpp b/include/boost/graph/maximum_adjacency_search.hpp index 58dc8695..e27a7a04 100644 --- a/include/boost/graph/maximum_adjacency_search.hpp +++ b/include/boost/graph/maximum_adjacency_search.hpp @@ -118,8 +118,6 @@ namespace boost { void maximum_adjacency_search(const Graph& g, WeightMap weights, MASVisitor vis, const typename boost::graph_traits::vertex_descriptor start, VertexAssignmentMap assignments, KeyedUpdatablePriorityQueue pq) { typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; - typedef typename boost::graph_traits::vertices_size_type vertices_size_type; - typedef typename boost::graph_traits::edge_descriptor edge_descriptor; typedef typename boost::property_traits::value_type weight_type; std::set assignedVertices; @@ -197,7 +195,7 @@ maximum_adjacency_search(const Graph& g, WeightMap weights, MASVisitor vis, cons typedef typename boost::graph_traits::edge_descriptor edge_descriptor; BOOST_CONCEPT_ASSERT((boost::Convertible::directed_category, boost::undirected_tag>)); BOOST_CONCEPT_ASSERT((boost::ReadablePropertyMapConcept)); - typedef typename boost::property_traits::value_type weight_type; + // typedef typename boost::property_traits::value_type weight_type; boost::function_requires< MASVisitorConcept >(); BOOST_CONCEPT_ASSERT((boost::ReadWritePropertyMapConcept)); BOOST_CONCEPT_ASSERT((boost::Convertible::value_type>)); diff --git a/include/boost/graph/mcgregor_common_subgraphs.hpp b/include/boost/graph/mcgregor_common_subgraphs.hpp index c46f7215..987a03bf 100644 --- a/include/boost/graph/mcgregor_common_subgraphs.hpp +++ b/include/boost/graph/mcgregor_common_subgraphs.hpp @@ -121,7 +121,6 @@ namespace boost { VertexEquivalencePredicate vertices_equivalent, bool only_connected_subgraphs) { - typedef typename graph_traits::vertex_descriptor VertexFirst; typedef typename graph_traits::vertex_descriptor VertexSecond; typedef typename graph_traits::edge_descriptor EdgeFirst; diff --git a/include/boost/graph/metric_tsp_approx.hpp b/include/boost/graph/metric_tsp_approx.hpp index dd0ff1d6..c8e7dba5 100644 --- a/include/boost/graph/metric_tsp_approx.hpp +++ b/include/boost/graph/metric_tsp_approx.hpp @@ -173,7 +173,6 @@ namespace boost // We build a custom graph in this algorithm. typedef adjacency_list MSTImpl; - typedef graph_traits::edge_descriptor Edge; typedef graph_traits::vertex_descriptor Vertex; typedef graph_traits::vertex_iterator VItr; diff --git a/include/boost/graph/named_function_params.hpp b/include/boost/graph/named_function_params.hpp index 4ab24f63..26d3d5e4 100644 --- a/include/boost/graph/named_function_params.hpp +++ b/include/boost/graph/named_function_params.hpp @@ -64,6 +64,7 @@ namespace boost { BOOST_BGL_ONE_PARAM_CREF(weight_map, edge_weight) \ BOOST_BGL_ONE_PARAM_CREF(weight_map2, edge_weight2) \ BOOST_BGL_ONE_PARAM_CREF(distance_map, vertex_distance) \ + BOOST_BGL_ONE_PARAM_CREF(distance_map2, vertex_distance2) \ BOOST_BGL_ONE_PARAM_CREF(predecessor_map, vertex_predecessor) \ BOOST_BGL_ONE_PARAM_CREF(rank_map, vertex_rank) \ BOOST_BGL_ONE_PARAM_CREF(root_map, vertex_root) \ diff --git a/include/boost/graph/planar_canonical_ordering.hpp b/include/boost/graph/planar_canonical_ordering.hpp index 86203aaf..d470ee59 100644 --- a/include/boost/graph/planar_canonical_ordering.hpp +++ b/include/boost/graph/planar_canonical_ordering.hpp @@ -41,10 +41,8 @@ namespace boost typedef typename graph_traits::vertex_descriptor vertex_t; typedef typename graph_traits::edge_descriptor edge_t; - typedef typename graph_traits::vertex_iterator vertex_iterator_t; typedef typename graph_traits::adjacency_iterator adjacency_iterator_t; - typedef typename std::pair vertex_pair_t; typedef typename property_traits::value_type embedding_value_t; typedef typename embedding_value_t::const_iterator embedding_iterator_t; diff --git a/include/boost/graph/r_c_shortest_paths.hpp b/include/boost/graph/r_c_shortest_paths.hpp index 28755d87..081393ee 100644 --- a/include/boost/graph/r_c_shortest_paths.hpp +++ b/include/boost/graph/r_c_shortest_paths.hpp @@ -185,7 +185,10 @@ void r_c_shortest_paths_dispatch pareto_optimal_resource_containers.clear(); pareto_optimal_solutions.clear(); - unsigned long i_label_num = 0; + typedef typename boost::graph_traits::vertices_size_type + vertices_size_type; + + size_t i_label_num = 0; typedef typename Label_Allocator::template rebind @@ -217,9 +220,9 @@ void r_c_shortest_paths_dispatch vec_vertex_labels[vertex_index_map[s]].push_back( splabel_first_label ); std::vector::iterator> vec_last_valid_positions_for_dominance( num_vertices( g ) ); - for( int i = 0; i < static_cast( num_vertices( g ) ); ++i ) + for( vertices_size_type i = 0; i < num_vertices( g ); ++i ) vec_last_valid_positions_for_dominance[i] = vec_vertex_labels[i].begin(); - std::vector vec_last_valid_index_for_dominance( num_vertices( g ), 0 ); + std::vector vec_last_valid_index_for_dominance( num_vertices( g ), 0 ); std::vector b_vec_vertex_already_checked_for_dominance( num_vertices( g ), false ); while( !unprocessed_labels.empty() && vis.on_enter_loop(unprocessed_labels, g) ) @@ -241,12 +244,12 @@ void r_c_shortest_paths_dispatch // if the label to be extended is undominated if( !cur_label->b_is_dominated ) { - int i_cur_resident_vertex_num = cur_label->resident_vertex; + vertices_size_type i_cur_resident_vertex_num = get(vertex_index_map, cur_label->resident_vertex); std::list& list_labels_cur_vertex = vec_vertex_labels[i_cur_resident_vertex_num]; - if( static_cast( list_labels_cur_vertex.size() ) >= 2 + if( list_labels_cur_vertex.size() >= 2 && vec_last_valid_index_for_dominance[i_cur_resident_vertex_num] - < static_cast( list_labels_cur_vertex.size() ) ) + < list_labels_cur_vertex.size() ) { typename std::list::iterator outer_iter = list_labels_cur_vertex.begin(); @@ -318,7 +321,7 @@ void r_c_shortest_paths_dispatch if( !b_outer_iter_erased ) ++outer_iter; } - if( static_cast( list_labels_cur_vertex.size() ) > 1 ) + if( list_labels_cur_vertex.size() > 1 ) vec_last_valid_positions_for_dominance[i_cur_resident_vertex_num] = (--(list_labels_cur_vertex.end())); else @@ -327,7 +330,7 @@ void r_c_shortest_paths_dispatch b_vec_vertex_already_checked_for_dominance [i_cur_resident_vertex_num] = true; vec_last_valid_index_for_dominance[i_cur_resident_vertex_num] = - static_cast( list_labels_cur_vertex.size() ) - 1; + list_labels_cur_vertex.size() - 1; } } if( !b_all_pareto_optimal_solutions && cur_label->resident_vertex == t ) @@ -430,8 +433,8 @@ void r_c_shortest_paths_dispatch } } - int i_size = static_cast( vec_vertex_labels.size() ); - for( int i = 0; i < i_size; ++i ) + size_t i_size = vec_vertex_labels.size(); + for( size_t i = 0; i < i_size; ++i ) { const std::list& list_labels_cur_vertex = vec_vertex_labels[i]; csi_end = list_labels_cur_vertex.end(); @@ -679,7 +682,7 @@ void check_r_c_path( const Graph& g, typename graph_traits::edge_descriptor& ed_last_extended_arc ) { - int i_size_ed_vec_path = static_cast( ed_vec_path.size() ); + size_t i_size_ed_vec_path = ed_vec_path.size(); std::vector::edge_descriptor> buf_path; if( i_size_ed_vec_path == 0 ) b_feasible = true; @@ -689,9 +692,9 @@ void check_r_c_path( const Graph& g, || target( ed_vec_path[0], g ) == source( ed_vec_path[1], g ) ) buf_path = ed_vec_path; else - for( int i = i_size_ed_vec_path - 1; i >= 0; --i ) - buf_path.push_back( ed_vec_path[i] ); - for( int i = 0; i < i_size_ed_vec_path - 1; ++i ) + for( size_t i = i_size_ed_vec_path ; i > 0; --i ) + buf_path.push_back( ed_vec_path[i - 1] ); + for( size_t i = 0; i < i_size_ed_vec_path - 1; ++i ) { if( target( buf_path[i], g ) != source( buf_path[i + 1], g ) ) { @@ -707,7 +710,7 @@ void check_r_c_path( const Graph& g, b_correctly_extended = false; Resource_Container current_resource_levels = initial_resource_levels; actual_final_resource_levels = current_resource_levels; - for( int i = 0; i < i_size_ed_vec_path; ++i ) + for( size_t i = 0; i < i_size_ed_vec_path; ++i ) { ed_last_extended_arc = buf_path[i]; b_feasible = ref( g, diff --git a/include/boost/graph/random.hpp b/include/boost/graph/random.hpp index f4001337..f0153b2c 100644 --- a/include/boost/graph/random.hpp +++ b/include/boost/graph/random.hpp @@ -86,8 +86,6 @@ namespace boost { template typename graph_traits::edge_descriptor weighted_random_out_edge(Graph& g, typename graph_traits::vertex_descriptor src, WeightMap weight, RandomNumGen& gen) { - typedef graph_traits gt; - typedef typename gt::vertex_descriptor vertex_descriptor; typedef typename property_traits::value_type weight_type; weight_type weight_sum(0); BGL_FORALL_OUTEDGES_T(src, e, g, Graph) {weight_sum += get(weight, e);} diff --git a/include/boost/graph/random_spanning_tree.hpp b/include/boost/graph/random_spanning_tree.hpp index 5ecd4f17..76dc7f2b 100644 --- a/include/boost/graph/random_spanning_tree.hpp +++ b/include/boost/graph/random_spanning_tree.hpp @@ -33,7 +33,6 @@ namespace boost { template void random_spanning_tree_internal(const Graph& g, typename graph_traits::vertex_descriptor s, PredMap pred, ColorMap color, NextEdge next_edge) { typedef typename graph_traits::vertex_descriptor vertex_descriptor; - typedef typename graph_traits::edge_descriptor edge_descriptor; BOOST_ASSERT (num_vertices(g) >= 1); // g must also be undirected (or symmetric) and connected diff --git a/include/boost/graph/read_dimacs.hpp b/include/boost/graph/read_dimacs.hpp index 06f1a335..0297744c 100644 --- a/include/boost/graph/read_dimacs.hpp +++ b/include/boost/graph/read_dimacs.hpp @@ -45,7 +45,6 @@ int read_dimacs_max_flow_internal(Graph& g, const int NODE_FIELDS = 2; /* no of fields in node line */ const int P_FIELDS = 3; /* no of fields in problem line */ - typedef typename graph_traits::vertices_size_type vertices_size_type; typedef typename graph_traits::vertex_descriptor vertex_descriptor; typedef typename graph_traits::edge_descriptor edge_descriptor; diff --git a/include/boost/graph/stoer_wagner_min_cut.hpp b/include/boost/graph/stoer_wagner_min_cut.hpp index a777f031..eb5998c7 100644 --- a/include/boost/graph/stoer_wagner_min_cut.hpp +++ b/include/boost/graph/stoer_wagner_min_cut.hpp @@ -76,7 +76,6 @@ namespace boost { template < typename Vertex, typename Graph > void finish_vertex(Vertex u, const Graph & g) { - typedef typename boost::property_traits::value_type parity_type; typedef typename boost::property_traits::value_type internal_parity_type; ++m_visited; @@ -131,10 +130,7 @@ namespace boost { typename boost::property_traits::value_type stoer_wagner_min_cut(const UndirectedGraph& g, WeightMap weights, ParityMap parities, VertexAssignmentMap assignments, KeyedUpdatablePriorityQueue& pq, IndexMap index_map) { typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; - typedef typename boost::graph_traits::vertices_size_type vertices_size_type; - typedef typename boost::graph_traits::edge_descriptor edge_descriptor; typedef typename boost::property_traits::value_type weight_type; - typedef typename boost::property_traits::value_type parity_type; typename graph_traits::vertex_iterator u_iter, u_end; @@ -185,9 +181,9 @@ namespace boost { typedef typename boost::graph_traits::edge_descriptor edge_descriptor; BOOST_CONCEPT_ASSERT((boost::Convertible::directed_category, boost::undirected_tag>)); BOOST_CONCEPT_ASSERT((boost::ReadablePropertyMapConcept)); - typedef typename boost::property_traits::value_type weight_type; + // typedef typename boost::property_traits::value_type weight_type; BOOST_CONCEPT_ASSERT((boost::WritablePropertyMapConcept)); - typedef typename boost::property_traits::value_type parity_type; + // typedef typename boost::property_traits::value_type parity_type; BOOST_CONCEPT_ASSERT((boost::ReadWritePropertyMapConcept)); BOOST_CONCEPT_ASSERT((boost::Convertible::value_type>)); BOOST_CONCEPT_ASSERT((boost::KeyedUpdatableQueueConcept)); diff --git a/include/boost/graph/successive_shortest_path_nonnegative_weights.hpp b/include/boost/graph/successive_shortest_path_nonnegative_weights.hpp new file mode 100644 index 00000000..72b1512c --- /dev/null +++ b/include/boost/graph/successive_shortest_path_nonnegative_weights.hpp @@ -0,0 +1,261 @@ +//======================================================================= +// Copyright 2013 University of Warsaw. +// Authors: Piotr Wygocki +// +// 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) +//======================================================================= +// +//This algorithm is described in "Network Flows: Theory, Algorithms, and Applications" +// by Ahuja, Magnanti, Orlin. + +#ifndef BOOST_GRAPH_SUCCESSIVE_SHORTEST_PATH_HPP +#define BOOST_GRAPH_SUCCESSIVE_SHORTEST_PATH_HPP + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { + + +namespace detail { + +template +class MapReducedWeight : + public put_get_helper::value_type, MapReducedWeight > { + typedef graph_traits gtraits; +public: + typedef boost::readable_property_map_tag category; + typedef typename property_traits::value_type value_type; + typedef value_type reference; + typedef typename gtraits::edge_descriptor key_type; + MapReducedWeight(const Graph & g, Weight w, Distance d, Reversed r) : + g_(g), weight_(w), distance_(d), rev_(r) {} + + reference operator[](key_type v) const { + return get(distance_, source(v, g_)) - get(distance_,target(v, g_)) + get(weight_, v); + } +private: + const Graph & g_; + Weight weight_; + Distance distance_; + Reversed rev_; +}; + +template +MapReducedWeight +make_mapReducedWeight(const Graph & g, Weight w, Distance d, Reversed r) { + return MapReducedWeight(g, w, d, r); +} + +}//detail + + +template +void successive_shortest_path_nonnegative_weights( + const Graph &g, + typename graph_traits::vertex_descriptor s, + typename graph_traits::vertex_descriptor t, + Capacity capacity, + ResidualCapacity residual_capacity, + Weight weight, + Reversed rev, + VertexIndex index, + Pred pred, + Distance distance, + Distance2 distance_prev) { + filtered_graph > + gres = detail::residual_graph(g, residual_capacity); + typedef typename graph_traits::edge_descriptor edge_descriptor; + + BGL_FORALL_EDGES_T(e, g, Graph) { + put(residual_capacity, e, get(capacity, e)); + } + + BGL_FORALL_VERTICES_T(v, g, Graph) { + put(distance_prev, v, 0); + } + + while(true) { + BGL_FORALL_VERTICES_T(v, g, Graph) { + put(pred, v, edge_descriptor()); + } + dijkstra_shortest_paths(gres, s, + weight_map(detail::make_mapReducedWeight(gres, weight, distance_prev, rev)). + distance_map(distance). + vertex_index_map(index). + visitor(make_dijkstra_visitor(record_edge_predecessors(pred, on_edge_relaxed())))); + + if(get(pred, t) == edge_descriptor()) { + break; + } + + BGL_FORALL_VERTICES_T(v, g, Graph) { + put(distance_prev, v, get(distance_prev, v) + get(distance, v)); + } + + detail::augment(g, s, t, pred, residual_capacity, rev); + } +} + +//in this namespace argument dispatching tak place +namespace detail { + +template +void successive_shortest_path_nonnegative_weights_dispatch3( + const Graph &g, + typename graph_traits::vertex_descriptor s, + typename graph_traits::vertex_descriptor t, + Capacity capacity, + ResidualCapacity residual_capacity, + Weight weight, + Reversed rev, + VertexIndex index, + Pred pred, + Distance dist, + Distance2 dist_pred) { + successive_shortest_path_nonnegative_weights(g, s, t, capacity, residual_capacity, weight, rev, index, pred, dist, dist_pred); +} + +//setting default distance map +template +void successive_shortest_path_nonnegative_weights_dispatch3( + Graph &g, + typename graph_traits::vertex_descriptor s, + typename graph_traits::vertex_descriptor t, + Capacity capacity, + ResidualCapacity residual_capacity, + Weight weight, + Reversed rev, + VertexIndex index, + Pred pred, + Distance dist, + param_not_found) { + typedef typename property_traits::value_type D; + + std::vector d_map(num_vertices(g)); + + successive_shortest_path_nonnegative_weights(g, s, t, capacity, residual_capacity, weight, rev, index, pred, dist, + make_iterator_property_map(d_map.begin(), index)); +} + +template +void successive_shortest_path_nonnegative_weights_dispatch2( + Graph &g, + typename graph_traits::vertex_descriptor s, + typename graph_traits::vertex_descriptor t, + Capacity capacity, + ResidualCapacity residual_capacity, + Weight weight, + Reversed rev, + VertexIndex index, + Pred pred, + Distance dist, + const bgl_named_params& params) { + successive_shortest_path_nonnegative_weights_dispatch3(g, s, t, capacity, residual_capacity, weight, rev, index, pred, dist, get_param(params, vertex_distance2)); +} + +//setting default distance map +template +void successive_shortest_path_nonnegative_weights_dispatch2( + Graph &g, + typename graph_traits::vertex_descriptor s, + typename graph_traits::vertex_descriptor t, + Capacity capacity, + ResidualCapacity residual_capacity, + Weight weight, + Reversed rev, + VertexIndex index, + Pred pred, + param_not_found, + const bgl_named_params& params) { + typedef typename property_traits::value_type D; + + std::vector d_map(num_vertices(g)); + + successive_shortest_path_nonnegative_weights_dispatch3(g, s, t, capacity, residual_capacity, weight, rev, index, pred, + make_iterator_property_map(d_map.begin(), index), + get_param(params, vertex_distance2)); +} + +template +void successive_shortest_path_nonnegative_weights_dispatch1( + Graph &g, + typename graph_traits::vertex_descriptor s, + typename graph_traits::vertex_descriptor t, + Capacity capacity, + ResidualCapacity residual_capacity, + Weight weight, + Reversed rev, + VertexIndex index, + Pred pred, + const bgl_named_params& params) { + successive_shortest_path_nonnegative_weights_dispatch2(g, s, t, capacity, residual_capacity, weight, rev, index, pred, + get_param(params, vertex_distance), params); +} + +//setting default predecessors map +template +void successive_shortest_path_nonnegative_weights_dispatch1( + Graph &g, + typename graph_traits::vertex_descriptor s, + typename graph_traits::vertex_descriptor t, + Capacity capacity, + ResidualCapacity residual_capacity, + Weight weight, + Reversed rev, + VertexIndex index, + param_not_found, + const bgl_named_params& params) { + typedef typename graph_traits::edge_descriptor edge_descriptor; + std::vector pred_vec(num_vertices(g)); + + successive_shortest_path_nonnegative_weights_dispatch2(g, s, t, capacity, residual_capacity, weight, rev, index, + make_iterator_property_map(pred_vec.begin(), index), + get_param(params, vertex_distance), params); +} + +}//detail + + +template +void successive_shortest_path_nonnegative_weights( + Graph &g, + typename graph_traits::vertex_descriptor s, + typename graph_traits::vertex_descriptor t, + const bgl_named_params& params) { + + return detail::successive_shortest_path_nonnegative_weights_dispatch1(g, s, t, + choose_const_pmap(get_param(params, edge_capacity), g, edge_capacity), + choose_pmap(get_param(params, edge_residual_capacity), + g, edge_residual_capacity), + choose_const_pmap(get_param(params, edge_weight), g, edge_weight), + choose_const_pmap(get_param(params, edge_reverse), g, edge_reverse), + choose_const_pmap(get_param(params, vertex_index), g, vertex_index), + get_param(params, vertex_predecessor), + params); +} + +template +void successive_shortest_path_nonnegative_weights( + Graph &g, + typename graph_traits::vertex_descriptor s, + typename graph_traits::vertex_descriptor t) { + bgl_named_params params(0); + successive_shortest_path_nonnegative_weights(g, s, t, params); +} + + +}//boost +#endif /* BOOST_GRAPH_SUCCESSIVE_SHORTEST_PATH_HPP */ + diff --git a/include/boost/graph/tiernan_all_cycles.hpp b/include/boost/graph/tiernan_all_cycles.hpp index 97ee89c4..d4527d55 100644 --- a/include/boost/graph/tiernan_all_cycles.hpp +++ b/include/boost/graph/tiernan_all_cycles.hpp @@ -212,7 +212,6 @@ namespace detail { BOOST_CONCEPT_ASSERT(( IncidenceGraphConcept )); typedef typename graph_traits::vertex_descriptor Vertex; - typedef typename graph_traits::edge_descriptor Edge; typedef typename graph_traits::out_edge_iterator OutIterator; // get the current vertex diff --git a/include/boost/graph/transitive_closure.hpp b/include/boost/graph/transitive_closure.hpp index 5ba0cab7..4f81349b 100644 --- a/include/boost/graph/transitive_closure.hpp +++ b/include/boost/graph/transitive_closure.hpp @@ -14,11 +14,11 @@ #include #include #include -#include #include #include #include #include +#include #include namespace boost @@ -71,7 +71,6 @@ namespace boost if (num_vertices(g) == 0) return; typedef typename graph_traits < Graph >::vertex_descriptor vertex; - typedef typename graph_traits < Graph >::edge_descriptor edge; typedef typename graph_traits < Graph >::vertex_iterator vertex_iterator; typedef typename property_traits < VertexIndexMap >::value_type size_type; typedef typename graph_traits < @@ -95,7 +94,7 @@ namespace boost std::vector < std::vector < vertex > >components; build_component_lists(g, num_scc, component_number, components); - typedef std::vector > CG_t; + typedef boost::adjacency_list CG_t; CG_t CG(num_scc); for (cg_vertex s = 0; s < components.size(); ++s) { std::vector < cg_vertex > adj; @@ -113,7 +112,10 @@ namespace boost std::unique(adj.begin(), adj.end()); if (di != adj.end()) adj.erase(di, adj.end()); - CG[s] = adj; + for (typename std::vector::const_iterator i = adj.begin(); + i != adj.end(); ++i) { + add_edge(s, *i, CG); + } } std::vector topo_order; @@ -126,15 +128,20 @@ namespace boost iter != topo_order.end(); ++iter) topo_number[*iter] = n++; - for (size_type i = 0; i < num_vertices(CG); ++i) - std::sort(CG[i].begin(), CG[i].end(), + std::vector > CG_vec(num_vertices(CG)); + for (size_type i = 0; i < num_vertices(CG); ++i) { + typedef typename boost::graph_traits::adjacency_iterator cg_adj_iter; + std::pair pr = adjacent_vertices(i, CG); + CG_vec[i].assign(pr.first, pr.second); + std::sort(CG_vec[i].begin(), CG_vec[i].end(), boost::bind(std::less(), boost::bind(detail::subscript(topo_number), _1), boost::bind(detail::subscript(topo_number), _2))); + } std::vector > chains; { - std::vector in_a_chain(num_vertices(CG)); + std::vector in_a_chain(CG_vec.size()); for (typename std::vector::iterator i = topo_order.begin(); i != topo_order.end(); ++i) { cg_vertex v = *i; @@ -144,12 +151,10 @@ namespace boost for (;;) { chain.push_back(v); in_a_chain[v] = true; - typename graph_traits::adjacency_iterator adj_first, adj_last; - boost::tie(adj_first, adj_last) = adjacent_vertices(v, CG); - typename graph_traits::adjacency_iterator next - = std::find_if(adj_first, adj_last, + typename std::vector::const_iterator next + = std::find_if(CG_vec[v].begin(), CG_vec[v].end(), std::not1(detail::subscript(in_a_chain))); - if (next != adj_last) + if (next != CG_vec[v].end()) v = *next; else break; // end of chain, dead-end @@ -158,8 +163,8 @@ namespace boost } } } - std::vector chain_number(num_vertices(CG)); - std::vector pos_in_chain(num_vertices(CG)); + std::vector chain_number(CG_vec.size()); + std::vector pos_in_chain(CG_vec.size()); for (size_type i = 0; i < chains.size(); ++i) for (size_type j = 0; j < chains[i].size(); ++j) { cg_vertex v = chains[i][j]; @@ -168,14 +173,14 @@ namespace boost } cg_vertex inf = (std::numeric_limits< cg_vertex >::max)(); - std::vector > successors(num_vertices(CG), + std::vector > successors(CG_vec.size(), std::vector (chains.size(), inf)); for (typename std::vector::reverse_iterator i = topo_order.rbegin(); i != topo_order.rend(); ++i) { cg_vertex u = *i; - typename graph_traits::adjacency_iterator adj, adj_last; - for (boost::tie(adj, adj_last) = adjacent_vertices(u, CG); + typename std::vector::const_iterator adj, adj_last; + for (adj = CG_vec[u].begin(), adj_last = CG_vec[u].end(); adj != adj_last; ++adj) { cg_vertex v = *adj; if (topo_number[v] < successors[u][chain_number[v]]) { @@ -188,32 +193,31 @@ namespace boost } } - for (size_type i = 0; i < CG.size(); ++i) - CG[i].clear(); - for (size_type i = 0; i < CG.size(); ++i) + for (size_type i = 0; i < CG_vec.size(); ++i) + CG_vec[i].clear(); + for (size_type i = 0; i < CG_vec.size(); ++i) for (size_type j = 0; j < chains.size(); ++j) { size_type topo_num = successors[i][j]; if (topo_num < inf) { cg_vertex v = topo_order[topo_num]; for (size_type k = pos_in_chain[v]; k < chains[j].size(); ++k) - CG[i].push_back(chains[j][k]); + CG_vec[i].push_back(chains[j][k]); } } // Add vertices to the transitive closure graph - typedef typename graph_traits < GraphTC >::vertex_descriptor tc_vertex; { vertex_iterator i, i_end; for (boost::tie(i, i_end) = vertices(g); i != i_end; ++i) g_to_tc_map[*i] = add_vertex(tc); } // Add edges between all the vertices in two adjacent SCCs - typename graph_traits::vertex_iterator si, si_end; - for (boost::tie(si, si_end) = vertices(CG); si != si_end; ++si) { - cg_vertex s = *si; - typename graph_traits::adjacency_iterator i, i_end; - for (boost::tie(i, i_end) = adjacent_vertices(s, CG); i != i_end; ++i) { + typename std::vector >::const_iterator si, si_end; + for (si = CG_vec.begin(), si_end = CG_vec.end(); si != si_end; ++si) { + cg_vertex s = si - CG_vec.begin(); + typename std::vector::const_iterator i, i_end; + for (i = CG_vec[s].begin(), i_end = CG_vec[s].end(); i != i_end; ++i) { cg_vertex t = *i; for (size_type k = 0; k < components[s].size(); ++k) for (size_type l = 0; l < components[t].size(); ++l) @@ -300,7 +304,6 @@ namespace boost template < typename G > void warshall_transitive_closure(G & g) { - typedef typename graph_traits < G >::vertex_descriptor vertex; typedef typename graph_traits < G >::vertex_iterator vertex_iterator; BOOST_CONCEPT_ASSERT(( AdjacencyMatrixConcept < G > )); @@ -326,7 +329,6 @@ namespace boost template < typename G > void warren_transitive_closure(G & g) { using namespace boost; - typedef typename graph_traits < G >::vertex_descriptor vertex; typedef typename graph_traits < G >::vertex_iterator vertex_iterator; BOOST_CONCEPT_ASSERT(( AdjacencyMatrixConcept < G > )); diff --git a/include/boost/graph/two_graphs_common_spanning_trees.hpp b/include/boost/graph/two_graphs_common_spanning_trees.hpp index 86d57ece..48f80df1 100644 --- a/include/boost/graph/two_graphs_common_spanning_trees.hpp +++ b/include/boost/graph/two_graphs_common_spanning_trees.hpp @@ -591,17 +591,11 @@ two_graphs_common_spanning_trees typedef typename GraphTraits::edges_size_type edges_size_type; typedef typename GraphTraits::edge_iterator edge_iterator; - typedef typename Seq::const_iterator seq_const_iterator; - typedef typename Seq::difference_type seq_diff_type; typedef typename Seq::value_type seq_value_type; typedef typename Seq::size_type seq_size_type; - typedef typename Seq::iterator seq_iterator; - typedef typename Order::const_iterator order_const_iterator; - typedef typename Order::difference_type order_diff_type; typedef typename Order::value_type order_value_type; typedef typename Order::size_type order_size_type; - typedef typename Order::iterator order_iterator; BOOST_STATIC_ASSERT((is_same::value)); BOOST_CONCEPT_ASSERT((Convertible)); @@ -846,7 +840,6 @@ two_graphs_common_spanning_trees typedef graph_traits GraphTraits; typedef typename GraphTraits::edge_descriptor edge_descriptor; - typedef typename GraphTraits::edges_size_type edges_size_type; typedef typename GraphTraits::edge_iterator edge_iterator; std::vector iGO, vGO; diff --git a/include/boost/graph/undirected_dfs.hpp b/include/boost/graph/undirected_dfs.hpp index a3e1c038..89cb10f2 100644 --- a/include/boost/graph/undirected_dfs.hpp +++ b/include/boost/graph/undirected_dfs.hpp @@ -46,18 +46,18 @@ namespace boost { typedef color_traits Color; typedef color_traits EColor; typedef typename graph_traits::out_edge_iterator Iter; - typedef std::pair > VertexInfo; + typedef std::pair, std::pair > > VertexInfo; std::vector stack; put(vertex_color, u, Color::gray()); vis.discover_vertex(u, g); - stack.push_back(std::make_pair(u, out_edges(u, g))); + stack.push_back(std::make_pair(u, std::make_pair(boost::optional(), out_edges(u, g)))); while (!stack.empty()) { VertexInfo& back = stack.back(); u = back.first; - Iter ei, ei_end; - boost::tie(ei, ei_end) = back.second; + boost::optional src_e = back.second.first; + Iter ei = back.second.second.first, ei_end = back.second.second.second; stack.pop_back(); while (ei != ei_end) { Vertex v = target(*ei, g); @@ -67,20 +67,24 @@ namespace boost { put(edge_color, *ei, EColor::black()); if (v_color == Color::white()) { vis.tree_edge(*ei, g); - stack.push_back(std::make_pair(u, std::make_pair(++ei, ei_end))); + src_e = *ei; + stack.push_back(std::make_pair(u, std::make_pair(src_e, std::make_pair(++ei, ei_end)))); u = v; put(vertex_color, u, Color::gray()); vis.discover_vertex(u, g); boost::tie(ei, ei_end) = out_edges(u, g); } else if (v_color == Color::gray()) { if (uv_color == EColor::white()) vis.back_edge(*ei, g); + call_finish_edge(vis, *ei, g); ++ei; } else { // if (v_color == Color::black()) + call_finish_edge(vis, *ei, g); ++ei; } } put(vertex_color, u, Color::black()); vis.finish_vertex(u, g); + if (src_e) call_finish_edge(vis, src_e.get(), g); } } @@ -119,6 +123,7 @@ namespace boost { undir_dfv_impl(g, v, vis, vertex_color, edge_color); } else if (v_color == Color::gray() && uv_color == EColor::white()) vis.back_edge(*ei, g); + call_finish_edge(vis, *ei, g); } put(vertex_color, u, Color::black()); vis.finish_vertex(u, g); } diff --git a/include/boost/graph/vf2_sub_graph_iso.hpp b/include/boost/graph/vf2_sub_graph_iso.hpp index a316f781..21011b51 100755 --- a/include/boost/graph/vf2_sub_graph_iso.hpp +++ b/include/boost/graph/vf2_sub_graph_iso.hpp @@ -1014,8 +1014,6 @@ namespace boost { bool vf2_subgraph_iso(const GraphSmall& graph_small, const GraphLarge& graph_large, SubGraphIsoMapCallback user_callback) { - typedef typename graph_traits::vertex_descriptor vertex_small_type; - return vf2_subgraph_iso(graph_small, graph_large, user_callback, get(vertex_index, graph_small), get(vertex_index, graph_large), vertex_order_by_mult(graph_small), @@ -1144,8 +1142,6 @@ namespace boost { bool vf2_graph_iso(const Graph1& graph1, const Graph2& graph2, GraphIsoMapCallback user_callback) { - typedef typename graph_traits::vertex_descriptor vertex1_type; - return vf2_graph_iso(graph1, graph2, user_callback, get(vertex_index, graph1), get(vertex_index, graph2), vertex_order_by_mult(graph1), diff --git a/include/boost/graph/visitors.hpp b/include/boost/graph/visitors.hpp index d10e140c..e4a614f3 100644 --- a/include/boost/graph/visitors.hpp +++ b/include/boost/graph/visitors.hpp @@ -44,7 +44,7 @@ namespace boost { on_discover_vertex_num, on_finish_vertex_num, on_examine_vertex_num, on_examine_edge_num, on_tree_edge_num, on_non_tree_edge_num, on_gray_target_num, on_black_target_num, - on_forward_or_cross_edge_num, on_back_edge_num, + on_forward_or_cross_edge_num, on_back_edge_num, on_finish_edge_num, on_edge_relaxed_num, on_edge_not_relaxed_num, on_edge_minimized_num, on_edge_not_minimized_num }; @@ -75,6 +75,7 @@ namespace boost { struct on_forward_or_cross_edge { enum { num = detail::on_forward_or_cross_edge_num }; }; struct on_back_edge { enum { num = detail::on_back_edge_num }; }; + struct on_finish_edge { enum { num = detail::on_finish_edge_num }; }; struct on_edge_relaxed { enum { num = detail::on_edge_relaxed_num }; }; struct on_edge_not_relaxed { diff --git a/include/boost/graph/write_dimacs.hpp b/include/boost/graph/write_dimacs.hpp index a9a89046..a4a57773 100644 --- a/include/boost/graph/write_dimacs.hpp +++ b/include/boost/graph/write_dimacs.hpp @@ -51,10 +51,6 @@ void write_dimacs_max_flow(const Graph& g, typename graph_traits::vertex_descriptor sink, std::ostream& out) { - typedef typename graph_traits::vertex_descriptor vertex_descriptor; - typedef typename graph_traits::vertices_size_type vertices_size_type; - typedef typename graph_traits::edge_descriptor edge_descriptor; - typedef typename graph_traits::edges_size_type edges_size_type; typedef typename graph_traits::edge_iterator edge_iterator; out << "c DIMACS max-flow file generated from boost::write_dimacs_max_flow" << std::endl; diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index fe0b4849..a41d2336 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -43,6 +43,7 @@ test-suite graph_test : [ run csr_graph_test.cpp : : : : : release ] [ run dag_longest_paths.cpp ] [ run dfs.cpp ../../test/build//boost_test_exec_monitor ] + [ run undirected_dfs.cpp ../../test/build//boost_test_exec_monitor ] [ compile dfs_cc.cpp ] [ compile dijkstra_cc.cpp ] [ run dijkstra_heap_performance.cpp : 10000 ] @@ -103,6 +104,7 @@ test-suite graph_test : ../../system/build : $(PLANAR_INPUT_FILES) ] [ run r_c_shortest_paths_test.cpp ] + [ run rcsp_custom_vertex_id.cpp ] [ run is_straight_line_draw_test.cpp ] [ run metric_tsp_approx.cpp : metric_tsp_approx.graph ] [ compile dimacs.cpp ] @@ -126,6 +128,9 @@ test-suite graph_test : [ run stoer_wagner_test.cpp ../../test/build//boost_unit_test_framework/static : $(TEST_DIR) ] [ compile filtered_graph_properties_dijkstra.cpp ] [ run vf2_sub_graph_iso_test.cpp ] + [ run hawick_circuits.cpp ] + [ run successive_shortest_path_nonnegative_weights_test.cpp ../../test/build//boost_unit_test_framework/static ] + [ run cycle_canceling_test.cpp ../../test/build//boost_unit_test_framework/static ] ; # Run SDB tests only when -sSDB= is set. diff --git a/test/adj_list_loops.cpp b/test/adj_list_loops.cpp index 205f3730..cd7b0896 100644 --- a/test/adj_list_loops.cpp +++ b/test/adj_list_loops.cpp @@ -17,7 +17,6 @@ template void test_graph_nonloop() { typedef typename graph_traits::vertex_descriptor Vertex; - typedef typename graph_traits::edge_descriptor Edge; // Build a graph with 1 edge and turn it into a loop. Graph g(5); @@ -36,7 +35,6 @@ template void test_multigraph_nonloop() { typedef typename graph_traits::vertex_descriptor Vertex; - typedef typename graph_traits::edge_descriptor Edge; // Build a graph with 1 edge and turn it into a loop. Graph g(5); @@ -55,7 +53,6 @@ template void test_graph_loop() { typedef typename graph_traits::vertex_descriptor Vertex; - typedef typename graph_traits::edge_descriptor Edge; Graph g(5); Vertex v = *next(vertices(g).first, 2); @@ -70,7 +67,6 @@ template void test_multigraph_loop() { typedef typename graph_traits::vertex_descriptor Vertex; - typedef typename graph_traits::edge_descriptor Edge; Graph g(5); Vertex v = *next(vertices(g).first, 2); diff --git a/test/all_planar_input_files_test.cpp b/test/all_planar_input_files_test.cpp index 5fec2e36..e918f1f8 100644 --- a/test/all_planar_input_files_test.cpp +++ b/test/all_planar_input_files_test.cpp @@ -122,9 +122,7 @@ int test_graph(const std::string& dimacs_filename) typedef graph_traits::edge_iterator edge_iterator_t; typedef graph_traits::vertex_iterator vertex_iterator_t; typedef graph_traits::edges_size_type e_size_t; - typedef graph_traits::vertices_size_type v_size_t; typedef graph_traits::vertex_descriptor vertex_t; - typedef std::pair vertex_pair_t; typedef edge_index_update_visitor::type> edge_visitor_t; diff --git a/test/astar_search_test.cpp b/test/astar_search_test.cpp index d72b91f0..72f29150 100644 --- a/test/astar_search_test.cpp +++ b/test/astar_search_test.cpp @@ -122,7 +122,6 @@ int main(int, char **) typedef property_map::type WeightMap; typedef mygraph_t::vertex_descriptor vertex; typedef mygraph_t::edge_descriptor edge_descriptor; - typedef mygraph_t::vertex_iterator vertex_iterator; typedef std::pair edge; // specify data @@ -185,13 +184,18 @@ int main(int, char **) vector p(num_vertices(g)); vector d(num_vertices(g)); + + boost::property_map::const_type + idx = get(boost::vertex_index, g); + try { // call astar named parameter interface astar_search (g, start, distance_heuristic (locations, goal), - predecessor_map(&p[0]).distance_map(&d[0]). + predecessor_map(make_iterator_property_map(p.begin(), idx)). + distance_map(make_iterator_property_map(d.begin(), idx)). visitor(astar_goal_visitor(goal)).distance_inf(my_float((std::numeric_limits::max)()))); diff --git a/test/bellman-test.cpp b/test/bellman-test.cpp index 7fa948aa..a285b31d 100644 --- a/test/bellman-test.cpp +++ b/test/bellman-test.cpp @@ -56,8 +56,8 @@ int test_main(int, char*[]) bool const r = bellman_ford_shortest_paths (g, int (numVertex), weight_pmap, - &parent[0], - &distance[0], + boost::make_iterator_property_map(parent.begin(), get(boost::vertex_index, g)), + boost::make_iterator_property_map(distance.begin(), get(boost::vertex_index, g)), closed_plus(), std::less(), default_bellman_visitor()); @@ -81,8 +81,10 @@ int test_main(int, char*[]) std::vector distance2(numVertex, 17); bool const r2 = bellman_ford_shortest_paths (g, - weight_map(weight_pmap).distance_map(&distance2[0]). - predecessor_map(&parent2[0]).root_vertex(s)); + weight_map(weight_pmap). + distance_map(boost::make_iterator_property_map(distance2.begin(), get(boost::vertex_index, g))). + predecessor_map(boost::make_iterator_property_map(parent2.begin(), get(boost::vertex_index, g))). + root_vertex(s)); if (r2) { for(int i = 0; i < numVertex; ++i) { std::cout << name[i] << ": "; diff --git a/test/bfs.cpp b/test/bfs.cpp index 7e59ac9b..615999a9 100644 --- a/test/bfs.cpp +++ b/test/bfs.cpp @@ -140,20 +140,38 @@ struct bfs_test parent[*ui] = *ui; std::vector color(i); + // Get vertex index map + typedef typename boost::property_map::const_type idx_type; + idx_type idx = get(boost::vertex_index, g); + + // Make property maps from vectors + typedef + boost::iterator_property_map::iterator, idx_type> + distance_pm_type; + distance_pm_type distance_pm(distance.begin(), idx); + typedef + boost::iterator_property_map::iterator, idx_type> + parent_pm_type; + parent_pm_type parent_pm(parent.begin(), idx); + typedef + boost::iterator_property_map::iterator, idx_type> + color_pm_type; + color_pm_type color_pm(color.begin(), idx); + // Create the testing visitor. - bfs_testing_visitor - vis(start, &distance[0], &parent[0], &color[0]); + bfs_testing_visitor + vis(start, distance_pm, parent_pm, color_pm); boost::breadth_first_search(g, start, visitor(vis). - color_map(&color[0])); + color_map(color_pm)); // All white vertices should be unreachable from the source. for (boost::tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui) if (color[*ui] == Color::white()) { std::vector color2(i, Color::white()); - BOOST_CHECK(!boost::is_reachable(start, *ui, g, &color2[0])); + BOOST_CHECK(!boost::is_reachable(start, *ui, g, color_pm_type(color2.begin(), idx))); } // The shortest path to a child should be one longer than diff --git a/test/boykov_kolmogorov_max_flow_test.cpp b/test/boykov_kolmogorov_max_flow_test.cpp index 17607fce..1f0ce589 100644 --- a/test/boykov_kolmogorov_max_flow_test.cpp +++ b/test/boykov_kolmogorov_max_flow_test.cpp @@ -218,7 +218,8 @@ long test_overloads(int n_verts, int n_edges, std::size_t seed){ get(edge_capacity,g), get(edge_residual_capacity,g), get(edge_reverse,g), - &(color_vec[0]), + boost::make_iterator_property_map( + color_vec.begin(), get(vertex_index, g)), get(vertex_index,g), src, sink); diff --git a/test/closeness_centrality.cpp b/test/closeness_centrality.cpp index 5fd16b9c..62b65de1 100644 --- a/test/closeness_centrality.cpp +++ b/test/closeness_centrality.cpp @@ -31,8 +31,6 @@ template void build_graph(Graph& g, typename vertex_vector::type& v) { - typedef typename graph_traits::vertex_descriptor Vertex; - // add vertices for(size_t i = 0; i < N; ++i) { v[i] = add_vertex(g); diff --git a/test/clustering_coefficient.cpp b/test/clustering_coefficient.cpp index 21eee890..a4de0417 100644 --- a/test/clustering_coefficient.cpp +++ b/test/clustering_coefficient.cpp @@ -27,8 +27,6 @@ struct vertex_vector template void build_graph(Graph& g, typename vertex_vector::type& v) { - typedef typename graph_traits::vertex_descriptor Vertex; - // add vertices for(size_t i = 0; i < N; ++i) { v[i] = add_vertex(g); @@ -98,7 +96,7 @@ int main(int, char *[]) { typedef undirected_graph<> Graph; - typedef directed_graph<> Digraph; + // typedef directed_graph<> Digraph; // TODO: write a test for directed clustering coefficient. diff --git a/test/cycle_canceling_test.cpp b/test/cycle_canceling_test.cpp new file mode 100644 index 00000000..d2acc802 --- /dev/null +++ b/test/cycle_canceling_test.cpp @@ -0,0 +1,63 @@ +//======================================================================= +// Copyright 2013 University of Warsaw. +// Authors: Piotr Wygocki +// +// 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) +//======================================================================= + +#define BOOST_TEST_MODULE cycle_canceling_test + +#include + +#include +#include + +#include "min_cost_max_flow_utils.hpp" + + +BOOST_AUTO_TEST_CASE(cycle_canceling_def_test) { + boost::SampleGraph::vertex_descriptor s,t; + boost::SampleGraph::Graph g; + boost::SampleGraph::getSampleGraph(g, s, t); + + boost::edmonds_karp_max_flow(g, s, t); + boost::cycle_canceling(g); + + int cost = boost::find_flow_cost(g); + BOOST_CHECK_EQUAL(cost, 29); +} + +BOOST_AUTO_TEST_CASE(path_augmentation_def_test2) { + boost::SampleGraph::vertex_descriptor s,t; + boost::SampleGraph::Graph g; + boost::SampleGraph::getSampleGraph2(g, s, t); + + boost::edmonds_karp_max_flow(g, s, t); + boost::cycle_canceling(g); + + int cost = boost::find_flow_cost(g); + BOOST_CHECK_EQUAL(cost, 7); +} + +BOOST_AUTO_TEST_CASE(cycle_canceling_test) { + boost::SampleGraph::vertex_descriptor s,t; + typedef boost::SampleGraph::Graph Graph; + boost::SampleGraph::Graph g; + boost::SampleGraph::getSampleGraph(g, s, t); + + int N = num_vertices(g); + std::vector dist(N); + typedef boost::graph_traits::edge_descriptor edge_descriptor; + std::vector pred(N); + + boost::property_map::const_type idx = get(boost::vertex_index, g); + + boost::edmonds_karp_max_flow(g, s, t); + boost::cycle_canceling(g, boost::distance_map(boost::make_iterator_property_map(dist.begin(), idx)).predecessor_map(boost::make_iterator_property_map(pred.begin(), idx)).vertex_index_map(idx)); + + int cost = boost::find_flow_cost(g); + BOOST_CHECK_EQUAL(cost, 29); +} + diff --git a/test/cycle_ratio_tests.cpp b/test/cycle_ratio_tests.cpp index ac5f208f..5448c87b 100644 --- a/test/cycle_ratio_tests.cpp +++ b/test/cycle_ratio_tests.cpp @@ -331,7 +331,6 @@ int test_main(int argc, char* argv[]) { GraphMInt gm(10); typedef graph_traits::vertex_iterator VertexItM; - typedef graph_traits::edge_descriptor EdgeM; VertexItM vi1, vi2, vi_end; for (boost::tie(vi1, vi_end) = vertices(gm); vi1 != vi_end; ++vi1) { diff --git a/test/cycle_test.hpp b/test/cycle_test.hpp new file mode 100644 index 00000000..53704473 --- /dev/null +++ b/test/cycle_test.hpp @@ -0,0 +1,80 @@ +// (C) Copyright 2013 Louis Dionne +// +// Modified from `tiernan_all_cycles.cpp`. +// +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0 (See accompanying file +// LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_GRAPH_TEST_CYCLE_TEST_HPP +#define BOOST_GRAPH_TEST_CYCLE_TEST_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +namespace cycle_test_detail { + using namespace boost; + + struct cycle_validator { + explicit cycle_validator(std::size_t& number_of_cycles) + : cycles(number_of_cycles) + { } + + template + void cycle(Path const& p, Graph const& g) { + ++cycles; + // Check to make sure that each of the vertices in the path + // is truly connected and that the back is connected to the + // front - it's not validating that we find all paths, just + // that the paths are valid. + typename Path::const_iterator i, j, last = prior(p.end()); + for (i = p.begin(); i != last; ++i) { + j = boost::next(i); + BOOST_ASSERT(edge(*i, *j, g).second); + } + BOOST_ASSERT(edge(p.back(), p.front(), g).second); + } + + std::size_t& cycles; + }; + + template + void test_one(Algorithm algorithm) { + typedef erdos_renyi_iterator er; + + // Generate random graphs with 15 vertices and 15% probability + // of edge connection. + static std::size_t const N = 20; + static double const P = 0.1; + minstd_rand rng; + + Graph g(er(rng, N, P), er(), N); + renumber_indices(g); + print_edges(g, get(vertex_index, g)); + + std::size_t cycles = 0; + cycle_validator vis(cycles); + algorithm(g, vis); + std::cout << "# cycles: " << vis.cycles << "\n"; + } +} // end namespace cycle_test_detail + +template +void cycle_test(Algorithm const& algorithm) { + std::cout << "*** undirected ***\n"; + cycle_test_detail::test_one >(algorithm); + + std::cout << "*** directed ***\n"; + cycle_test_detail::test_one >(algorithm); +} + +#endif // !BOOST_GRAPH_TEST_CYCLE_TEST_HPP diff --git a/test/degree_centrality.cpp b/test/degree_centrality.cpp index bb6e6b39..42adb5b1 100644 --- a/test/degree_centrality.cpp +++ b/test/degree_centrality.cpp @@ -22,8 +22,6 @@ template void build_graph(Graph& g, vector::vertex_descriptor>& v) { - typedef typename graph_traits::vertex_descriptor Vertex; - // add vertices for(size_t i = 0; i < N; ++i) { v[i] = add_vertex(g); diff --git a/test/dfs.cpp b/test/dfs.cpp index fdffd4ef..d958ba44 100644 --- a/test/dfs.cpp +++ b/test/dfs.cpp @@ -68,6 +68,12 @@ public: using namespace boost; BOOST_CHECK( get(m_color, target(e, g)) == Color::black() ); } + template + void finish_edge(Edge e, Graph& g) { + using namespace boost; + BOOST_CHECK( get(m_color, target(e, g)) == Color::gray() || + get(m_color, target(e, g)) == Color::black() ); + } template void finish_vertex(Vertex u, Graph&) { using namespace boost; @@ -116,9 +122,24 @@ struct dfs_test std::vector discover_time(num_vertices(g)), finish_time(num_vertices(g)); - dfs_test_visitor vis(color, &parent[0], - &discover_time[0], &finish_time[0]); + // Get vertex index map + typedef typename boost::property_map::const_type idx_type; + idx_type idx = get(boost::vertex_index, g); + + typedef + boost::iterator_property_map::iterator, idx_type> + parent_pm_type; + parent_pm_type parent_pm(parent.begin(), idx); + typedef + boost::iterator_property_map::iterator, idx_type> + time_pm_type; + time_pm_type discover_time_pm(discover_time.begin(), idx); + time_pm_type finish_time_pm(finish_time.begin(), idx); + + dfs_test_visitor + vis(color, parent_pm, + discover_time_pm, finish_time_pm); boost::depth_first_search(g, visitor(vis).color_map(color)); @@ -136,10 +157,10 @@ struct dfs_test || finish_time[v] < discover_time[u] || (discover_time[v] < discover_time[u] && finish_time[u] < finish_time[v] - && boost::is_descendant(u, v, &parent[0])) + && boost::is_descendant(u, v, parent_pm)) || (discover_time[u] < discover_time[v] && finish_time[v] < finish_time[u] - && boost::is_descendant(v, u, &parent[0])) + && boost::is_descendant(v, u, parent_pm)) ); } } diff --git a/test/dijkstra_heap_performance.cpp b/test/dijkstra_heap_performance.cpp index 72d40f9c..2cab3fbf 100644 --- a/test/dijkstra_heap_performance.cpp +++ b/test/dijkstra_heap_performance.cpp @@ -117,7 +117,9 @@ int main(int argc, char* argv[]) dijkstra_relaxed_heap = false; #endif dijkstra_shortest_paths(g, vertex(0, g), - distance_map(&binary_heap_distances[0])); + distance_map( + boost::make_iterator_property_map( + binary_heap_distances.begin(), get(boost::vertex_index, g)))); double binary_heap_time = t.elapsed(); std::cout << binary_heap_time << " seconds.\n"; @@ -135,7 +137,9 @@ int main(int argc, char* argv[]) dijkstra_relaxed_heap = true; #endif dijkstra_shortest_paths(g, vertex(0, g), - distance_map(&relaxed_heap_distances[0])); + distance_map( + boost::make_iterator_property_map( + relaxed_heap_distances.begin(), get(boost::vertex_index, g)))); double relaxed_heap_time = t.elapsed(); std::cout << relaxed_heap_time << " seconds.\n" << "Speedup = " << (binary_heap_time / relaxed_heap_time) << ".\n"; @@ -159,7 +163,7 @@ int main(int argc, char* argv[]) dijkstra_shortest_paths_no_color_map (g, vertex(0, g), boost::dummy_property_map(), - boost::make_iterator_property_map(&no_color_map_distances[0], + boost::make_iterator_property_map(no_color_map_distances.begin(), get(boost::vertex_index, g), 0.), get(boost::edge_weight, g), diff --git a/test/dijkstra_no_color_map_compare.cpp b/test/dijkstra_no_color_map_compare.cpp index 5ff18c1c..739b899e 100644 --- a/test/dijkstra_no_color_map_compare.cpp +++ b/test/dijkstra_no_color_map_compare.cpp @@ -94,9 +94,6 @@ int test_main(int argc, char* argv[]) property, property > graph_t; - typedef graph_traits::vertex_descriptor vertex_t; - typedef graph_traits::edge_descriptor edge_t; - graph_t graph; generate_random_graph(graph, vertices_to_create, edges_to_create, generator); diff --git a/test/eccentricity.cpp b/test/eccentricity.cpp index 596f38ef..2c04c7d6 100644 --- a/test/eccentricity.cpp +++ b/test/eccentricity.cpp @@ -31,8 +31,6 @@ template void build_graph(Graph& g, typename vertex_vector::type& v) { - typedef typename graph_traits::vertex_descriptor Vertex; - // add vertices for(size_t i = 0; i < N; ++i) { v[i] = add_vertex(g); diff --git a/test/graphviz_test.cpp b/test/graphviz_test.cpp index adc29034..94f200a0 100644 --- a/test/graphviz_test.cpp +++ b/test/graphviz_test.cpp @@ -75,9 +75,6 @@ bool test_graph(std::istream& dotfile, graph_t& graph, MassMap mass, WeightMap weight) { - typedef typename graph_traits < graph_t >::edge_descriptor edge_t; - typedef typename graph_traits < graph_t >::vertex_descriptor vertex_t; - // Construct a graph and set up the dynamic_property_maps. dynamic_properties dp(ignore_other_properties); dp.property(node_id,name); diff --git a/test/hawick_circuits.cpp b/test/hawick_circuits.cpp new file mode 100644 index 00000000..29b6470b --- /dev/null +++ b/test/hawick_circuits.cpp @@ -0,0 +1,32 @@ +// (C) Copyright 2013 Louis Dionne +// +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0 (See accompanying file +// LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + +#include "cycle_test.hpp" +#include +#include + + +struct call_hawick_circuits { + template + void operator()(Graph const& g, Visitor const& v) const { + boost::hawick_circuits(g, v); + } +}; + +struct call_hawick_unique_circuits { + template + void operator()(Graph const& g, Visitor const& v) const { + boost::hawick_unique_circuits(g, v); + } +}; + +int main() { + std::cout << "---------hawick_circuits---------\n"; + cycle_test(call_hawick_circuits()); + + std::cout << "\n\n---------hawick_unique_circuits---------\n"; + cycle_test(call_hawick_unique_circuits()); +} diff --git a/test/index_graph.cpp b/test/index_graph.cpp index 3e757e82..aaa7958b 100644 --- a/test/index_graph.cpp +++ b/test/index_graph.cpp @@ -64,7 +64,6 @@ void test() template void build() { - typedef typename graph_traits::vertex_descriptor Vertex; typedef typename graph_traits::vertex_iterator Iterator; typedef typename property_map::type IndexMap; diff --git a/test/layout_test.cpp b/test/layout_test.cpp index 7f85614a..4bf9e705 100644 --- a/test/layout_test.cpp +++ b/test/layout_test.cpp @@ -78,10 +78,8 @@ template void test_circle_layout(Graph*, typename graph_traits::vertices_size_type n) { - typedef typename graph_traits::vertex_descriptor vertex; typedef typename graph_traits::vertex_iterator vertex_iterator; typedef typename graph_traits::vertices_size_type vertices_size_type; - typedef typename graph_traits::edges_size_type edges_size_type; Graph g(n); diff --git a/test/make_connected_test.cpp b/test/make_connected_test.cpp index 40517f0f..bc4a9104 100644 --- a/test/make_connected_test.cpp +++ b/test/make_connected_test.cpp @@ -114,10 +114,14 @@ int test_main(int, char* []) make_disconnected_cycles(gVV, num_cycles, cycle_size); reset_edge_index(gVV); std::vector gVV_components(num_vertices(gVV)); - BOOST_CHECK(connected_components(gVV, &gVV_components[0]) == + boost::iterator_property_map< + std::vector::iterator, + typename boost::property_map::const_type + > gVV_components_pm(gVV_components.begin(), get(boost::vertex_index, gVV)); + BOOST_CHECK(connected_components(gVV, gVV_components_pm) == static_cast(num_cycles)); make_connected(gVV); - BOOST_CHECK(connected_components(gVV, &gVV_components[0]) == 1); + BOOST_CHECK(connected_components(gVV, gVV_components_pm) == 1); BOOST_CHECK(num_edges(gVV) == num_cycles * cycle_size + num_cycles - 1); LVgraph_t gLV; @@ -126,10 +130,14 @@ int test_main(int, char* []) make_disconnected_cycles(gLV, num_cycles, cycle_size); reset_edge_index(gLV); std::vector gLV_components(num_vertices(gLV)); - BOOST_CHECK(connected_components(gLV, &gLV_components[0]) == + boost::iterator_property_map< + std::vector::iterator, + typename boost::property_map::const_type + > gLV_components_pm(gLV_components.begin(), get(boost::vertex_index, gLV)); + BOOST_CHECK(connected_components(gLV, gLV_components_pm) == static_cast(num_cycles)); make_connected(gLV); - BOOST_CHECK(connected_components(gLV, &gLV_components[0]) == 1); + BOOST_CHECK(connected_components(gLV, gLV_components_pm) == 1); BOOST_CHECK(num_edges(gLV) == num_cycles * cycle_size + num_cycles - 1); VLgraph_t gVL; diff --git a/test/matching_test.cpp b/test/matching_test.cpp index 784fca58..f1526965 100644 --- a/test/matching_test.cpp +++ b/test/matching_test.cpp @@ -131,7 +131,6 @@ void matching_test(std::size_t num_v, const std::string& graph_name) typedef vector_property_map< typename graph_traits::vertex_descriptor, vertex_index_map_t > mate_t; typedef typename graph_traits::vertex_iterator vertex_iterator_t; typedef typename graph_traits::vertex_descriptor vertex_descriptor_t; - typedef typename graph_traits::vertices_size_type v_size_t; const std::size_t double_num_v = num_v * 2; diff --git a/test/mcgregor_subgraphs_test.cpp b/test/mcgregor_subgraphs_test.cpp index 516a32aa..96cf4fa0 100644 --- a/test/mcgregor_subgraphs_test.cpp +++ b/test/mcgregor_subgraphs_test.cpp @@ -195,10 +195,6 @@ struct simple_callback { typedef typename boost::graph_traits::vertex_descriptor Vertex; - typedef typename boost::property_map::type VertexIndexMap; - typedef typename boost::property_map::type VertexNameMap; - typedef typename boost::property_map::type EdgeNameMap; - std::stringstream subgraph_string; BGL_FORALL_VERTICES_T(vertex1, m_graph1, Graph) { @@ -308,9 +304,6 @@ int test_main (int argc, char *argv[]) { boost::property >, boost::property > Graph; - typedef boost::graph_traits::vertex_descriptor Vertex; - typedef boost::graph_traits::edge_descriptor Edge; - typedef boost::property_map::type VertexNameMap; typedef boost::property_map::type EdgeNameMap; diff --git a/test/mean_geodesic.cpp b/test/mean_geodesic.cpp index c5b0f91f..d78f677d 100644 --- a/test/mean_geodesic.cpp +++ b/test/mean_geodesic.cpp @@ -31,8 +31,6 @@ struct vertex_vector template void build_graph(Graph& g, typename vertex_vector::type& v) { - typedef typename graph_traits::vertex_descriptor Vertex; - // add vertices for(size_t i = 0; i < N; ++i) { v[i] = add_vertex(g); diff --git a/test/metric_tsp_approx.cpp b/test/metric_tsp_approx.cpp index 111a8e26..57560bd4 100644 --- a/test/metric_tsp_approx.cpp +++ b/test/metric_tsp_approx.cpp @@ -86,7 +86,6 @@ void testScalability(unsigned numpts) property > > Graph; typedef graph_traits::vertex_descriptor Vertex; - typedef graph_traits ::edge_descriptor Edge; typedef property_map::type WeightMap; typedef set, cmpPnt > PointSet; typedef vector< Vertex > Container; @@ -199,7 +198,6 @@ int main(int argc, char* argv[]) typedef adjacency_matrix > Graph; typedef graph_traits::vertex_descriptor Vertex; - typedef graph_traits ::edge_descriptor Edge; typedef vector Container; typedef property_map::type WeightMap; typedef property_map::type VertexMap; diff --git a/test/min_cost_max_flow_utils.hpp b/test/min_cost_max_flow_utils.hpp new file mode 100644 index 00000000..37c97953 --- /dev/null +++ b/test/min_cost_max_flow_utils.hpp @@ -0,0 +1,136 @@ +//======================================================================= +// Copyright 2013 University of Warsaw. +// Authors: Piotr Wygocki +// +// 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 SAMPLE_GRAPH_UNDIRECTED_HPP +#define SAMPLE_GRAPH_UNDIRECTED_HPP + +#include +#include +#include + + +namespace boost { +struct SampleGraph { + typedef adjacency_list_traits < vecS, vecS, directedS > Traits; + + typedef adjacency_list < vecS, vecS, directedS, no_property, + property < edge_capacity_t, long, + property < edge_residual_capacity_t, long, + property < edge_reverse_t, Traits::edge_descriptor, + property + > + > + > > Graph; + typedef property_map < Graph, edge_capacity_t >::type Capacity; + typedef property_map < Graph, edge_residual_capacity_t >::type ResidualCapacity; + typedef property_map < Graph, edge_weight_t >::type Weight; + typedef property_map < Graph, edge_reverse_t>::type Reversed; + typedef boost::graph_traits::vertices_size_type size_type; + typedef Traits::vertex_descriptor vertex_descriptor; + + class EdgeAdder { + public: + EdgeAdder(Graph & g, Weight & w, Capacity & c, Reversed & rev, ResidualCapacity & residualCapacity) + : m_g(g), m_w(w), m_cap(c), m_resCap(residualCapacity), m_rev(rev) {} + void addEdge(vertex_descriptor v, vertex_descriptor w, long weight, long capacity) { + Traits::edge_descriptor e,f; + e = add(v, w, weight, capacity); + f = add(w, v, -weight, 0); + m_rev[e] = f; + m_rev[f] = e; + } + private: + Traits::edge_descriptor add(vertex_descriptor v, vertex_descriptor w, long weight, long capacity) { + bool b; + Traits::edge_descriptor e; + boost::tie(e, b) = add_edge(vertex(v, m_g), vertex(w, m_g), m_g); + if (!b) { + std::cerr << "Edge between " << v << " and " << w << " already exists." << std::endl; + std::abort(); + } + m_cap[e] = capacity; + m_w[e] = weight; + return e; + } + Graph & m_g; + Weight & m_w; + Capacity & m_cap; + ResidualCapacity & m_resCap; + Reversed & m_rev; + }; + + + static void getSampleGraph(Graph &g, vertex_descriptor & s, vertex_descriptor & t) { + size_type N(6); + typedef property_map < Graph, edge_reverse_t >::type Reversed; + + for(size_type i = 0; i < N; ++i){ + add_vertex(g); + } + Capacity capacity = get(edge_capacity, g); + Reversed rev = get(edge_reverse, g); + ResidualCapacity residual_capacity = get(edge_residual_capacity, g); + Weight weight = get(edge_weight, g); + + s = 0; + t = 5; + + EdgeAdder ea(g, weight, capacity, rev, residual_capacity); + + ea.addEdge(0, 1, 4 ,2); + ea.addEdge(0, 2, 2 ,2); + + ea.addEdge(1, 3, 2 ,2); + ea.addEdge(1, 4, 1 ,1); + ea.addEdge(2, 3, 1 ,1); + ea.addEdge(2, 4, 1 ,1); + + ea.addEdge(3, 5, 4 ,20); + ea.addEdge(4, 5, 2 ,20); + } + + static void getSampleGraph2(Graph &g, vertex_descriptor & s, vertex_descriptor & t) { + + const boost::graph_traits::vertices_size_type N(5); + typedef property_map < Graph, edge_reverse_t >::type Reversed; + + for(size_type i = 0; i < N; ++i){ + add_vertex(g); + } + + Capacity capacity = get(edge_capacity, g); + Reversed rev = get(edge_reverse, g); + ResidualCapacity residual_capacity = get(edge_residual_capacity, g); + Weight weight = get(edge_weight, g); + + s = 0; + t = 4; + + EdgeAdder ea(g, weight, capacity, rev, residual_capacity); + + ea.addEdge(0, 1, 4 ,2); + ea.addEdge(0, 2, 2 ,2); + ea.addEdge(1, 2, 2 ,2); + ea.addEdge(2, 3, 1 ,1); + ea.addEdge(2, 4, 1 ,1); + ea.addEdge(3, 4, 1 ,1); + + + ea.addEdge(1, 0, 2 ,2); + ea.addEdge(2, 0, 1 ,1); + ea.addEdge(2, 1, 5 ,2); + ea.addEdge(3, 2, 1 ,1); + ea.addEdge(4, 2, 2 ,2); + ea.addEdge(4, 3, 1 ,3); + } +}; +} //boost + +#endif /* SAMPLE_GRAPH_UNDIRECTED_HPP */ + diff --git a/test/parallel_edges_loops_test.cpp b/test/parallel_edges_loops_test.cpp index 52bb4e92..6045c37c 100644 --- a/test/parallel_edges_loops_test.cpp +++ b/test/parallel_edges_loops_test.cpp @@ -195,9 +195,7 @@ int test_graph(const std::string& dimacs_filename) typedef graph_traits::edge_iterator edge_iterator_t; typedef graph_traits::vertex_iterator vertex_iterator_t; typedef graph_traits::edges_size_type e_size_t; - typedef graph_traits::vertices_size_type v_size_t; typedef graph_traits::vertex_descriptor vertex_t; - typedef std::pair vertex_pair_t; typedef edge_index_update_visitor::type> edge_visitor_t; diff --git a/test/property_iter.cpp b/test/property_iter.cpp index d206d2a7..3c27f942 100644 --- a/test/property_iter.cpp +++ b/test/property_iter.cpp @@ -109,19 +109,9 @@ int main(int, char* []) ++E; } - typedef boost::graph_property_iter_range< Graph, vertex_id_t>::const_iterator TNodeConstIterator; - typedef boost::graph_property_iter_range< Graph, vertex_id_t>::const_type TNodeConstIteratorType; - typedef boost::graph_property_iter_range< Graph, vertex_id_t>::iterator TNodeIterator; - typedef boost::graph_property_iter_range< Graph, vertex_id_t>::type TNodeIteratorType; - - typedef boost::graph_property_iter_range< Graph, edge_id_t>::const_iterator TLinkConstIterator; - typedef boost::graph_property_iter_range< Graph, edge_id_t>::const_type TLinkConstIteratorType; typedef boost::graph_property_iter_range< Graph, edge_id_t>::iterator TLinkIterator; - typedef boost::graph_property_iter_range< Graph, edge_id_t>::type TLinkIteratorType; - - typedef std::pair tLinkConstIteratorPair; TLinkIterator itEdgeBegin, itEdgeEnd; diff --git a/test/rcsp_custom_vertex_id.cpp b/test/rcsp_custom_vertex_id.cpp new file mode 100644 index 00000000..46770967 --- /dev/null +++ b/test/rcsp_custom_vertex_id.cpp @@ -0,0 +1,110 @@ +//======================================================================= +// Copyright (c) 2013 Alberto Santini +// Author: Alberto Santini +// +// 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 +#include +#include + +using std::vector; +using std::allocator; +using namespace boost; + +class VertexProperty { +public: + int property1; + int property2; + int id; + VertexProperty() {} + VertexProperty(const int property1, const int property2) : property1(property1), property2(property2) {} +}; + +class EdgeProperty { +public: + int cost; + int id; + EdgeProperty() {} + EdgeProperty(const int cost) : cost(cost) {} +}; + +typedef adjacency_list Graph; +typedef graph_traits::vertex_descriptor Vertex; +typedef graph_traits::edge_descriptor Edge; + +class ResourceCont { +public: + int res; + ResourceCont(const int res = 5) : res(res) {} + bool operator==(const ResourceCont& rc) const { return (res == rc.res); } + bool operator<(const ResourceCont& rc) const { return (res > rc.res); } +}; + +class LabelExt { +public: + bool operator()(const Graph& g, ResourceCont& rc, const ResourceCont& old_rc, Edge e) const { + rc.res = old_rc.res - g[e].cost; + return (rc.res > 0); + } +}; + +class LabelDom { +public: + bool operator()(const ResourceCont& rc1, const ResourceCont& rc2) const { + return (rc1 == rc2 || rc1 < rc2); + } +}; + +int main() { + VertexProperty vp1(1, 1); + VertexProperty vp2(5, 9); + VertexProperty vp3(4, 3); + EdgeProperty e12(1); + EdgeProperty e23(2); + + Graph g; + + Vertex v1 = add_vertex(g); g[v1] = vp1; + Vertex v2 = add_vertex(g); g[v2] = vp2; + Vertex v3 = add_vertex(g); g[v3] = vp3; + + add_edge(v1, v2, e12, g); + add_edge(v2, v3, e23, g); + + int index = 0; + BGL_FORALL_VERTICES(v, g, Graph) { + g[v].id = index++; + } + index = 0; + BGL_FORALL_EDGES(e, g, Graph) { + g[e].id = index++; + } + + typedef vector > OptPath; + typedef vector ParetoOpt; + + OptPath op; + ParetoOpt ol; + + r_c_shortest_paths( g, + get(&VertexProperty::id, g), + get(&EdgeProperty::id, g), + v1, + v2, + op, + ol, + ResourceCont(5), + LabelExt(), + LabelDom(), + allocator >(), + default_r_c_shortest_paths_visitor()); + + return 0; +} diff --git a/test/sequential_vertex_coloring.cpp b/test/sequential_vertex_coloring.cpp index 2a0775ae..eee7d738 100644 --- a/test/sequential_vertex_coloring.cpp +++ b/test/sequential_vertex_coloring.cpp @@ -16,7 +16,6 @@ using namespace boost; int test_main(int, char*[]) { typedef adjacency_list Graph; - typedef graph_traits::vertex_descriptor vertex_descriptor; typedef graph_traits::vertices_size_type vertices_size_type; typedef property_map::const_type vertex_index_map; diff --git a/test/stoer_wagner_test.cpp b/test/stoer_wagner_test.cpp index 034d5498..0b7e83e2 100644 --- a/test/stoer_wagner_test.cpp +++ b/test/stoer_wagner_test.cpp @@ -45,9 +45,6 @@ struct edge_t // the example from Stoer & Wagner (1997) BOOST_AUTO_TEST_CASE(test0) { - typedef boost::graph_traits::vertex_descriptor vertex_descriptor; - typedef boost::graph_traits::edge_descriptor edge_descriptor; - edge_t edges[] = {{0, 1}, {1, 2}, {2, 3}, {0, 4}, {1, 4}, {1, 5}, {2, 6}, {3, 6}, {3, 7}, {4, 5}, {5, 6}, {6, 7}}; weight_type ws[] = {2, 3, 4, 3, 2, 2, 2, 2, 2, 3, 1, 3}; @@ -72,16 +69,12 @@ BOOST_AUTO_TEST_CASE(test0) BOOST_AUTO_TEST_CASE(test1) { { // if only one vertex, can't run `boost::stoer_wagner_min_cut` - typedef boost::graph_traits::vertex_descriptor vertex_descriptor; - typedef boost::graph_traits::edge_descriptor edge_descriptor; - undirected_graph g; add_vertex(g); BOOST_CHECK_THROW(boost::stoer_wagner_min_cut(g, get(boost::edge_weight, g)), boost::bad_graph); }{ // three vertices with one multi-edge typedef boost::graph_traits::vertex_descriptor vertex_descriptor; - typedef boost::graph_traits::edge_descriptor edge_descriptor; edge_t edges[] = {{0, 1}, {1, 2}, {1, 2}, {2, 0}}; weight_type ws[] = {3, 1, 1, 1}; @@ -104,9 +97,6 @@ BOOST_AUTO_TEST_CASE(test1) // example by Daniel Trebbien BOOST_AUTO_TEST_CASE(test2) { - typedef boost::graph_traits::vertex_descriptor vertex_descriptor; - typedef boost::graph_traits::edge_descriptor edge_descriptor; - edge_t edges[] = {{5, 2}, {0, 6}, {5, 6}, {3, 1}, {0, 1}, {6, 3}, {4, 6}, {2, 4}, {5, 3}}; weight_type ws[] = {1, 3, 4, 6, 4, 1, 2, 5, 2}; @@ -129,9 +119,6 @@ BOOST_AUTO_TEST_CASE(test2) // example by Daniel Trebbien BOOST_AUTO_TEST_CASE(test3) { - typedef boost::graph_traits::vertex_descriptor vertex_descriptor; - typedef boost::graph_traits::edge_descriptor edge_descriptor; - edge_t edges[] = {{3, 4}, {3, 6}, {3, 5}, {0, 4}, {0, 1}, {0, 6}, {0, 7}, {0, 5}, {0, 2}, {4, 1}, {1, 6}, {1, 5}, {6, 7}, {7, 5}, {5, 2}, {3, 4}}; weight_type ws[] = {0, 3, 1, 3, 1, 2, 6, 1, 8, 1, 1, 80, 2, 1, 1, 4}; @@ -196,7 +183,6 @@ BOOST_AUTO_TEST_CASE(test4) BOOST_AUTO_TEST_CASE(test_prgen_20_70_2) { typedef boost::graph_traits::vertex_descriptor vertex_descriptor; - typedef boost::graph_traits::edge_descriptor edge_descriptor; std::ifstream ifs((test_dir + "/prgen_input_graphs/prgen_20_70_2.net").c_str()); undirected_graph g; @@ -221,7 +207,6 @@ BOOST_AUTO_TEST_CASE(test_prgen_20_70_2) BOOST_AUTO_TEST_CASE(test_prgen_50_40_2) { typedef boost::graph_traits::vertex_descriptor vertex_descriptor; - typedef boost::graph_traits::edge_descriptor edge_descriptor; std::ifstream ifs((test_dir + "/prgen_input_graphs/prgen_50_40_2.net").c_str()); undirected_graph g; @@ -239,7 +224,6 @@ BOOST_AUTO_TEST_CASE(test_prgen_50_40_2) BOOST_AUTO_TEST_CASE(test_prgen_50_70_2) { typedef boost::graph_traits::vertex_descriptor vertex_descriptor; - typedef boost::graph_traits::edge_descriptor edge_descriptor; std::ifstream ifs((test_dir + "/prgen_input_graphs/prgen_50_70_2.net").c_str()); undirected_graph g; diff --git a/test/subgraph.cpp b/test/subgraph.cpp index d0154a31..b1dcdb59 100644 --- a/test/subgraph.cpp +++ b/test/subgraph.cpp @@ -27,7 +27,6 @@ int test_main(int, char*[]) > graph_t; typedef subgraph subgraph_t; typedef graph_traits::vertex_descriptor vertex_t; - typedef graph_traits::edge_descriptor edge_t; mt19937 gen; for (int t = 0; t < 100; t += 5) { diff --git a/test/successive_shortest_path_nonnegative_weights_test.cpp b/test/successive_shortest_path_nonnegative_weights_test.cpp new file mode 100644 index 00000000..cf9fe50c --- /dev/null +++ b/test/successive_shortest_path_nonnegative_weights_test.cpp @@ -0,0 +1,67 @@ +//======================================================================= +// Copyright 2013 University of Warsaw. +// Authors: Piotr Wygocki +// +// 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) +//======================================================================= + +#define BOOST_TEST_MODULE successive_shortest_path_nonnegative_weights_test + +#include + +#include +#include + +#include "min_cost_max_flow_utils.hpp" + + +BOOST_AUTO_TEST_CASE(path_augmentation_def_test) { + boost::SampleGraph::vertex_descriptor s,t; + boost::SampleGraph::Graph g; + boost::SampleGraph::getSampleGraph(g, s, t); + + boost::successive_shortest_path_nonnegative_weights(g, s, t); + + int cost = boost::find_flow_cost(g); + BOOST_CHECK_EQUAL(cost, 29); +} + +BOOST_AUTO_TEST_CASE(path_augmentation_def_test2) { + boost::SampleGraph::vertex_descriptor s,t; + boost::SampleGraph::Graph g; + boost::SampleGraph::getSampleGraph2(g, s, t); + + boost::successive_shortest_path_nonnegative_weights(g, s, t); + + int cost = boost::find_flow_cost(g); + BOOST_CHECK_EQUAL(cost, 7); +} + +BOOST_AUTO_TEST_CASE(path_augmentation_test) { + boost::SampleGraph::vertex_descriptor s,t; + typedef boost::SampleGraph::Graph Graph; + Graph g; + boost::SampleGraph::getSampleGraph(g, s, t); + + int N = boost::num_vertices(g); + std::vector dist(N); + std::vector dist_prev(N); + typedef boost::graph_traits::edge_descriptor edge_descriptor; + std::vector pred(N); + + boost::property_map::const_type + idx = get(boost::vertex_index, g); + + boost::successive_shortest_path_nonnegative_weights(g, s, t, + boost::distance_map(boost::make_iterator_property_map(dist.begin(), idx)). + predecessor_map(boost::make_iterator_property_map(pred.begin(), idx)). + distance_map2(boost::make_iterator_property_map(dist_prev.begin(), idx)). + vertex_index_map(idx)); + + int cost = boost::find_flow_cost(g); + BOOST_CHECK_EQUAL(cost, 29); +} + + diff --git a/test/test_properties.hpp b/test/test_properties.hpp index adeb9ae1..2d71b9b2 100644 --- a/test/test_properties.hpp +++ b/test/test_properties.hpp @@ -17,9 +17,6 @@ void test_graph_bundle(Graph& g, boost::mpl::true_) { using namespace boost; std::cout << "...test_graph_bundle\n"; - typedef typename graph_property_type::type Property; - typedef typename graph_bundle_type::type Bundle; - GraphBundle& b1 = g[graph_bundle]; GraphBundle& b2 = get_property(g); ignore(b1); ignore(b2); diff --git a/test/tiernan_all_cycles.cpp b/test/tiernan_all_cycles.cpp index 39f8af84..0e77c784 100644 --- a/test/tiernan_all_cycles.cpp +++ b/test/tiernan_all_cycles.cpp @@ -27,8 +27,6 @@ struct cycle_validator void cycle(const Path& p, const Graph& g) { ++cycles; - typedef typename graph_traits::vertex_descriptor Vertex; - typedef typename graph_traits::edge_descriptor Edge; // Check to make sure that each of the vertices in the path // is truly connected and that the back is connected to the // front - it's not validating that we find all paths, just diff --git a/test/transitive_closure_test.cpp b/test/transitive_closure_test.cpp index 16ec350f..cdae591d 100644 --- a/test/transitive_closure_test.cpp +++ b/test/transitive_closure_test.cpp @@ -74,7 +74,7 @@ bool check_transitive_closure(Graph& g, GraphTC& tc) typename graph_traits::adjacency_iterator k, k_end; for (boost::tie(k, k_end) = adjacent_vertices(*i, g); k != k_end; ++k) { std::vector color_map_vec(num_vertices(g)); - if (is_reachable(*k, *i, g, &color_map_vec[0])) { + if (is_reachable(*k, *i, g, boost::make_iterator_property_map(color_map_vec.begin(), get(boost::vertex_index, g)))) { can_reach = true; break; } @@ -93,7 +93,7 @@ bool check_transitive_closure(Graph& g, GraphTC& tc) } } else { std::vector color_map_vec(num_vertices(g)); - if (is_reachable(*i, *j, g, &color_map_vec[0])) { + if (is_reachable(*i, *j, g, boost::make_iterator_property_map(color_map_vec.begin(), get(boost::vertex_index, g)))) { if (num_tc != 1) return false; } else { @@ -117,16 +117,16 @@ bool test(int n, double p) { progress_timer t; cout << "transitive_closure" << endl; - transitive_closure(g1, g1_tc, vertex_index_map(identity_property_map())); + transitive_closure(g1, g1_tc, vertex_index_map(get(boost::vertex_index, g1))); } if(check_transitive_closure(g1, g1_tc)) return true; else { cout << "Original graph was "; - print_graph(g1, identity_property_map()); + print_graph(g1, get(boost::vertex_index, g1)); cout << "Result is "; - print_graph(g1_tc, identity_property_map()); + print_graph(g1_tc, get(boost::vertex_index, g1_tc)); return false; } } diff --git a/test/undirected_dfs.cpp b/test/undirected_dfs.cpp new file mode 100644 index 00000000..74e7d388 --- /dev/null +++ b/test/undirected_dfs.cpp @@ -0,0 +1,202 @@ +//======================================================================= +// Copyright 2001 University of Notre Dame. +// Author: Jeremy G. Siek +// +// 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 +#include +#include +#include +#include + +#include + +template +class dfs_test_visitor { + typedef typename boost::property_traits::value_type ColorValue; + typedef typename boost::color_traits Color; +public: + dfs_test_visitor(ColorMap color, ParentMap p, DiscoverTimeMap d, + FinishTimeMap f) + : m_color(color), m_parent(p), + m_discover_time(d), m_finish_time(f), m_time(0) { } + + template + void initialize_vertex(Vertex u, Graph&) { + BOOST_CHECK( boost::get(m_color, u) == Color::white() ); + } + template + void start_vertex(Vertex u, Graph&) { + BOOST_CHECK( boost::get(m_color, u) == Color::white() ); + } + template + void discover_vertex(Vertex u, Graph&) { + using namespace boost; + BOOST_CHECK( get(m_color, u) == Color::gray() ); + BOOST_CHECK( get(m_color, get(m_parent, u)) == Color::gray() ); + + put(m_discover_time, u, m_time++); + } + template + void examine_edge(Edge e, Graph& g) { + using namespace boost; + BOOST_CHECK( get(m_color, source(e, g)) == Color::gray() ); + } + template + void tree_edge(Edge e, Graph& g) { + using namespace boost; + BOOST_CHECK( get(m_color, target(e, g)) == Color::white() ); + + put(m_parent, target(e, g), source(e, g)); + } + template + void back_edge(Edge e, Graph& g) { + using namespace boost; + BOOST_CHECK( get(m_color, target(e, g)) == Color::gray() ); + } + template + void forward_or_cross_edge(Edge e, Graph& g) { + using namespace boost; + BOOST_CHECK( get(m_color, target(e, g)) == Color::black() ); + } + template + void finish_edge(Edge e, Graph& g) { + using namespace boost; + BOOST_CHECK( + (get(m_color, target(e, g)) == Color::gray()) + || (get(m_color, target(e, g)) == Color::black()) + ); + } + template + void finish_vertex(Vertex u, Graph&) { + using namespace boost; + BOOST_CHECK( get(m_color, u) == Color::black() ); + + put(m_finish_time, u, m_time++); + } +private: + ColorMap m_color; + ParentMap m_parent; + DiscoverTimeMap m_discover_time; + FinishTimeMap m_finish_time; + typename boost::property_traits::value_type m_time; +}; + +template +struct dfs_test +{ + typedef boost::graph_traits Traits; + typedef typename Traits::vertices_size_type + vertices_size_type; + + static void go(vertices_size_type max_V) { + using namespace boost; + typedef typename Traits::vertex_descriptor vertex_descriptor; + typedef typename boost::property_map::type ColorMap; + typedef typename boost::property_traits::value_type ColorValue; + typedef typename boost::color_traits Color; + typedef typename boost::property_map::type EColorMap; + typedef typename boost::property_traits::value_type EColorValue; + typedef typename boost::color_traits EColor; + + vertices_size_type i, k; + typename Traits::edges_size_type j; + typename Traits::vertex_iterator vi, vi_end, ui, ui_end; + typename Traits::edge_iterator ei, ei_end; + + boost::mt19937 gen; + + for (i = 0; i < max_V; ++i) + for (j = 0; j < i*i; ++j) { + Graph g; + generate_random_graph(g, i, j, gen); + + ColorMap color = get(boost::vertex_color, g); + EColorMap e_color = get(boost::edge_color, g); + std::vector parent(num_vertices(g)); + for (k = 0; k < num_vertices(g); ++k) + parent[k] = k; + std::vector discover_time(num_vertices(g)), + finish_time(num_vertices(g)); + + // Get vertex index map + typedef typename boost::property_map::const_type idx_type; + idx_type idx = get(boost::vertex_index, g); + + typedef + boost::iterator_property_map::iterator, idx_type> + parent_pm_type; + parent_pm_type parent_pm(parent.begin(), idx); + typedef + boost::iterator_property_map::iterator, idx_type> + time_pm_type; + time_pm_type discover_time_pm(discover_time.begin(), idx); + time_pm_type finish_time_pm(finish_time.begin(), idx); + + dfs_test_visitor + vis(color, parent_pm, + discover_time_pm, finish_time_pm); + + boost::undirected_dfs(g, visitor(vis).color_map(color) + .edge_color_map(e_color)); + + // all vertices should be black + for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) + BOOST_CHECK(get(color, *vi) == Color::black()); + + // all edges should be black + for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) + BOOST_CHECK(get(e_color, *ei) == EColor::black()); + + // check parenthesis structure of discover/finish times + // See CLR p.480 + for (boost::tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui) + for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) { + vertex_descriptor u = *ui, v = *vi; + if (u != v) { + BOOST_CHECK( finish_time[u] < discover_time[v] + || finish_time[v] < discover_time[u] + || (discover_time[v] < discover_time[u] + && finish_time[u] < finish_time[v] + && boost::is_descendant(u, v, parent_pm)) + || (discover_time[u] < discover_time[v] + && finish_time[v] < finish_time[u] + && boost::is_descendant(v, u, parent_pm)) + ); + } + } + } + + } +}; + + +// usage: undirected_dfs.exe [max-vertices=15] + +int test_main(int argc, char* argv[]) +{ + int max_V = 7; + if (argc > 1) + max_V = atoi(argv[1]); + + // Test undirected graphs. + dfs_test< boost::adjacency_list, + boost::property > + >::go(max_V); + + return 0; +} +