mirror of
https://github.com/boostorg/graph.git
synced 2026-01-19 04:12:11 +00:00
Merged Boost.Graph, Boost.Graph.Parallel, and Boost.PropertyMap changes from Boost trunk
[SVN r85813]
This commit is contained in:
@@ -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
|
||||
<toolset>msvc-7.1:<cxxflags>-GR-
|
||||
<toolset>sun:<build>no
|
||||
:
|
||||
:
|
||||
;
|
||||
|
||||
@@ -150,6 +150,15 @@ undirected graph this method is never called.
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Finish Edge</td>
|
||||
<td><tt>vis.finish_edge(e, g)</tt></td>
|
||||
<td><tt>void</tt></td>
|
||||
<td>
|
||||
This is invoked on each non-tree edge as well as on each tree edge after
|
||||
<tt>finish_vertex</tt> has been called on its target vertex.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Finish Vertex</td>
|
||||
<td><tt>vis.finish_vertex(u, g)</tt></td>
|
||||
<td><tt>void</tt></td>
|
||||
|
||||
223
doc/cycle_canceling.html
Normal file
223
doc/cycle_canceling.html
Normal file
@@ -0,0 +1,223 @@
|
||||
<HTML>
|
||||
<!--
|
||||
Copyright (c) Piotr Wygocki 2013
|
||||
|
||||
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)
|
||||
-->
|
||||
<Head>
|
||||
<Title>Boost Graph Library: Cycle Canceling for Min Cost Max Flow</Title>
|
||||
<BODY BGCOLOR="#ffffff" LINK="#0000ee" TEXT="#000000" VLINK="#551a8b"
|
||||
ALINK="#ff0000">
|
||||
<IMG SRC="../../../boost.png"
|
||||
ALT="C++ Boost" width="277" height="86">
|
||||
|
||||
<BR Clear>
|
||||
|
||||
<H1><A NAME="sec:cycle_canceling">
|
||||
<TT>cycle_canceling</TT>
|
||||
</H1>
|
||||
|
||||
<PRE>
|
||||
<i>// named parameter version</i>
|
||||
template <class <a href="./Graph.html">Graph</a>, class P, class T, class R>
|
||||
void cycle_canceling(
|
||||
Graph &g,
|
||||
const bgl_named_params<P, T, R> & params = <i>all defaults</i>)
|
||||
|
||||
<i>// non-named parameter version</i>
|
||||
template <class <a href="./Graph.html">Graph</a>, 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)
|
||||
</PRE>
|
||||
|
||||
<P>
|
||||
The <tt>cycle_canceling()</tt> function calculates the minimum cost flow of a network with given flow. See Section <a
|
||||
href="./graph_theory_review.html#sec:network-flow-algorithms">Network
|
||||
Flow Algorithms</a> for a description of maximum flow.
|
||||
For given flow values <i> f(u,v)</i> function minimizes flow cost in such a way, that for each <i>v in V</i> the
|
||||
<i> sum<sub> u in V</sub> f(v,u) </i> is preserved. Particularly if the input flow was the maximum flow, the function produces min cost max flow.
|
||||
|
||||
|
||||
The function calculates the flow values <i>f(u,v)</i> for all <i>(u,v)</i> in
|
||||
<i>E</i>, which are returned in the form of the residual capacity
|
||||
<i>r(u,v) = c(u,v) - f(u,v)</i>.
|
||||
|
||||
<p>
|
||||
There are several special requirements on the input graph and property
|
||||
map parameters for this algorithm. First, the directed graph
|
||||
<i>G=(V,E)</i> that represents the network must be augmented to
|
||||
include the reverse edge for every edge in <i>E</i>. That is, the
|
||||
input graph should be <i>G<sub>in</sub> = (V,{E U
|
||||
E<sup>T</sup>})</i>. The <tt>ReverseEdgeMap</tt> argument <tt>rev</tt>
|
||||
must map each edge in the original graph to its reverse edge, that is
|
||||
<i>(u,v) -> (v,u)</i> for all <i>(u,v)</i> in <i>E</i>.
|
||||
The <tt>WeightMap</tt> has to map each edge from <i>E<sup>T</sup></i> to <i>-weight</i> of its reversed edge.
|
||||
Note that edges from <i>E</i> can have negative weights.
|
||||
<p>
|
||||
If weights in the graph are nonnegative, the
|
||||
<a href="./successive_shortest_path_nonnegative_weights.html"><tt>successive_shortest_path_nonnegative_weights()</tt></a>
|
||||
might be better choice for min cost max flow.
|
||||
|
||||
<p>
|
||||
The algorithm is described in <a
|
||||
href="./bibliography.html#ahuja93:_network_flows">Network Flows</a>.
|
||||
|
||||
<p>
|
||||
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.
|
||||
|
||||
<p>
|
||||
Note that, although we mention capacity in the problem description, the actual algorithm doesn't have to now it.
|
||||
|
||||
<p>
|
||||
In order to find the cost of the result flow use:
|
||||
<a href="./find_flow_cost.html"><tt>find_flow_cost()</tt></a>.
|
||||
|
||||
|
||||
<H3>Where Defined</H3>
|
||||
|
||||
<P>
|
||||
<a href="../../../boost/graph/successive_shortest_path_nonnegative_weights.hpp"><TT>boost/graph/successive_shortest_path_nonnegative_weights.hpp</TT></a>
|
||||
|
||||
<P>
|
||||
|
||||
<h3>Parameters</h3>
|
||||
|
||||
IN: <tt>Graph& g</tt>
|
||||
<blockquote>
|
||||
A directed graph. The
|
||||
graph's type must be a model of <a
|
||||
href="./VertexListGraph.html">VertexListGraph</a> and <a href="./IncidenceGraph.html">IncidenceGraph</a> For each edge
|
||||
<i>(u,v)</i> in the graph, the reverse edge <i>(v,u)</i> must also
|
||||
be in the graph.
|
||||
</blockquote>
|
||||
|
||||
<h3>Named Parameters</h3>
|
||||
|
||||
|
||||
IN/OUT: <tt>residual_capacity_map(ResidualCapacityEdgeMap res)</tt>
|
||||
<blockquote>
|
||||
This maps edges to their residual capacity. The type must be a model
|
||||
of a mutable <a
|
||||
href="../../property_map/doc/LvaluePropertyMap.html">Lvalue Property
|
||||
Map</a>. The key type of the map must be the graph's edge descriptor
|
||||
type.<br>
|
||||
<b>Default:</b> <tt>get(edge_residual_capacity, g)</tt>
|
||||
</blockquote>
|
||||
|
||||
IN: <tt>reverse_edge_map(ReverseEdgeMap rev)</tt>
|
||||
<blockquote>
|
||||
An edge property map that maps every edge <i>(u,v)</i> in the graph
|
||||
to the reverse edge <i>(v,u)</i>. The map must be a model of
|
||||
constant <a href="../../property_map/doc/LvaluePropertyMap.html">Lvalue
|
||||
Property Map</a>. The key type of the map must be the graph's edge
|
||||
descriptor type.<br>
|
||||
<b>Default:</b> <tt>get(edge_reverse, g)</tt>
|
||||
</blockquote>
|
||||
|
||||
IN: <tt>weight_map(WeightMap w)</tt>
|
||||
<blockquote>
|
||||
The weight (also know as ``length'' or ``cost'') of each edge in the
|
||||
graph. The <tt>WeightMap</tt> type must be a model of <a
|
||||
href="../../property_map/doc/ReadablePropertyMap.html">Readable Property
|
||||
Map</a>. The key type for this property map must be the edge
|
||||
descriptor of the graph. The value type for the weight map must be
|
||||
<i>Addable</i> with the distance map's value type. <br>
|
||||
<b>Default:</b> <tt>get(edge_weight, g)</tt><br>
|
||||
</blockquote>
|
||||
|
||||
UTIL: <tt>predecessor_map(PredEdgeMap pred)</tt>
|
||||
<blockquote>
|
||||
Use by the algorithm to store augmenting paths. The map must be a
|
||||
model of mutable <a
|
||||
href="../../property_map/doc/LvaluePropertyMap.html">Lvalue Property Map</a>.
|
||||
The key type must be the graph's vertex descriptor type and the
|
||||
value type must be the graph's edge descriptor type.<br>
|
||||
|
||||
<b>Default:</b> an <a
|
||||
href="../../property_map/doc/iterator_property_map.html">
|
||||
<tt>iterator_property_map</tt></a> created from a <tt>std::vector</tt>
|
||||
of edge descriptors of size <tt>num_vertices(g)</tt> and
|
||||
using the <tt>i_map</tt> for the index map.
|
||||
</blockquote>
|
||||
|
||||
UTIL: <tt>distance_map(DistanceMap d_map)</tt>
|
||||
<blockquote>
|
||||
The shortest path weight from the source vertex <tt>s</tt> to each
|
||||
vertex in the graph <tt>g</tt> is recorded in this property map. The
|
||||
shortest path weight is the sum of the edge weights along the
|
||||
shortest path. The type <tt>DistanceMap</tt> must be a model of <a
|
||||
href="../../property_map/doc/ReadWritePropertyMap.html">Read/Write
|
||||
Property Map</a>. The vertex descriptor type of the graph needs to
|
||||
be usable as the key type of the distance map.
|
||||
|
||||
<b>Default:</b> <a
|
||||
href="../../property_map/doc/iterator_property_map.html">
|
||||
<tt>iterator_property_map</tt></a> created from a
|
||||
<tt>std::vector</tt> of the <tt>WeightMap</tt>'s value type of size
|
||||
<tt>num_vertices(g)</tt> and using the <tt>i_map</tt> for the index
|
||||
map.<br>
|
||||
|
||||
</blockquote>
|
||||
|
||||
IN: <tt>vertex_index_map(VertexIndexMap i_map)</tt>
|
||||
<blockquote>
|
||||
Maps each vertex of the graph to a unique integer in the range
|
||||
<tt>[0, num_vertices(g))</tt>. 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 <a
|
||||
href="../../property_map/doc/ReadablePropertyMap.html">Readable Property
|
||||
Map</a>. The key type of the map must be the graph's vertex
|
||||
descriptor type.<br>
|
||||
<b>Default:</b> <tt>get(vertex_index, g)</tt>
|
||||
Note: if you use this default, make sure your graph has
|
||||
an internal <tt>vertex_index</tt> property. For example,
|
||||
<tt>adjacenty_list</tt> with <tt>VertexList=listS</tt> does
|
||||
not have an internal <tt>vertex_index</tt> property.
|
||||
</blockquote>
|
||||
|
||||
<h3>Complexity</h3>
|
||||
In the integer capacity and weight case, if <i>C</i> is the initial cost of the flow, then the complexity is <i> O(C * |V| * |E|)</i>,
|
||||
where <i>O(|E|* |V|)</i> is the complexity of the bellman ford shortest paths algorithm and <i>C</i> is upper bound on number of iteration.
|
||||
In many real world cases number of iterations is much smaller than <i>C</i>.
|
||||
|
||||
|
||||
<h3>Example</h3>
|
||||
|
||||
The program in <a
|
||||
href="../example/cycle_canceling_example.cpp"><tt>example/cycle_canceling_example.cpp</tt></a>.
|
||||
|
||||
|
||||
<h3>See Also</h3>
|
||||
|
||||
<a href="./successive_shortest_path_nonnegative_weights.html"><tt>successive_shortest_path_nonnegative_weights()</tt></a><br>
|
||||
<a href="./find_flow_cost.html"><tt>find_flow_cost()</tt></a>.
|
||||
|
||||
<br>
|
||||
<HR>
|
||||
<TABLE>
|
||||
<TR valign=top>
|
||||
<TD nowrap>Copyright © 2013</TD><TD>
|
||||
Piotr Wygocki, University of Warsaw (<A HREF="mailto:wygos@mimuw.edu.pl">wygos at mimuw.edu.pl</A>)
|
||||
</TD></TR></TABLE>
|
||||
|
||||
</BODY>
|
||||
</HTML>
|
||||
<!-- LocalWords: HTML Siek Edmonds BGCOLOR ffffff ee VLINK ALINK ff IMG SRC
|
||||
-->
|
||||
<!-- LocalWords: gif ALT BR sec edmonds karp TT DIV CELLPADDING TR TD PRE lt
|
||||
-->
|
||||
<!-- LocalWords: typename VertexListGraph CapacityEdgeMap ReverseEdgeMap gt
|
||||
-->
|
||||
<!-- LocalWords: ResidualCapacityEdgeMap VertexIndexMap src rev ColorMap pred
|
||||
-->
|
||||
<!-- LocalWords: PredEdgeMap tt href html hpp ul li nbsp br LvaluePropertyMap
|
||||
-->
|
||||
<!-- LocalWords: num ColorValue DIMACS cpp pre config iostream dimacs int std
|
||||
-->
|
||||
<!-- LocalWords: namespace vecS directedS cout endl iter ei HR valign nowrap
|
||||
-->
|
||||
<!-- LocalWords: jeremy siek htm Univ mailto jsiek lsc edu
|
||||
p -->
|
||||
|
||||
@@ -107,6 +107,7 @@ DFS-VISIT(<i>G</i>, <i>u</i>)
|
||||
<i>...</i>
|
||||
<b>else if</b> (<i>color[v] =</i> BLACK)
|
||||
<i>...</i>
|
||||
<i>...</i>
|
||||
<b>end for</b>
|
||||
<i>color[u] :=</i> BLACK
|
||||
<i>f_time[u] := time := time + 1</i>
|
||||
@@ -140,6 +141,8 @@ examine edge <i>(u,v)</i>
|
||||
-
|
||||
<i>(u,v)</i> is a cross or forward edge
|
||||
-
|
||||
finish edge <i>(u,v)</i>
|
||||
-
|
||||
finish vertex <i>u</i>
|
||||
-
|
||||
</pre>
|
||||
@@ -266,6 +269,9 @@ The time complexity is <i>O(E + V)</i>.
|
||||
<li><b><tt>vis.forward_or_cross_edge(e, g)</tt></b> is invoked on
|
||||
forward or cross edges in the graph. In an undirected graph this
|
||||
method is never called.
|
||||
|
||||
<li><b><tt>vis.finish_edge(e, g)</tt></b> is invoked on the non-tree edges in
|
||||
the graph as well as on each tree edge after its target vertex is finished.
|
||||
|
||||
<li><b><tt>vis.finish_vertex(u, g)</tt></b> is invoked on a vertex after
|
||||
all of its out edges have been added to the search tree and all of
|
||||
|
||||
@@ -124,11 +124,12 @@ DIJKSTRA(<i>G</i>, <i>s</i>, <i>w</i>)
|
||||
<b>if</b> (<i>w(u,v) + d[u] < d[v]</i>)
|
||||
<i>d[v] := w(u,v) + d[u]</i>
|
||||
<i>p[v] := u</i>
|
||||
DECREASE-KEY(<i>Q</i>, <i>v</i>)
|
||||
<b>if</b> (<i>d[v]</i> was originally infinity)
|
||||
INSERT(<i>Q</i>, <i>v</i>)
|
||||
<b>else</b>
|
||||
DECREASE-KEY(<i>Q</i>, <i>v</i>)
|
||||
<b>else</b>
|
||||
...
|
||||
<b>if</b> (<i>d[v]</i> was originally infinity)
|
||||
INSERT(<i>Q</i>, <i>v</i>)
|
||||
<b>end for</b>
|
||||
<b>end while</b>
|
||||
return (<i>d</i>, <i>p</i>)
|
||||
@@ -146,10 +147,11 @@ examine edge <i>(u,v)</i>
|
||||
edge <i>(u,v)</i> relaxed
|
||||
|
||||
|
||||
discover vertex <i>v</i>
|
||||
|
||||
|
||||
edge <i>(u,v)</i> not relaxed
|
||||
|
||||
discover vertex <i>v</i>
|
||||
finish vertex <i>u</i>
|
||||
</pre>
|
||||
</td>
|
||||
|
||||
98
doc/edge_coloring.html
Normal file
98
doc/edge_coloring.html
Normal file
@@ -0,0 +1,98 @@
|
||||
<HTML>
|
||||
<!--
|
||||
~~ Copyright (c) Maciej Piechotka 2013
|
||||
~~
|
||||
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)
|
||||
-->
|
||||
|
||||
|
||||
<Head>
|
||||
<Title>Boost Graph Library: Edge Coloring</Title>
|
||||
<BODY BGCOLOR="#ffffff" LINK="#0000ee" TEXT="#000000" VLINK="#551a8b"
|
||||
ALINK="#ff0000">
|
||||
<IMG SRC="../../../boost.png"
|
||||
ALT="C++ Boost" width="277" height="86">
|
||||
|
||||
<BR Clear>
|
||||
|
||||
<H1>
|
||||
<!-- <img src="figs/python.gif" alt="(Python)"/> -->
|
||||
<TT>edge_coloring</TT>
|
||||
</H1>
|
||||
|
||||
|
||||
<P>
|
||||
<DIV ALIGN="LEFT">
|
||||
<TABLE CELLPADDING=3 border>
|
||||
<TR><TH ALIGN="LEFT"><B>Graphs:</B></TH>
|
||||
<TD ALIGN="LEFT">undirected, loop-free</TD>
|
||||
</TR>
|
||||
<TR><TH ALIGN="LEFT"><B>Properties:</B></TH>
|
||||
<TD ALIGN="LEFT">color</TD>
|
||||
</TR>
|
||||
<TR><TH ALIGN="LEFT"><B>Complexity:</B></TH>
|
||||
<TD ALIGN="LEFT">time: <i>O(|E| |V|)</i> </TD>
|
||||
</TR>
|
||||
</TABLE>
|
||||
</DIV>
|
||||
|
||||
|
||||
<pre>
|
||||
template <class Graph, class ColorMap>
|
||||
typename boost::property_traits<ColorMap>::value_type
|
||||
edge_coloring(const Graph &g, ColorMap color);
|
||||
</pre>
|
||||
|
||||
<p>Computes an edge coloring for the vertices in the graph, using
|
||||
an algorithm proposed by Mista et al. []. Given edges ordered
|
||||
e<sub>1</sub>, e<sub>2</sub>, ..., e<sub>n</sub> it assignes a
|
||||
colors c<sub>1</sub>, c<sub>2</sub>, ..., c<sub>n</sub> in a way
|
||||
that no vertex connects with 2 edges of the same color. Furthermore
|
||||
at most m + 1 colors are used.
|
||||
|
||||
<!-- King, I.P. An automatic reordering scheme for simultaneous equations derived from network analysis. Int. J. Numer. Methods Engrg. 2 (1970), 523-533 -->
|
||||
|
||||
<h3>Where defined</h3>
|
||||
<a href="../../../boost/graph/edge_coloring.hpp"><tt>boost/graph/edge_coloring.hpp</tt></a>
|
||||
|
||||
<h3>Parameters</h3>
|
||||
|
||||
IN: <tt>const Graph& g</tt>
|
||||
<blockquote>
|
||||
The graph object on which the algorithm will be applied. The type
|
||||
<tt>Graph</tt> must be a model of <a href="EdgeListGraph.html">
|
||||
Edge List Graph</a> and <a href="IncidenceGraph.html">Incidence
|
||||
Graph</a>.
|
||||
</blockquote>
|
||||
|
||||
OUT: <tt>ColorMap color</tt>
|
||||
<blockquote>
|
||||
This property map records the colors of each edges. It must be a
|
||||
model of <A HREF="../../property_map/doc/ReadWritePropertyMap.html">
|
||||
Read/Write Property Map</A> 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.
|
||||
</blockquote>
|
||||
|
||||
|
||||
<h3>Example</h3>
|
||||
|
||||
See <A
|
||||
href="../example/edge_coloring.cpp"><tt>example/king_ordering.cpp</tt></A>.
|
||||
|
||||
<h3>See Also</h3>
|
||||
|
||||
<A href="./sequential_vertex_coloring.html">sequential vertex ordering</tt></A>.
|
||||
|
||||
<br>
|
||||
<HR>
|
||||
<TABLE>
|
||||
<TR valign=top>
|
||||
<TD nowrap>Copyright © 2013</TD><TD>
|
||||
Maciej Piechotka (<A HREF="mailto:uzytkownik2@gmail.com">uzytkownik2@gmail.com</A>)
|
||||
</TD></TR></TABLE>
|
||||
|
||||
</BODY>
|
||||
</HTML>
|
||||
139
doc/find_flow_cost.html
Normal file
139
doc/find_flow_cost.html
Normal file
@@ -0,0 +1,139 @@
|
||||
<HTML>
|
||||
<!--
|
||||
Copyright (c) Piotr Wygocki 2013
|
||||
|
||||
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)
|
||||
-->
|
||||
<Head>
|
||||
<Title>Boost Graph Library: Find Flow Cost</Title>
|
||||
<BODY BGCOLOR="#ffffff" LINK="#0000ee" TEXT="#000000" VLINK="#551a8b"
|
||||
ALINK="#ff0000">
|
||||
<IMG SRC="../../../boost.png"
|
||||
ALT="C++ Boost" width="277" height="86">
|
||||
|
||||
<BR Clear>
|
||||
|
||||
<H1><A NAME="sec:find_flow_cost">
|
||||
<TT>find_flow_cost</TT>
|
||||
</H1>
|
||||
|
||||
<PRE>
|
||||
<i>// named parameter version</i>
|
||||
template <class <a href="./Graph.html">Graph</a>>
|
||||
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 = <i>all defaults</i>)
|
||||
|
||||
<i>// non-named parameter version</i>
|
||||
template<class <a href="./Graph.html">Graph</a>, 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)
|
||||
</PRE>
|
||||
|
||||
<P>
|
||||
The <tt>find_flow_cost()</tt> function calculates the minimum cost maximum flow value of a network and given flow. See Section <a
|
||||
href="./graph_theory_review.html#sec:network-flow-algorithms">Network
|
||||
Flow Algorithms</a> for a description of maximum flow.
|
||||
The function calculates the cost from the flow values <i>f(u,v)</i> for <i>(u,v)</i> in
|
||||
<i>E</i>, which are passed in the form of the residual capacity
|
||||
<i>r(u,v) = c(u,v) - f(u,v)</i>.
|
||||
|
||||
<p>
|
||||
In order to compute the min cost max flow use :
|
||||
<a href="./successive_shortest_path_nonnegative_weights.html"><tt>successive_shortest_path_nonnegative_weights()</tt></a> or
|
||||
<a href="./cycle_canceling.html"><tt>cycle_canceling()</tt></a>.
|
||||
|
||||
<H3>Where Defined</H3>
|
||||
|
||||
<P>
|
||||
<a href="../../../boost/graph/successive_shortest_path_nonnegative_weights.hpp"><TT>boost/graph/successive_shortest_path_nonnegative_weights.hpp</TT></a>
|
||||
|
||||
<P>
|
||||
|
||||
<h3>Parameters</h3>
|
||||
|
||||
IN: <tt>const Graph& g</tt>
|
||||
<blockquote>
|
||||
A directed graph. The
|
||||
graph's type must be a model of <a
|
||||
href="./VertexListGraph.html">VertexListGraph</a> and <a href="./IncidenceGraph.html">IncidenceGraph</a> For each edge
|
||||
<i>(u,v)</i> in the graph, the reverse edge <i>(v,u)</i> must also
|
||||
be in the graph.
|
||||
</blockquote>
|
||||
<h3>Named Parameters</h3>
|
||||
|
||||
|
||||
IN: <tt>capacity_map(CapacityEdgeMap cap)</tt>
|
||||
<blockquote>
|
||||
The edge capacity property map. The type must be a model of a
|
||||
constant <a
|
||||
href="../../property_map/doc/LvaluePropertyMap.html">Lvalue Property Map</a>. The
|
||||
key type of the map must be the graph's edge descriptor type.<br>
|
||||
<b>Default:</b> <tt>get(edge_capacity, g)</tt>
|
||||
</blockquote>
|
||||
|
||||
IN: <tt>residual_capacity_map(ResidualCapacityEdgeMap res)</tt>
|
||||
<blockquote>
|
||||
This maps edges to their residual capacity. The type must be a model
|
||||
of a mutable <a
|
||||
href="../../property_map/doc/LvaluePropertyMap.html">Lvalue Property
|
||||
Map</a>. The key type of the map must be the graph's edge descriptor
|
||||
type.<br>
|
||||
<b>Default:</b> <tt>get(edge_residual_capacity, g)</tt>
|
||||
</blockquote>
|
||||
|
||||
|
||||
IN: <tt>weight_map(WeightMap w_map)</tt>
|
||||
<blockquote>
|
||||
The weight or ``cost'' of each edge in the graph.
|
||||
The type <tt>WeightMap</tt> must be a model of
|
||||
<a href="../../property_map/doc/ReadablePropertyMap.html">Readable Property Map</a>. 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.<br>
|
||||
<b>Default:</b> <tt>get(edge_weight, g)</tt><br>
|
||||
|
||||
</blockquote>
|
||||
|
||||
<h3>Complexity</h3>
|
||||
The complexity is <i> O(|E|)</i>,
|
||||
|
||||
<h3>Example</h3>
|
||||
|
||||
The function is used in the successive_shortest_path_nonnegative_weights example. The program in <a
|
||||
href="../example/successive_shortest_path_nonnegative_weights_example.cpp"><tt>example/successive_shortest_path_nonnegative_weights_example.cpp</tt></a>.
|
||||
|
||||
<h3>See Also</h3>
|
||||
|
||||
<a href="./cycle_canceling.html"><tt>cycle_canceling()</tt></a><br>
|
||||
<a href="./successive_shortest_path_nonnegative_weights.html"><tt>successive_shortest_path_nonnegative_weights()</tt></a>.
|
||||
|
||||
<br>
|
||||
<HR>
|
||||
<TABLE>
|
||||
<TR valign=top>
|
||||
<TD nowrap>Copyright © 2013</TD><TD>
|
||||
Piotr Wygocki, University of Warsaw (<A HREF="mailto:wygos@mimuw.edu.pl">wygos at mimuw.edu.pl</A>)
|
||||
</TD></TR></TABLE>
|
||||
|
||||
</BODY>
|
||||
</HTML>
|
||||
<!-- LocalWords: HTML Siek Edmonds BGCOLOR ffffff ee VLINK ALINK ff IMG SRC
|
||||
-->
|
||||
<!-- LocalWords: gif ALT BR sec edmonds karp TT DIV CELLPADDING TR TD PRE lt
|
||||
-->
|
||||
<!-- LocalWords: typename VertexListGraph CapacityEdgeMap ReverseEdgeMap gt
|
||||
-->
|
||||
<!-- LocalWords: ResidualCapacityEdgeMap VertexIndexMap src rev ColorMap pred
|
||||
-->
|
||||
<!-- LocalWords: PredEdgeMap tt href html hpp ul li nbsp br LvaluePropertyMap
|
||||
-->
|
||||
<!-- LocalWords: num ColorValue DIMACS cpp pre config iostream dimacs int std
|
||||
-->
|
||||
<!-- LocalWords: namespace vecS directedS cout endl iter ei HR valign nowrap
|
||||
-->
|
||||
<!-- LocalWords: jeremy siek htm Univ mailto jsiek lsc edu
|
||||
p -->
|
||||
|
||||
@@ -552,6 +552,9 @@ f(u,v)</i>. The edges with <i>r(u,v) > 0</i> are residual edges
|
||||
The <b><i>maximum flow problem</i></b> is to determine the maximum
|
||||
possible value for <i>|f|</i> and the corresponding flow values for
|
||||
every vertex pair in the graph.
|
||||
<p>
|
||||
The <b><i>minimum cost maximum flow problem</i></b> is to determine the maximum flow which minimizes <i> sum<sub>(u,v) in E</sub>
|
||||
cost(u,v) * f(u,v) </i>.
|
||||
|
||||
<p>
|
||||
A flow network is shown in <a href="#fig:max-flow">Figure
|
||||
|
||||
58
doc/hawick_circuits.html
Normal file
58
doc/hawick_circuits.html
Normal file
@@ -0,0 +1,58 @@
|
||||
<p><body bgcolor="#ffffff" link="#0000ee" text="#000000" vlink="#551a8b" alink="#ff0000"></p>
|
||||
|
||||
<p><img src="../../../boost.png" alt="C++ Boost" /></p>
|
||||
|
||||
<h1 id="hawick_circuits"><code>hawick_circuits</code></h1>
|
||||
|
||||
<pre><code>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));
|
||||
</code></pre>
|
||||
|
||||
<p>Enumerate all the elementary circuits in a directed multigraph. Specifically,
|
||||
self-loops and redundant circuits caused by parallel edges are enumerated too.
|
||||
<code>hawick_unique_circuits</code> may be used if redundant circuits caused by parallel
|
||||
edges are not desired.</p>
|
||||
|
||||
<p>The algorithm is described in detail in
|
||||
<a href="http://www.massey.ac.nz/~kahawick/cstn/013/cstn-013.pdf">http://www.massey.ac.nz/~kahawick/cstn/013/cstn-013.pdf</a>.</p>
|
||||
|
||||
<h3 id="where-defined">Where defined</h3>
|
||||
|
||||
<p><a href="../../../boost/graph/hawick_circuits.hpp"><code>#include <boost/graph/hawick_circuits.hpp></code></a></p>
|
||||
|
||||
<h3 id="parameters">Parameters</h3>
|
||||
|
||||
<p><strong>IN:</strong> <code>Graph const& graph</code></p>
|
||||
|
||||
<blockquote>
|
||||
<p>The graph on which the algorithm is to be performed. It must be a model of
|
||||
the <code>VertexListGraph</code> and <code>AdjacencyGraph</code> concepts.</p>
|
||||
</blockquote>
|
||||
|
||||
<p><strong>IN:</strong> <code>Visitor visitor</code></p>
|
||||
|
||||
<blockquote>
|
||||
<p>The visitor that will be notified on each circuit found by the algorithm.
|
||||
The <code>visitor.cycle(circuit, graph)</code> expression must be valid, with <code>circuit</code>
|
||||
being a <code>const</code>-reference to a random access sequence of <code>vertex_descriptor</code>s.</p>
|
||||
|
||||
<p>For example, if a circuit <code>u -> v -> w -> u</code> exists in the graph, the
|
||||
visitor will be called with a sequence consisting of <code>(u, v, w)</code>.</p>
|
||||
</blockquote>
|
||||
|
||||
<p><strong>IN:</strong> <code>VertexIndexMap const& vim = get(vertex_index, graph)</code></p>
|
||||
|
||||
<blockquote>
|
||||
<p>A model of the <code>ReadablePropertyMap</code> concept mapping each <code>vertex_descriptor</code>
|
||||
to an integer in the range <code>[0, num_vertices(graph))</code>. It defaults to using
|
||||
the vertex index map provided by the <code>graph</code>.</p>
|
||||
</blockquote>
|
||||
|
||||
<hr />
|
||||
|
||||
<div class="footer">
|
||||
© 2013 Louis Dionne
|
||||
</div>
|
||||
53
doc/hawick_circuits.md
Normal file
53
doc/hawick_circuits.md
Normal file
@@ -0,0 +1,53 @@
|
||||
<body bgcolor="#ffffff" link="#0000ee" text="#000000" vlink="#551a8b" alink="#ff0000">
|
||||
|
||||

|
||||
|
||||
# `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>`](../../../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`.
|
||||
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
<div class="footer">
|
||||
© 2013 Louis Dionne
|
||||
</div>
|
||||
264
doc/successive_shortest_path_nonnegative_weights.html
Normal file
264
doc/successive_shortest_path_nonnegative_weights.html
Normal file
@@ -0,0 +1,264 @@
|
||||
<HTML>
|
||||
<!--
|
||||
Copyright (c) Piotr Wygocki 2013
|
||||
|
||||
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)
|
||||
-->
|
||||
<Head>
|
||||
<Title>Boost Graph Library: Successive Shortest Path for Min Cost Max Flow</Title>
|
||||
<BODY BGCOLOR="#ffffff" LINK="#0000ee" TEXT="#000000" VLINK="#551a8b"
|
||||
ALINK="#ff0000">
|
||||
<IMG SRC="../../../boost.png"
|
||||
ALT="C++ Boost" width="277" height="86">
|
||||
|
||||
<BR Clear>
|
||||
|
||||
<H1><A NAME="sec:successive_shortest_path_nonnegative_weights">
|
||||
<TT>successive_shortest_path_nonnegative_weights</TT>
|
||||
</H1>
|
||||
|
||||
<PRE>
|
||||
<i>// named parameter version</i>
|
||||
template <class <a href="./Graph.html">Graph</a>, 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 = <i>all defaults</i>)
|
||||
|
||||
<i>// non-named parameter version</i>
|
||||
template <class <a href="./Graph.html">Graph</a>, 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)
|
||||
</PRE>
|
||||
|
||||
<P>
|
||||
The <tt>successive_shortest_path_nonnegative_weights()</tt> function calculates the minimum cost maximum flow of a network. See Section <a
|
||||
href="./graph_theory_review.html#sec:network-flow-algorithms">Network
|
||||
Flow Algorithms</a> for a description of maximum flow.
|
||||
The function calculates the flow values <i>f(u,v)</i> for all <i>(u,v)</i> in
|
||||
<i>E</i>, which are returned in the form of the residual capacity
|
||||
<i>r(u,v) = c(u,v) - f(u,v)</i>.
|
||||
|
||||
<p>
|
||||
There are several special requirements on the input graph and property
|
||||
map parameters for this algorithm. First, the directed graph
|
||||
<i>G=(V,E)</i> that represents the network must be augmented to
|
||||
include the reverse edge for every edge in <i>E</i>. That is, the
|
||||
input graph should be <i>G<sub>in</sub> = (V,{E U
|
||||
E<sup>T</sup>})</i>. The <tt>ReverseEdgeMap</tt> argument <tt>rev</tt>
|
||||
must map each edge in the original graph to its reverse edge, that is
|
||||
<i>(u,v) -> (v,u)</i> for all <i>(u,v)</i> in <i>E</i>. The
|
||||
<tt>CapacityEdgeMap</tt> argument <tt>cap</tt> must map each edge in
|
||||
<i>E</i> to a positive number, and each edge in <i>E<sup>T</sup></i>
|
||||
to 0. The <tt>WeightMap</tt> has to map each edge from <i>E</i> to nonnegative number, and each edge from <i>E<sup>T</sup></i> to <i>-weight</i> of its reversed edge.
|
||||
|
||||
<p>
|
||||
The algorithm is described in <a
|
||||
href="./bibliography.html#ahuja93:_network_flows">Network Flows</a>.
|
||||
|
||||
<p>
|
||||
This algorithm starts with empty flow and in each round augments the shortest path (in terms of weight) in the residual graph.
|
||||
|
||||
<p>
|
||||
In order to find the cost of the result flow use:
|
||||
<a href="./find_flow_cost.html"><tt>find_flow_cost()</tt></a>.
|
||||
|
||||
<H3>Where Defined</H3>
|
||||
|
||||
<P>
|
||||
<a href="../../../boost/graph/successive_shortest_path_nonnegative_weights.hpp"><TT>boost/graph/successive_shortest_path_nonnegative_weights.hpp</TT></a>
|
||||
|
||||
<P>
|
||||
|
||||
<h3>Parameters</h3>
|
||||
|
||||
IN: <tt>Graph& g</tt>
|
||||
<blockquote>
|
||||
A directed graph. The
|
||||
graph's type must be a model of <a
|
||||
href="./VertexListGraph.html">VertexListGraph</a> and <a href="./IncidenceGraph.html">IncidenceGraph</a> For each edge
|
||||
<i>(u,v)</i> in the graph, the reverse edge <i>(v,u)</i> must also
|
||||
be in the graph.
|
||||
</blockquote>
|
||||
|
||||
IN: <tt>vertex_descriptor s</tt>
|
||||
<blockquote>
|
||||
The source vertex for the flow network graph.
|
||||
</blockquote>
|
||||
|
||||
IN: <tt>vertex_descriptor t</tt>
|
||||
<blockquote>
|
||||
The sink vertex for the flow network graph.
|
||||
</blockquote>
|
||||
|
||||
<h3>Named Parameters</h3>
|
||||
|
||||
|
||||
IN: <tt>capacity_map(CapacityEdgeMap cap)</tt>
|
||||
<blockquote>
|
||||
The edge capacity property map. The type must be a model of a
|
||||
constant <a
|
||||
href="../../property_map/doc/LvaluePropertyMap.html">Lvalue Property Map</a>. The
|
||||
key type of the map must be the graph's edge descriptor type.<br>
|
||||
<b>Default:</b> <tt>get(edge_capacity, g)</tt>
|
||||
</blockquote>
|
||||
|
||||
OUT: <tt>residual_capacity_map(ResidualCapacityEdgeMap res)</tt>
|
||||
<blockquote>
|
||||
This maps edges to their residual capacity. The type must be a model
|
||||
of a mutable <a
|
||||
href="../../property_map/doc/LvaluePropertyMap.html">Lvalue Property
|
||||
Map</a>. The key type of the map must be the graph's edge descriptor
|
||||
type.<br>
|
||||
<b>Default:</b> <tt>get(edge_residual_capacity, g)</tt>
|
||||
</blockquote>
|
||||
|
||||
IN: <tt>reverse_edge_map(ReverseEdgeMap rev)</tt>
|
||||
<blockquote>
|
||||
An edge property map that maps every edge <i>(u,v)</i> in the graph
|
||||
to the reverse edge <i>(v,u)</i>. The map must be a model of
|
||||
constant <a href="../../property_map/doc/LvaluePropertyMap.html">Lvalue
|
||||
Property Map</a>. The key type of the map must be the graph's edge
|
||||
descriptor type.<br>
|
||||
<b>Default:</b> <tt>get(edge_reverse, g)</tt>
|
||||
</blockquote>
|
||||
|
||||
IN: <tt>weight_map(WeightMap w_map)</tt>
|
||||
<blockquote>
|
||||
The weight or ``cost'' of each edge in the graph. The weights
|
||||
must all be non-negative, and the algorithm will throw a
|
||||
<a href="./exception.html#negative_edge"><tt>negative_edge</tt></a>
|
||||
exception if one of the edges is negative.
|
||||
The type <tt>WeightMap</tt> must be a model of
|
||||
<a href="../../property_map/doc/ReadablePropertyMap.html">Readable Property Map</a>. 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.<br>
|
||||
<b>Default:</b> <tt>get(edge_weight, g)</tt><br>
|
||||
|
||||
</blockquote>
|
||||
|
||||
UTIL: <tt>predecessor_map(PredEdgeMap pred)</tt>
|
||||
<blockquote>
|
||||
Use by the algorithm to store augmenting paths. The map must be a
|
||||
model of mutable <a
|
||||
href="../../property_map/doc/LvaluePropertyMap.html">Lvalue Property Map</a>.
|
||||
The key type must be the graph's vertex descriptor type and the
|
||||
value type must be the graph's edge descriptor type.<br>
|
||||
|
||||
<b>Default:</b> an <a
|
||||
href="../../property_map/doc/iterator_property_map.html">
|
||||
<tt>iterator_property_map</tt></a> created from a <tt>std::vector</tt>
|
||||
of edge descriptors of size <tt>num_vertices(g)</tt> and
|
||||
using the <tt>i_map</tt> for the index map.
|
||||
</blockquote>
|
||||
|
||||
UTIL: <tt>distance_map(DistanceMap d_map)</tt>
|
||||
<blockquote>
|
||||
The shortest path weight from the source vertex <tt>s</tt> to each
|
||||
vertex in the graph <tt>g</tt> is recorded in this property map. The
|
||||
shortest path weight is the sum of the edge weights along the
|
||||
shortest path. The type <tt>DistanceMap</tt> must be a model of <a
|
||||
href="../../property_map/doc/ReadWritePropertyMap.html">Read/Write
|
||||
Property Map</a>. The vertex descriptor type of the graph needs to
|
||||
be usable as the key type of the distance map.
|
||||
|
||||
<b>Default:</b> <a
|
||||
href="../../property_map/doc/iterator_property_map.html">
|
||||
<tt>iterator_property_map</tt></a> created from a
|
||||
<tt>std::vector</tt> of the <tt>WeightMap</tt>'s value type of size
|
||||
<tt>num_vertices(g)</tt> and using the <tt>i_map</tt> for the index
|
||||
map.<br>
|
||||
|
||||
</blockquote>
|
||||
|
||||
UTIL: <tt>distance_map2(DistanceMap2 d_map2)</tt>
|
||||
<blockquote>
|
||||
The shortest path computation in iteration nr <i>k</i> uses distances computed in iteration <i>k</i>.
|
||||
The type <tt>DistanceMap2</tt> must be a model of <a
|
||||
href="../../property_map/doc/ReadWritePropertyMap.html">Read/Write
|
||||
Property Map</a>. The vertex descriptor type of the graph needs to
|
||||
be usable as the key type of the distance map.
|
||||
|
||||
<b>Default:</b> <a
|
||||
href="../../property_map/doc/iterator_property_map.html">
|
||||
<tt>iterator_property_map</tt></a> created from a
|
||||
<tt>std::vector</tt> of the <tt>WeightMap</tt>'s value type of size
|
||||
<tt>num_vertices(g)</tt> and using the <tt>i_map</tt> for the index
|
||||
map.<br>
|
||||
|
||||
</blockquote>
|
||||
|
||||
IN: <tt>vertex_index_map(VertexIndexMap i_map)</tt>
|
||||
<blockquote>
|
||||
Maps each vertex of the graph to a unique integer in the range
|
||||
<tt>[0, num_vertices(g))</tt>. 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 <a
|
||||
href="../../property_map/doc/ReadablePropertyMap.html">Readable Property
|
||||
Map</a>. The key type of the map must be the graph's vertex
|
||||
descriptor type.<br>
|
||||
<b>Default:</b> <tt>get(vertex_index, g)</tt>
|
||||
Note: if you use this default, make sure your graph has
|
||||
an internal <tt>vertex_index</tt> property. For example,
|
||||
<tt>adjacenty_list</tt> with <tt>VertexList=listS</tt> does
|
||||
not have an internal <tt>vertex_index</tt> property.
|
||||
</blockquote>
|
||||
|
||||
|
||||
<h3>Complexity</h3>
|
||||
In the integer capacity case, if <i>U</i> is the value of the max flow, then the complexity is <i> O(U * (|E| + |V|*log|V|))</i>,
|
||||
where <i>O(|E| + |V|*log|V|)</i> is the complexity of the dijkstra algorithm and <i>U</i> is upper bound on number of iteration.
|
||||
In many real world cases number of iterations is much smaller than <i>U</i>.
|
||||
|
||||
|
||||
<h3>Example</h3>
|
||||
|
||||
The program in <a
|
||||
href="../example/successive_shortest_path_nonnegative_weights_example.cpp"><tt>example/successive_shortest_path_nonnegative_weights_example.cpp</tt></a>.
|
||||
|
||||
<h3>See Also</h3>
|
||||
|
||||
<a href="./cycle_canceling.html"><tt>cycle_canceling()</tt></a><br>
|
||||
<a href="./find_flow_cost.html"><tt>find_flow_cost()</tt></a>.
|
||||
|
||||
<br>
|
||||
<HR>
|
||||
<TABLE>
|
||||
<TR valign=top>
|
||||
<TD nowrap>Copyright © 2013</TD><TD>
|
||||
Piotr Wygocki, University of Warsaw (<A HREF="mailto:wygos@mimuw.edu.pl">wygos at mimuw.edu.pl</A>)
|
||||
</TD></TR></TABLE>
|
||||
|
||||
</BODY>
|
||||
</HTML>
|
||||
<!-- LocalWords: HTML Siek Edmonds BGCOLOR ffffff ee VLINK ALINK ff IMG SRC
|
||||
-->
|
||||
<!-- LocalWords: gif ALT BR sec edmonds karp TT DIV CELLPADDING TR TD PRE lt
|
||||
-->
|
||||
<!-- LocalWords: typename VertexListGraph CapacityEdgeMap ReverseEdgeMap gt
|
||||
-->
|
||||
<!-- LocalWords: ResidualCapacityEdgeMap VertexIndexMap src rev ColorMap pred
|
||||
-->
|
||||
<!-- LocalWords: PredEdgeMap tt href html hpp ul li nbsp br LvaluePropertyMap
|
||||
-->
|
||||
<!-- LocalWords: num ColorValue DIMACS cpp pre config iostream dimacs int std
|
||||
-->
|
||||
<!-- LocalWords: namespace vecS directedS cout endl iter ei HR valign nowrap
|
||||
-->
|
||||
<!-- LocalWords: jeremy siek htm Univ mailto jsiek lsc edu
|
||||
p -->
|
||||
|
||||
@@ -214,6 +214,12 @@
|
||||
<li><a href="boykov_kolmogorov_max_flow.html"><tt>boykov_kolmogorov_max_flow</tt></a></li>
|
||||
<LI><A href="maximum_matching.html"><tt>edmonds_maximum_cardinality_matching</tt></A>
|
||||
</OL>
|
||||
<LI>Minimum Cost Maximum Flow Algorithms
|
||||
<OL>
|
||||
<LI><A href="cycle_canceling.html"><tt>cycle_canceling</tt></A>
|
||||
<LI><A href="successive_shortest_path_nonnegative_weights.html"><tt>successive_shortest_path_nonnegative_weights</tt></A>
|
||||
<li><a href="find_flow_cost.html"><tt>find_flow_cost</tt></a></li>
|
||||
</OL>
|
||||
<LI>Minimum Cut Algorithms
|
||||
<OL>
|
||||
<LI><A href="stoer_wagner_min_cut.html"><tt>stoer_wagner_min_cut</tt></A>
|
||||
@@ -284,10 +290,12 @@
|
||||
<li>Miscellaneous Algorithms
|
||||
<ol>
|
||||
<li><a href="metric_tsp_approx.html"><tt>metric_tsp_approx</tt></a></li>
|
||||
<LI><A href="sequential_vertex_coloring.html"><tt>sequential_vertex_coloring</tt></A>
|
||||
<LI><A href="is_bipartite.html"><tt>is_bipartite</tt></A> (including two-coloring of bipartite graphs)
|
||||
<LI><A href="find_odd_cycle.html"><tt>find_odd_cycle</tt></A>
|
||||
<LI><A href="maximum_adjacency_search.html"><tt>maximum_adjacency_search</tt></A>
|
||||
<LI><A href="sequential_vertex_coloring.html"><tt>sequential_vertex_coloring</tt></A></li>
|
||||
<LI><A href="edge_coloring.html"><tt>edge_coloring</tt></A></li>
|
||||
<LI><A href="is_bipartite.html"><tt>is_bipartite</tt></A> (including two-coloring of bipartite graphs)</li>
|
||||
<LI><A href="find_odd_cycle.html"><tt>find_odd_cycle</tt></A></li>
|
||||
<LI><A href="maximum_adjacency_search.html"><tt>maximum_adjacency_search</tt></A></li>
|
||||
<LI><A href="hawick_circuits.html"><tt>hawick_circuits</tt></A> (find all circuits of a directed graph)</li>
|
||||
</ol>
|
||||
</li>
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
-->
|
||||
<Head>
|
||||
<Title>Boost Graph Library: Depth-First Search</Title>
|
||||
<Title>Boost Graph Library: Undirected Depth-First Search</Title>
|
||||
<BODY BGCOLOR="#ffffff" LINK="#0000ee" TEXT="#000000" VLINK="#551a8b"
|
||||
ALINK="#ff0000">
|
||||
<IMG SRC="../../../boost.png"
|
||||
@@ -116,6 +116,7 @@ DFS-VISIT(<i>G</i>, <i>u</i>)
|
||||
<b>call</b> DFS-VISIT(<i>G</i>, <i>v</i>)
|
||||
<b>else if</b> (<i>vcolor[v] =</i> GRAY and <i>ec =</i> WHITE)
|
||||
<i>...</i>
|
||||
<i>...</i>
|
||||
<b>end for</b>
|
||||
<i>vcolor[u] :=</i> BLACK
|
||||
<i>f_time[u] := time := time + 1</i>
|
||||
@@ -152,6 +153,8 @@ examine edge <i>(u,v)</i>
|
||||
<i>(u,v)</i> is a back edge
|
||||
-
|
||||
-
|
||||
finish edge <i>(u,v)</i>
|
||||
-
|
||||
finish vertex <i>u</i>
|
||||
-
|
||||
</pre>
|
||||
@@ -291,6 +294,9 @@ The time complexity is <i>O(E + V)</i>.
|
||||
<li><b><tt>vis.back_edge(e, g)</tt></b> is invoked on the back edges in
|
||||
the graph.
|
||||
|
||||
<li><b><tt>vis.finish_edge(e, g)</tt></b> is invoked on the back edges in
|
||||
the graph as well as on each tree edge after its target vertex is finished.
|
||||
|
||||
<li><b><tt>vis.finish_vertex(u, g)</tt></b> 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
|
||||
|
||||
@@ -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 ;
|
||||
|
||||
|
||||
@@ -118,7 +118,6 @@ int main(int argc, char **argv)
|
||||
typedef property_map<mygraph_t, edge_weight_t>::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<int, int> edge;
|
||||
|
||||
// specify data
|
||||
@@ -196,7 +195,8 @@ int main(int argc, char **argv)
|
||||
(g, start,
|
||||
distance_heuristic<mygraph_t, cost, location*>
|
||||
(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<vertex>(goal)));
|
||||
|
||||
|
||||
|
||||
@@ -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<std::vector<Size>::iterator,
|
||||
property_map<graph_t, vertex_index_t>::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)
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <boost/graph/breadth_first_search.hpp>
|
||||
#include <boost/pending/indirect_cmp.hpp>
|
||||
#include <boost/range/irange.hpp>
|
||||
#include <boost/property_map/property_map.hpp>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
@@ -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<graph_t>::vertex_descriptor Vertex;
|
||||
typedef graph_traits<graph_t>::vertices_size_type Size;
|
||||
typedef Size* Iiter;
|
||||
|
||||
Size time = 0;
|
||||
typedef property_map<graph_t, std::size_t VertexProps::*>::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<std::vector<Size>::iterator,
|
||||
property_map<graph_t, unsigned int VertexProps::*>::type>
|
||||
dtime_pm_type;
|
||||
graph_traits<graph_t>::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<graph_traits<graph_t>::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<Size>(),
|
||||
make_iterator_property_map(
|
||||
dtime.begin(),
|
||||
typed_identity_property_map<std::size_t>())));
|
||||
|
||||
std::cout << "order of discovery: ";
|
||||
for (int i = 0; i < N; ++i)
|
||||
|
||||
@@ -64,7 +64,8 @@ int main(int argc, char** argv)
|
||||
std::vector<vec_t> 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();
|
||||
|
||||
28
example/cycle_canceling_example.cpp
Normal file
28
example/cycle_canceling_example.cpp
Normal file
@@ -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 <boost/graph/cycle_canceling.hpp>
|
||||
#include <boost/graph/edmonds_karp_max_flow.hpp>
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
@@ -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<std::vector<size_type>::iterator,
|
||||
property_map<graph_t, vertex_index_t>::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]] << " ";
|
||||
|
||||
@@ -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<VisitorList> {
|
||||
<< " --> " << target(e, G) << endl;
|
||||
Base::forward_or_cross_edge(e, G);
|
||||
}
|
||||
template <class Edge, class Graph>
|
||||
void finish_edge(Edge e, Graph& G) {
|
||||
cout << "Finish edge: " << source(e, G) <<
|
||||
" --> " << target(e, G) << endl;
|
||||
Base::finish_edge(e, G);
|
||||
}
|
||||
};
|
||||
template <class VisitorList>
|
||||
edge_categorizer<VisitorList>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -26,7 +26,6 @@ main(int, char *[])
|
||||
property<vertex_distance_t, int,
|
||||
property<vertex_predecessor_t, vertex_descriptor> > > >,
|
||||
property<edge_weight_t, int> > graph_t;
|
||||
typedef graph_traits<graph_t>::edge_descriptor edge_descriptor;
|
||||
typedef std::pair<int, int> Edge;
|
||||
|
||||
const int num_nodes = 5;
|
||||
|
||||
@@ -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<int, int> Edge;
|
||||
|
||||
const int num_nodes = 5;
|
||||
|
||||
@@ -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<int, int> Edge;
|
||||
|
||||
const int num_nodes = 5;
|
||||
|
||||
70
example/edge_coloring.cpp
Normal file
70
example/edge_coloring.cpp
Normal file
@@ -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 <boost/config.hpp>
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/graph/edge_coloring.hpp>
|
||||
#include <boost/graph/properties.hpp>
|
||||
|
||||
/*
|
||||
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<vecS, vecS, undirectedS, no_property, size_t, no_property> Graph;
|
||||
|
||||
typedef std::pair<std::size_t, std::size_t> 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;
|
||||
}
|
||||
|
||||
96
example/hawick_circuits.cpp
Normal file
96
example/hawick_circuits.cpp
Normal file
@@ -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 <boost/assert.hpp>
|
||||
#include <boost/graph/directed_graph.hpp>
|
||||
#include <boost/graph/graph_traits.hpp>
|
||||
#include <boost/graph/hawick_circuits.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <boost/next_prior.hpp>
|
||||
#include <boost/property_map/property_map.hpp>
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
#include <iterator>
|
||||
#include <map>
|
||||
|
||||
|
||||
template <typename OutputStream>
|
||||
struct cycle_printer
|
||||
{
|
||||
cycle_printer(OutputStream& stream)
|
||||
: os(stream)
|
||||
{ }
|
||||
|
||||
template <typename Path, typename Graph>
|
||||
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 <typename Graph, typename VertexPairIterator>
|
||||
void build_graph(Graph& graph, unsigned int const nvertices,
|
||||
VertexPairIterator first, VertexPairIterator last) {
|
||||
typedef boost::graph_traits<Graph> Traits;
|
||||
typedef typename Traits::vertex_descriptor vertex_descriptor;
|
||||
std::map<unsigned int, vertex_descriptor> 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<unsigned int>(argv[1]);
|
||||
std::istream_iterator<unsigned int> first_vertex(std::cin), last_vertex;
|
||||
boost::directed_graph<> graph;
|
||||
build_graph(graph, num_vertices, first_vertex, last_vertex);
|
||||
|
||||
cycle_printer<std::ostream> visitor(std::cout);
|
||||
boost::hawick_circuits(graph, visitor);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
@@ -527,10 +527,16 @@ int main (int argc, char const *argv[]) {
|
||||
vertex_descriptor source = 0;
|
||||
std::vector<vertex_descriptor> pred(num_vertices(g));
|
||||
std::vector<edge_weight_map_value_type> dist(num_vertices(g));
|
||||
iterator_property_map<std::vector<vertex_descriptor>::iterator,
|
||||
property_map<ring_graph, vertex_index_t>::const_type>
|
||||
pred_pm(pred.begin(), get(vertex_index, g));
|
||||
iterator_property_map<std::vector<edge_weight_map_value_type>::iterator,
|
||||
property_map<ring_graph, vertex_index_t>::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) {
|
||||
|
||||
@@ -76,11 +76,7 @@ int main (int argc, char *argv[]) {
|
||||
property<vertex_index_t, unsigned int> >,
|
||||
property<edge_name_t, unsigned int> > Graph;
|
||||
|
||||
typedef graph_traits<Graph>::vertex_descriptor Vertex;
|
||||
typedef graph_traits<Graph>::edge_descriptor Edge;
|
||||
|
||||
typedef property_map<Graph, vertex_name_t>::type VertexNameMap;
|
||||
typedef property_map<Graph, edge_name_t>::type EdgeNameMap;
|
||||
|
||||
// Test maximum and unique variants on known graphs
|
||||
Graph graph_simple1, graph_simple2;
|
||||
|
||||
@@ -27,7 +27,6 @@ int main()
|
||||
|
||||
typedef boost::adjacency_list<boost::vecS, boost::vecS, boost::undirectedS,
|
||||
boost::no_property, boost::property<boost::edge_weight_t, int> > undirected_graph;
|
||||
typedef boost::graph_traits<undirected_graph>::vertex_descriptor vertex_descriptor;
|
||||
typedef boost::property_map<undirected_graph, boost::edge_weight_t>::type weight_map_type;
|
||||
typedef boost::property_traits<weight_map_type>::value_type weight_type;
|
||||
|
||||
|
||||
@@ -41,7 +41,6 @@
|
||||
int main(int,char*[])
|
||||
{
|
||||
using namespace boost;
|
||||
typedef adjacency_list_traits<vecS, vecS, directedS> Traits;
|
||||
typedef subgraph< adjacency_list<vecS, vecS, directedS,
|
||||
property<vertex_color_t, int>, property<edge_index_t, int> > > Graph;
|
||||
|
||||
|
||||
@@ -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 <boost/graph/successive_shortest_path_nonnegative_weights.hpp>
|
||||
#include <boost/graph/find_flow_cost.hpp>
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -102,8 +102,6 @@ namespace boost {
|
||||
typedef typename GTraits::vertex_descriptor Vertex;
|
||||
BOOST_CONCEPT_ASSERT(( ReadWritePropertyMapConcept<DistanceMap, Vertex> ));
|
||||
BOOST_CONCEPT_ASSERT(( ReadablePropertyMapConcept<WeightMap, Edge> ));
|
||||
typedef typename property_traits<DistanceMap>::value_type D_value;
|
||||
typedef typename property_traits<WeightMap>::value_type W_value;
|
||||
|
||||
typename GTraits::edge_iterator i, end;
|
||||
|
||||
|
||||
@@ -296,7 +296,6 @@ namespace detail { namespace graph {
|
||||
ShortestPaths shortest_paths)
|
||||
{
|
||||
typedef typename graph_traits<Graph>::vertex_iterator vertex_iterator;
|
||||
typedef typename graph_traits<Graph>::edge_iterator edge_iterator;
|
||||
typedef typename graph_traits<Graph>::vertex_descriptor vertex_descriptor;
|
||||
|
||||
// Initialize centrality
|
||||
@@ -421,7 +420,6 @@ namespace detail { namespace graph {
|
||||
VertexIndexMap vertex_index)
|
||||
{
|
||||
typedef typename graph_traits<Graph>::degree_size_type degree_size_type;
|
||||
typedef typename graph_traits<Graph>::vertex_descriptor vertex_descriptor;
|
||||
typedef typename graph_traits<Graph>::edge_descriptor edge_descriptor;
|
||||
typedef typename mpl::if_c<(is_same<CentralityMap,
|
||||
dummy_property_map>::value),
|
||||
@@ -457,7 +455,6 @@ namespace detail { namespace graph {
|
||||
VertexIndexMap vertex_index)
|
||||
{
|
||||
typedef typename graph_traits<Graph>::degree_size_type degree_size_type;
|
||||
typedef typename graph_traits<Graph>::vertex_descriptor vertex_descriptor;
|
||||
typedef typename graph_traits<Graph>::edge_descriptor edge_descriptor;
|
||||
typedef typename mpl::if_c<(is_same<CentralityMap,
|
||||
dummy_property_map>::value),
|
||||
|
||||
@@ -198,7 +198,6 @@ namespace boost {
|
||||
/// General types and variables
|
||||
typedef typename property_traits <PartitionMap>::value_type partition_color_t;
|
||||
typedef typename graph_traits <Graph>::vertex_descriptor vertex_descriptor_t;
|
||||
typedef typename graph_traits <Graph>::vertex_iterator vertex_iterator_t;
|
||||
|
||||
/// Declare dfs visitor
|
||||
// detail::empty_recorder recorder;
|
||||
|
||||
@@ -64,7 +64,6 @@ namespace boost {
|
||||
BOOST_CONCEPT_ASSERT(( IncidenceGraphConcept<IncidenceGraph> ));
|
||||
typedef graph_traits<IncidenceGraph> GTraits;
|
||||
typedef typename GTraits::vertex_descriptor Vertex;
|
||||
typedef typename GTraits::edge_descriptor Edge;
|
||||
BOOST_CONCEPT_ASSERT(( BFSVisitorConcept<BFSVisitor, IncidenceGraph> ));
|
||||
BOOST_CONCEPT_ASSERT(( ReadWritePropertyMapConcept<ColorMap, Vertex> ));
|
||||
typedef typename property_traits<ColorMap>::value_type ColorValue;
|
||||
@@ -248,8 +247,7 @@ namespace boost {
|
||||
ColorMap color,
|
||||
BFSVisitor vis,
|
||||
const bgl_named_params<P, T, R>& params,
|
||||
BOOST_GRAPH_ENABLE_IF_MODELS(VertexListGraph, vertex_list_graph_tag,
|
||||
void)* = 0)
|
||||
boost::mpl::false_)
|
||||
{
|
||||
typedef graph_traits<VertexListGraph> Traits;
|
||||
// Buffer default
|
||||
@@ -271,8 +269,7 @@ namespace boost {
|
||||
ColorMap color,
|
||||
BFSVisitor vis,
|
||||
const bgl_named_params<P, T, R>& 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<VertexListGraph>::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<VertexListGraph>::traversal_category>::value>());
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -73,7 +73,6 @@ namespace boost
|
||||
{
|
||||
|
||||
typedef typename graph_traits<Graph>::vertex_descriptor vertex_t;
|
||||
typedef typename graph_traits<Graph>::edge_descriptor edge_t;
|
||||
typedef typename graph_traits<Graph>::vertex_iterator vertex_iterator_t;
|
||||
typedef typename PlanarEmbedding::value_type::const_iterator
|
||||
edge_permutation_iterator_t;
|
||||
|
||||
@@ -123,7 +123,6 @@ all_closeness_centralities(const Graph& g,
|
||||
typedef typename property_traits<DistanceMatrixMap>::value_type DistanceMap;
|
||||
BOOST_CONCEPT_ASSERT(( ReadablePropertyMapConcept<DistanceMap,Vertex> ));
|
||||
BOOST_CONCEPT_ASSERT(( WritablePropertyMapConcept<CentralityMap,Vertex> ));
|
||||
typedef typename property_traits<DistanceMap>::value_type Distance;
|
||||
typedef typename property_traits<CentralityMap>::value_type Centrality;
|
||||
|
||||
typename graph_traits<Graph>::vertex_iterator i, end;
|
||||
@@ -147,7 +146,6 @@ all_closeness_centralities(const Graph& g,
|
||||
BOOST_CONCEPT_ASSERT(( ReadablePropertyMapConcept<DistanceMatrixMap,Vertex> ));
|
||||
typedef typename property_traits<DistanceMatrixMap>::value_type DistanceMap;
|
||||
BOOST_CONCEPT_ASSERT(( ReadablePropertyMapConcept<DistanceMap,Vertex> ));
|
||||
typedef typename property_traits<DistanceMap>::value_type Distance;
|
||||
typedef typename property_traits<CentralityMap>::value_type Result;
|
||||
|
||||
all_closeness_centralities(g, dist, cent, measure_closeness<Result>(g, DistanceMap()));
|
||||
|
||||
@@ -192,6 +192,11 @@ class compressed_sparse_row_graph<directedS, VertexProperty, EdgeProperty, Graph
|
||||
VertexProperty, Vertex, typed_identity_property_map<Vertex> >
|
||||
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<VertexProperty, void>::value));
|
||||
BOOST_STATIC_ASSERT((!is_same<EdgeProperty, void>::value));
|
||||
BOOST_STATIC_ASSERT((!is_same<GraphProperty, void>::value));
|
||||
|
||||
public:
|
||||
// For Property Graph
|
||||
typedef GraphProperty graph_property_type;
|
||||
|
||||
@@ -86,7 +86,7 @@ namespace boost {
|
||||
|
||||
typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
|
||||
BOOST_CONCEPT_ASSERT(( WritablePropertyMapConcept<ComponentMap, Vertex> ));
|
||||
typedef typename boost::graph_traits<Graph>::directed_category directed;
|
||||
// typedef typename boost::graph_traits<Graph>::directed_category directed;
|
||||
// BOOST_STATIC_ASSERT((boost::is_same<directed, undirected_tag>::value));
|
||||
|
||||
typedef typename property_traits<ComponentMap>::value_type comp_type;
|
||||
|
||||
@@ -316,7 +316,6 @@ namespace boost {
|
||||
core_numbers(Graph& g, CoreMap c, EdgeWeightMap wm, VertexIndexMap vim,
|
||||
CoreNumVisitor vis)
|
||||
{
|
||||
typedef typename graph_traits<Graph>::vertices_size_type size_type;
|
||||
detail::compute_in_degree_map(g,c,wm);
|
||||
return detail::core_numbers_dispatch(g,c,wm,vim,vis);
|
||||
}
|
||||
|
||||
@@ -75,7 +75,6 @@ namespace boost {
|
||||
{
|
||||
|
||||
//create queue, visitor...don't forget namespaces!
|
||||
typedef typename property_traits<DegreeMap>::value_type ds_type;
|
||||
typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
|
||||
typedef typename boost::sparse::sparse_ordering_queue<Vertex> queue;
|
||||
typedef typename detail::bfs_rcm_visitor<OutputIterator, queue, DegreeMap> Visitor;
|
||||
@@ -137,7 +136,6 @@ namespace boost {
|
||||
return permutation;
|
||||
|
||||
typedef typename boost::graph_traits<Graph>::vertex_descriptor Vertex;
|
||||
typedef typename boost::graph_traits<Graph>::vertex_iterator VerIter;
|
||||
typedef typename property_traits<ColorMap>::value_type ColorValue;
|
||||
typedef color_traits<ColorValue> Color;
|
||||
|
||||
@@ -172,7 +170,6 @@ namespace boost {
|
||||
if (boost::graph::has_no_vertices(G))
|
||||
return permutation;
|
||||
|
||||
typedef out_degree_property_map<Graph> DegreeMap;
|
||||
std::vector<default_color_type> colors(num_vertices(G));
|
||||
return cuthill_mckee_ordering(G, permutation,
|
||||
make_iterator_property_map(&colors[0],
|
||||
|
||||
181
include/boost/graph/cycle_canceling.hpp
Normal file
181
include/boost/graph/cycle_canceling.hpp
Normal file
@@ -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 <numeric>
|
||||
|
||||
#include <boost/property_map/property_map.hpp>
|
||||
#include <boost/graph/graph_traits.hpp>
|
||||
#include <boost/graph/graph_concepts.hpp>
|
||||
#include <boost/pending/indirect_cmp.hpp>
|
||||
#include <boost/pending/relaxed_heap.hpp>
|
||||
#include <boost/graph/bellman_ford_shortest_paths.hpp>
|
||||
#include <boost/graph/iteration_macros.hpp>
|
||||
#include <boost/graph/detail/augment.hpp>
|
||||
#include <boost/graph/find_flow_cost.hpp>
|
||||
|
||||
namespace boost {
|
||||
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <typename PredEdgeMap, typename Vertex>
|
||||
class RecordEdgeMapAndCycleVertex
|
||||
: public bellman_visitor<edge_predecessor_recorder<PredEdgeMap, on_edge_relaxed> > {
|
||||
typedef edge_predecessor_recorder<PredEdgeMap, on_edge_relaxed> PredRec;
|
||||
public:
|
||||
RecordEdgeMapAndCycleVertex(PredEdgeMap pred, Vertex & v) :
|
||||
bellman_visitor<PredRec>(PredRec(pred)), m_v(v), m_pred(pred) {}
|
||||
|
||||
template <typename Graph, typename Edge>
|
||||
void edge_not_minimized(Edge e, const Graph & g) const {
|
||||
typename graph_traits<Graph>::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 <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) {
|
||||
typedef filtered_graph<const Graph, is_residual_edge<ResidualCapacity> > ResGraph;
|
||||
ResGraph gres = detail::residual_graph(g, residual_capacity);
|
||||
|
||||
typedef graph_traits<ResGraph> ResGTraits;
|
||||
typedef graph_traits<Graph> 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, vertex_descriptor>(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 <class Graph, class P, class T, class R, class ResidualCapacity, class Weight, class Reversed, class Pred, class Distance>
|
||||
void cycle_canceling_dispatch2(
|
||||
const Graph &g,
|
||||
Weight weight,
|
||||
Reversed rev,
|
||||
ResidualCapacity residual_capacity,
|
||||
Pred pred,
|
||||
Distance dist,
|
||||
const bgl_named_params<P, T, R>& params) {
|
||||
cycle_canceling(g, weight, rev, residual_capacity, pred, dist);
|
||||
}
|
||||
|
||||
//setting default distance map
|
||||
template <class Graph, class P, class T, class R, class Pred, class ResidualCapacity, class Weight, class Reversed>
|
||||
void cycle_canceling_dispatch2(
|
||||
Graph &g,
|
||||
Weight weight,
|
||||
Reversed rev,
|
||||
ResidualCapacity residual_capacity,
|
||||
Pred pred,
|
||||
param_not_found,
|
||||
const bgl_named_params<P, T, R>& params) {
|
||||
typedef typename property_traits<Weight>::value_type D;
|
||||
|
||||
std::vector<D> 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 <class Graph, class P, class T, class R, class ResidualCapacity, class Weight, class Reversed, class Pred>
|
||||
void cycle_canceling_dispatch1(
|
||||
Graph &g,
|
||||
Weight weight,
|
||||
Reversed rev,
|
||||
ResidualCapacity residual_capacity,
|
||||
Pred pred,
|
||||
const bgl_named_params<P, T, R>& params) {
|
||||
cycle_canceling_dispatch2(g, weight, rev,residual_capacity, pred,
|
||||
get_param(params, vertex_distance), params);
|
||||
}
|
||||
|
||||
//setting default predecessors map
|
||||
template <class Graph, class P, class T, class R, class ResidualCapacity, class Weight, class Reversed>
|
||||
void cycle_canceling_dispatch1(
|
||||
Graph &g,
|
||||
Weight weight,
|
||||
Reversed rev,
|
||||
ResidualCapacity residual_capacity,
|
||||
param_not_found,
|
||||
const bgl_named_params<P, T, R>& params) {
|
||||
typedef typename graph_traits<Graph>::edge_descriptor edge_descriptor;
|
||||
std::vector<edge_descriptor> 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 <class Graph, class P, class T, class R>
|
||||
void cycle_canceling(Graph &g,
|
||||
const bgl_named_params<P, T, R>& 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 <class Graph>
|
||||
void cycle_canceling(Graph &g) {
|
||||
bgl_named_params<int, buffer_param_t> params(0);
|
||||
cycle_canceling(g, params);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif /* BOOST_GRAPH_CYCLE_CANCELING_HPP */
|
||||
|
||||
@@ -21,8 +21,10 @@
|
||||
#include <boost/graph/named_function_params.hpp>
|
||||
#include <boost/ref.hpp>
|
||||
#include <boost/implicit_cast.hpp>
|
||||
#include <boost/optional.hpp>
|
||||
#include <boost/parameter.hpp>
|
||||
#include <boost/concept/assert.hpp>
|
||||
#include <boost/tti/has_member_function.hpp>
|
||||
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
@@ -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 <bool IsCallable> struct do_call_finish_edge {
|
||||
template <typename E, typename G, typename Vis>
|
||||
static void call_finish_edge(Vis& vis, const E& e, const G& g) {
|
||||
vis.finish_edge(e, g);
|
||||
}
|
||||
};
|
||||
|
||||
template <> struct do_call_finish_edge<false> {
|
||||
template <typename E, typename G, typename Vis>
|
||||
static void call_finish_edge(Vis&, const E&, const G&) {}
|
||||
};
|
||||
|
||||
template <typename E, typename G, typename Vis>
|
||||
void call_finish_edge(Vis& vis, const E& e, const G& g) { // Only call if method exists
|
||||
do_call_finish_edge<has_member_function_finish_edge<Vis, void>::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<IncidenceGraph> ));
|
||||
BOOST_CONCEPT_ASSERT(( DFSVisitorConcept<DFSVisitor, IncidenceGraph> ));
|
||||
typedef typename graph_traits<IncidenceGraph>::vertex_descriptor Vertex;
|
||||
typedef typename graph_traits<IncidenceGraph>::edge_descriptor Edge;
|
||||
BOOST_CONCEPT_ASSERT(( ReadWritePropertyMapConcept<ColorMap, Vertex> ));
|
||||
typedef typename property_traits<ColorMap>::value_type ColorValue;
|
||||
BOOST_CONCEPT_ASSERT(( ColorValueConcept<ColorValue> ));
|
||||
typedef color_traits<ColorValue> Color;
|
||||
typedef typename graph_traits<IncidenceGraph>::out_edge_iterator Iter;
|
||||
typedef std::pair<Vertex, std::pair<Iter, Iter> > VertexInfo;
|
||||
typedef std::pair<Vertex, std::pair<boost::optional<Edge>, std::pair<Iter, Iter> > > VertexInfo;
|
||||
|
||||
boost::optional<Edge> src_e;
|
||||
Iter ei, ei_end;
|
||||
std::vector<VertexInfo> stack;
|
||||
|
||||
// Possible optimization for vector
|
||||
//stack.reserve(num_vertices(g));
|
||||
|
||||
typedef typename unwrap_reference<TerminatorFunc>::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<TF&>(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<Edge>(), 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<Edge>(), 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<TerminatorFunc>::type TF;
|
||||
// Variable is needed to workaround a borland bug.
|
||||
TF& fn = static_cast<TF&>(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 <class Edge, class Graph>
|
||||
void finish_edge(Edge u, const Graph& g) {
|
||||
invoke_visitors(m_vis, u, g, ::boost::on_finish_edge());
|
||||
}
|
||||
template <class Vertex, class Graph>
|
||||
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:
|
||||
|
||||
@@ -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);
|
||||
|
||||
63
include/boost/graph/detail/augment.hpp
Normal file
63
include/boost/graph/detail/augment.hpp
Normal file
@@ -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 <boost/graph/filtered_graph.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace detail {
|
||||
|
||||
template <class Graph, class ResCapMap>
|
||||
filtered_graph<const Graph, is_residual_edge<ResCapMap> >
|
||||
residual_graph(const Graph& g, ResCapMap residual_capacity) {
|
||||
return filtered_graph<const Graph, is_residual_edge<ResCapMap> >
|
||||
(g, is_residual_edge<ResCapMap>(residual_capacity));
|
||||
}
|
||||
|
||||
template <class Graph, class PredEdgeMap, class ResCapMap,
|
||||
class RevEdgeMap>
|
||||
inline void
|
||||
augment(const Graph& g,
|
||||
typename graph_traits<Graph>::vertex_descriptor src,
|
||||
typename graph_traits<Graph>::vertex_descriptor sink,
|
||||
PredEdgeMap p,
|
||||
ResCapMap residual_capacity,
|
||||
RevEdgeMap reverse_edge)
|
||||
{
|
||||
typename graph_traits<Graph>::edge_descriptor e;
|
||||
typename graph_traits<Graph>::vertex_descriptor u;
|
||||
typedef typename property_traits<ResCapMap>::value_type FlowValue;
|
||||
|
||||
// find minimum residual capacity along the augmenting path
|
||||
FlowValue delta = (std::numeric_limits<FlowValue>::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 */
|
||||
|
||||
@@ -118,6 +118,7 @@ namespace boost {
|
||||
struct dijkstra_bfs_visitor
|
||||
{
|
||||
typedef typename property_traits<DistanceMap>::value_type D;
|
||||
typedef typename property_traits<WeightMap>::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 <class Edge, class Graph>
|
||||
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 <class Edge, class Graph>
|
||||
void black_target(Edge, Graph&) { }
|
||||
@@ -255,6 +282,31 @@ namespace boost {
|
||||
};
|
||||
}
|
||||
|
||||
// Call breadth first search with default color map.
|
||||
template <class Graph, class SourceInputIter, class DijkstraVisitor,
|
||||
class PredecessorMap, class DistanceMap,
|
||||
class WeightMap, class IndexMap, class Compare, class Combine,
|
||||
class DistZero>
|
||||
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<Graph, IndexMap>
|
||||
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 <class Graph, class DijkstraVisitor,
|
||||
class PredecessorMap, class DistanceMap,
|
||||
@@ -269,26 +321,20 @@ namespace boost {
|
||||
Compare compare, Combine combine, DistZero zero,
|
||||
DijkstraVisitor vis)
|
||||
{
|
||||
typedef
|
||||
detail::default_color_map_generator<Graph, IndexMap>
|
||||
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 <class Graph, class DijkstraVisitor,
|
||||
template <class Graph, class SourceInputIter, class DijkstraVisitor,
|
||||
class PredecessorMap, class DistanceMap,
|
||||
class WeightMap, class IndexMap, class Compare, class Combine,
|
||||
class DistZero, class ColorMap>
|
||||
inline void
|
||||
dijkstra_shortest_paths_no_init
|
||||
(const Graph& g,
|
||||
typename graph_traits<Graph>::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 <class Graph, class DijkstraVisitor,
|
||||
class PredecessorMap, class DistanceMap,
|
||||
class WeightMap, class IndexMap, class Compare, class Combine,
|
||||
class DistZero, class ColorMap>
|
||||
inline void
|
||||
dijkstra_shortest_paths_no_init
|
||||
(const Graph& g,
|
||||
typename graph_traits<Graph>::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 <class VertexListGraph, class SourceInputIter, class DijkstraVisitor,
|
||||
class PredecessorMap, class DistanceMap,
|
||||
class WeightMap, class IndexMap, class Compare, class Combine,
|
||||
class DistInf, class DistZero, typename T, typename Tag,
|
||||
typename Base>
|
||||
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<T, Tag, Base>&
|
||||
BOOST_GRAPH_ENABLE_IF_MODELS_PARM(VertexListGraph,vertex_list_graph_tag))
|
||||
{
|
||||
boost::two_bit_color_map<IndexMap> 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<T, Tag, Base>&
|
||||
BOOST_GRAPH_ENABLE_IF_MODELS_PARM(VertexListGraph,vertex_list_graph_tag))
|
||||
{
|
||||
boost::two_bit_color_map<IndexMap> 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 <class VertexListGraph, class SourceInputIter, class DijkstraVisitor,
|
||||
class PredecessorMap, class DistanceMap,
|
||||
class WeightMap, class IndexMap, class Compare, class Combine,
|
||||
class DistInf, class DistZero, class ColorMap>
|
||||
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<ColorMap>::value_type ColorValue;
|
||||
typedef color_traits<ColorValue> Color;
|
||||
typename graph_traits<VertexListGraph>::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<ColorMap>::value_type ColorValue;
|
||||
typedef color_traits<ColorValue> Color;
|
||||
typename graph_traits<VertexListGraph>::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 <class VertexListGraph, class SourceInputIter,
|
||||
class DijkstraVisitor,
|
||||
class PredecessorMap, class DistanceMap,
|
||||
class WeightMap, class IndexMap, class Compare, class Combine,
|
||||
class DistInf, class DistZero>
|
||||
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 {
|
||||
|
||||
@@ -41,7 +41,6 @@ namespace boost {
|
||||
{
|
||||
typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
|
||||
typedef typename property_traits<DistanceMap>::value_type Distance;
|
||||
typedef typename property_traits<WeightMap>::value_type Weight;
|
||||
|
||||
typedef indirect_cmp<DistanceMap, DistanceCompare> DistanceIndirectCompare;
|
||||
DistanceIndirectCompare
|
||||
@@ -92,7 +91,6 @@ namespace boost {
|
||||
}
|
||||
|
||||
// Examine neighbors of min_vertex
|
||||
typedef typename graph_traits<Graph>::edge_descriptor Edge;
|
||||
BGL_FORALL_OUTEDGES_T(min_vertex, current_edge, graph, Graph) {
|
||||
visitor.examine_edge(current_edge, graph);
|
||||
|
||||
|
||||
196
include/boost/graph/edge_coloring.hpp
Normal file
196
include/boost/graph/edge_coloring.hpp
Normal file
@@ -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 <boost/graph/graph_traits.hpp>
|
||||
#include <boost/graph/iteration_macros.hpp>
|
||||
#include <boost/graph/properties.hpp>
|
||||
#include <algorithm>
|
||||
#include <limits>
|
||||
#include <vector>
|
||||
|
||||
/* 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<typename Graph, typename ColorMap>
|
||||
bool
|
||||
is_free(const Graph &g,
|
||||
ColorMap color,
|
||||
typename boost::graph_traits<Graph>::vertex_descriptor u,
|
||||
typename boost::property_traits<ColorMap>::value_type free_color)
|
||||
{
|
||||
typedef typename boost::property_traits<ColorMap>::value_type color_t;
|
||||
if (free_color == (std::numeric_limits<color_t>::max)())
|
||||
return false;
|
||||
BGL_FORALL_OUTEDGES_T(u, e, g, Graph) {
|
||||
if (get(color, e) == free_color) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename Graph, typename ColorMap>
|
||||
std::vector<typename boost::graph_traits<Graph>::vertex_descriptor>
|
||||
maximal_fan(const Graph &g,
|
||||
ColorMap color,
|
||||
typename boost::graph_traits<Graph>::vertex_descriptor x,
|
||||
typename boost::graph_traits<Graph>::vertex_descriptor y)
|
||||
{
|
||||
typedef typename boost::graph_traits<Graph>::vertex_descriptor vertex_t;
|
||||
std::vector<vertex_t> 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 Graph, typename ColorMap>
|
||||
typename boost::property_traits<ColorMap>::value_type
|
||||
find_free_color(const Graph &g,
|
||||
ColorMap color,
|
||||
typename boost::graph_traits<Graph>::vertex_descriptor u)
|
||||
{
|
||||
typename boost::property_traits<ColorMap>::value_type c = 0;
|
||||
while (!is_free(g, color, u, c)) c++;
|
||||
return c;
|
||||
}
|
||||
|
||||
template<typename Graph, typename ColorMap>
|
||||
void
|
||||
invert_cd_path(const Graph &g,
|
||||
ColorMap color,
|
||||
typename boost::graph_traits<Graph>::vertex_descriptor x,
|
||||
typename boost::graph_traits<Graph>::edge_descriptor eold,
|
||||
typename boost::property_traits<ColorMap>::value_type c,
|
||||
typename boost::property_traits<ColorMap>::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<typename Graph, typename ColorMap>
|
||||
void
|
||||
invert_cd_path(const Graph &g,
|
||||
ColorMap color,
|
||||
typename boost::graph_traits<Graph>::vertex_descriptor x,
|
||||
typename boost::property_traits<ColorMap>::value_type c,
|
||||
typename boost::property_traits<ColorMap>::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<typename Graph, typename ColorMap, typename ForwardIterator>
|
||||
void
|
||||
rotate_fan(const Graph &g,
|
||||
ColorMap color,
|
||||
typename boost::graph_traits<Graph>::vertex_descriptor x,
|
||||
ForwardIterator begin,
|
||||
ForwardIterator end)
|
||||
{
|
||||
typedef typename boost::graph_traits<Graph>::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<typename Graph, typename ColorMap>
|
||||
class find_free_in_fan
|
||||
{
|
||||
public:
|
||||
find_free_in_fan(const Graph &graph,
|
||||
const ColorMap color,
|
||||
typename boost::property_traits<ColorMap>::value_type d)
|
||||
: graph(graph),
|
||||
color(color),
|
||||
d(d) {}
|
||||
bool operator()(const typename boost::graph_traits<Graph>::vertex_descriptor u) const {
|
||||
return is_free(graph, color, u, d);
|
||||
}
|
||||
private:
|
||||
const Graph &graph;
|
||||
const ColorMap color;
|
||||
const typename boost::property_traits<ColorMap>::value_type d;
|
||||
};
|
||||
}
|
||||
|
||||
template<typename Graph, typename ColorMap>
|
||||
typename boost::property_traits<ColorMap>::value_type
|
||||
color_edge(const Graph &g,
|
||||
ColorMap color,
|
||||
typename boost::graph_traits<Graph>::edge_descriptor e)
|
||||
{
|
||||
typedef typename boost::graph_traits<Graph>::vertex_descriptor vertex_t;
|
||||
typedef typename boost::property_traits<ColorMap>::value_type color_t;
|
||||
typedef typename std::vector<vertex_t>::iterator fan_iterator;
|
||||
using namespace detail;
|
||||
vertex_t x = source(e, g), y = target(e, g);
|
||||
std::vector<vertex_t> 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<Graph, ColorMap>(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 Graph, typename ColorMap>
|
||||
typename boost::property_traits<ColorMap>::value_type
|
||||
edge_coloring(const Graph &g,
|
||||
ColorMap color)
|
||||
{
|
||||
typedef typename boost::property_traits<ColorMap>::value_type color_t;
|
||||
BGL_FORALL_EDGES_T(e, g, Graph) {
|
||||
put(color, e, (std::numeric_limits<color_t>::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
|
||||
@@ -151,7 +151,6 @@ namespace boost {
|
||||
const bgl_named_params<P, T, R>& params,
|
||||
param_not_found)
|
||||
{
|
||||
typedef typename graph_traits<Graph>::edge_descriptor edge_descriptor;
|
||||
typedef typename graph_traits<Graph>::vertices_size_type size_type;
|
||||
size_type n = is_default_param(get_param(params, vertex_color)) ?
|
||||
num_vertices(g) : 1;
|
||||
|
||||
52
include/boost/graph/find_flow_cost.hpp
Normal file
52
include/boost/graph/find_flow_cost.hpp
Normal file
@@ -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 <boost/graph/iteration_macros.hpp>
|
||||
|
||||
namespace boost {
|
||||
|
||||
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) {
|
||||
typedef typename property_traits<typename property_map<Graph, edge_weight_t>::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 <class Graph, class P, class T, class R>
|
||||
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) {
|
||||
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 <class Graph>
|
||||
typename property_traits<typename property_map < Graph, edge_capacity_t >::type>::value_type
|
||||
find_flow_cost(const Graph &g) {
|
||||
bgl_named_params<int, buffer_param_t> params(0);
|
||||
return find_flow_cost(g, params);
|
||||
}
|
||||
|
||||
|
||||
} //boost
|
||||
|
||||
#endif /* BOOST_GRAPH_FIND_FLOW_COST_HPP */
|
||||
|
||||
@@ -282,7 +282,6 @@ fruchterman_reingold_force_directed_layout
|
||||
Cooling cool,
|
||||
DisplacementMap displacement)
|
||||
{
|
||||
typedef typename Topology::point_type Point;
|
||||
typedef typename graph_traits<Graph>::vertex_iterator vertex_iterator;
|
||||
typedef typename graph_traits<Graph>::vertex_descriptor vertex_descriptor;
|
||||
typedef typename graph_traits<Graph>::edge_iterator edge_iterator;
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -237,8 +237,6 @@ namespace boost {
|
||||
template <class Graph, class Vertex>
|
||||
bool is_adj_dispatch(Graph& g, Vertex a, Vertex b, bidirectional_tag)
|
||||
{
|
||||
typedef typename graph_traits<Graph>::edge_descriptor
|
||||
edge_descriptor;
|
||||
typename graph_traits<Graph>::adjacency_iterator vi, viend,
|
||||
adj_found;
|
||||
boost::tie(vi, viend) = adjacent_vertices(a, g);
|
||||
@@ -265,8 +263,6 @@ namespace boost {
|
||||
template <class Graph, class Vertex>
|
||||
bool is_adj_dispatch(Graph& g, Vertex a, Vertex b, directed_tag)
|
||||
{
|
||||
typedef typename graph_traits<Graph>::edge_descriptor
|
||||
edge_descriptor;
|
||||
typename graph_traits<Graph>::adjacency_iterator vi, viend, found;
|
||||
boost::tie(vi, viend) = adjacent_vertices(a, g);
|
||||
#if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 && defined(__SGI_STL_PORT)
|
||||
|
||||
@@ -208,9 +208,6 @@ void gursoy_atun_refine(const VertexListAndIncidenceGraph& graph,
|
||||
|
||||
typedef typename graph_traits<VertexListAndIncidenceGraph>::vertex_iterator
|
||||
vertex_iterator;
|
||||
typedef typename graph_traits<VertexListAndIncidenceGraph>::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);
|
||||
|
||||
381
include/boost/graph/hawick_circuits.hpp
Normal file
381
include/boost/graph/hawick_circuits.hpp
Normal file
@@ -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 <algorithm>
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/graph/graph_traits.hpp>
|
||||
#include <boost/graph/one_bit_color_map.hpp>
|
||||
#include <boost/graph/properties.hpp>
|
||||
#include <boost/move/utility.hpp>
|
||||
#include <boost/property_map/property_map.hpp>
|
||||
#include <boost/range/begin.hpp>
|
||||
#include <boost/range/end.hpp>
|
||||
#include <boost/range/iterator.hpp>
|
||||
#include <boost/tuple/tuple.hpp> // for boost::tie
|
||||
#include <boost/type_traits/remove_reference.hpp>
|
||||
#include <boost/utility/result_of.hpp>
|
||||
#include <set>
|
||||
#include <utility> // for std::pair
|
||||
#include <vector>
|
||||
|
||||
|
||||
namespace boost {
|
||||
namespace hawick_circuits_detail {
|
||||
//! @internal Functor returning all the vertices adjacent to a vertex.
|
||||
struct get_all_adjacent_vertices {
|
||||
template <typename Sig>
|
||||
struct result;
|
||||
|
||||
template <typename This, typename Vertex, typename Graph>
|
||||
struct result<This(Vertex, Graph)> {
|
||||
private:
|
||||
typedef typename remove_reference<Graph>::type RawGraph;
|
||||
typedef graph_traits<RawGraph> Traits;
|
||||
typedef typename Traits::adjacency_iterator AdjacencyIterator;
|
||||
|
||||
public:
|
||||
typedef std::pair<AdjacencyIterator, AdjacencyIterator> type;
|
||||
};
|
||||
|
||||
template <typename Vertex, typename Graph>
|
||||
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<Vertex>(v),
|
||||
boost::forward<Graph>(g));
|
||||
}
|
||||
};
|
||||
|
||||
//! @internal Functor returning a set of the vertices adjacent to a vertex.
|
||||
struct get_unique_adjacent_vertices {
|
||||
template <typename Sig>
|
||||
struct result;
|
||||
|
||||
template <typename This, typename Vertex, typename Graph>
|
||||
struct result<This(Vertex, Graph)> {
|
||||
typedef std::set<typename remove_reference<Vertex>::type> type;
|
||||
};
|
||||
|
||||
template <typename Vertex, typename Graph>
|
||||
typename result<get_unique_adjacent_vertices(Vertex, Graph const&)>::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 <typename Container, typename Value>
|
||||
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<Graph> Traits;
|
||||
typedef typename Traits::vertex_descriptor Vertex;
|
||||
typedef typename Traits::edge_descriptor Edge;
|
||||
typedef typename Traits::vertices_size_type VerticesSize;
|
||||
typedef typename property_traits<VertexIndexMap>::value_type VertexIndex;
|
||||
|
||||
typedef typename result_of<
|
||||
GetAdjacentVertices(Vertex, Graph const&)
|
||||
>::type AdjacentVertices;
|
||||
typedef typename range_iterator<AdjacentVertices const>::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<VertexIndexMap> BlockedMap;
|
||||
typedef typename property_traits<BlockedMap>::value_type BlockedColor;
|
||||
|
||||
static BlockedColor blocked_false_color()
|
||||
{ return color_traits<BlockedColor>::white(); }
|
||||
|
||||
static BlockedColor blocked_true_color()
|
||||
{ return color_traits<BlockedColor>::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 const&>(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<Graph> Traits;
|
||||
typedef typename Traits::vertex_descriptor Vertex;
|
||||
typedef typename Traits::vertices_size_type VerticesSize;
|
||||
typedef typename Traits::vertex_iterator VertexIterator;
|
||||
|
||||
typedef std::vector<Vertex> Stack;
|
||||
typedef std::vector<std::vector<Vertex> > 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 <typename GetAdjacentVertices, typename Graph, typename Visitor>
|
||||
void call_hawick_circuits(Graph const& graph, BOOST_FWD_REF(Visitor) visitor) {
|
||||
call_hawick_circuits<GetAdjacentVertices>(
|
||||
graph, boost::forward<Visitor>(visitor), get(vertex_index, graph)
|
||||
);
|
||||
}
|
||||
} // end namespace hawick_circuits_detail
|
||||
|
||||
//! Enumerate all the elementary circuits in a directed multigraph.
|
||||
template <typename Graph, typename Visitor, typename VertexIndexMap>
|
||||
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>(graph),
|
||||
boost::forward<Visitor>(visitor),
|
||||
boost::forward<VertexIndexMap>(vertex_index_map)
|
||||
);
|
||||
}
|
||||
|
||||
template <typename Graph, typename Visitor>
|
||||
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>(graph), boost::forward<Visitor>(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 <typename Graph, typename Visitor, typename VertexIndexMap>
|
||||
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>(graph),
|
||||
boost::forward<Visitor>(visitor),
|
||||
boost::forward<VertexIndexMap>(vertex_index_map)
|
||||
);
|
||||
}
|
||||
|
||||
template <typename Graph, typename Visitor>
|
||||
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>(graph), boost::forward<Visitor>(visitor));
|
||||
}
|
||||
} // end namespace boost
|
||||
|
||||
#endif // !BOOST_GRAPH_HAWICK_CIRCUITS_HPP
|
||||
@@ -106,11 +106,8 @@ namespace boost
|
||||
{
|
||||
|
||||
typedef typename graph_traits<Graph>::vertex_descriptor vertex_t;
|
||||
typedef typename graph_traits<Graph>::vertex_iterator vertex_iterator_t;
|
||||
typedef typename graph_traits<Graph>::edge_descriptor edge_t;
|
||||
typedef typename graph_traits<Graph>::edge_iterator edge_iterator_t;
|
||||
typedef typename graph_traits<Graph>::edges_size_type e_size_t;
|
||||
typedef typename graph_traits<Graph>::vertices_size_type v_size_t;
|
||||
|
||||
typedef std::size_t x_coord_t;
|
||||
typedef std::size_t y_coord_t;
|
||||
|
||||
@@ -37,7 +37,6 @@ namespace boost {
|
||||
typename graph_traits<Graph>::out_edge_iterator ei, ei_end;
|
||||
Vertex v, w;
|
||||
|
||||
typedef typename std::deque<Vertex>::iterator iterator;
|
||||
typedef typename std::deque<Vertex>::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 <typename Vertex>
|
||||
void percolate_down(int offset){
|
||||
typedef typename std::deque<Vertex>::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<Graph>::vertex_descriptor Vertex;
|
||||
typedef typename boost::graph_traits<Graph>::vertex_iterator VerIter;
|
||||
typedef typename property_traits<ColorMap>::value_type ColorValue;
|
||||
typedef color_traits<ColorValue> Color;
|
||||
|
||||
@@ -302,7 +298,6 @@ namespace boost {
|
||||
if (has_no_vertices(G))
|
||||
return permutation;
|
||||
|
||||
typedef out_degree_property_map<Graph> DegreeMap;
|
||||
std::vector<default_color_type> colors(num_vertices(G));
|
||||
return king_ordering(G, permutation,
|
||||
make_iterator_property_map(&colors[0], index_map,
|
||||
|
||||
@@ -102,7 +102,6 @@ namespace boost {
|
||||
{
|
||||
typedef typename graph_traits<Graph>::vertices_size_type size_type;
|
||||
typedef typename graph_traits<Graph>::vertex_descriptor vertex_t;
|
||||
typedef typename property_map<Graph, vertex_index_t>::type index_map_t;
|
||||
if (num_vertices(g) == 0) return; // Nothing to do in this case
|
||||
typename graph_traits<Graph>::vertices_size_type
|
||||
n = num_vertices(g);
|
||||
|
||||
@@ -118,8 +118,6 @@ namespace boost {
|
||||
void
|
||||
maximum_adjacency_search(const Graph& g, WeightMap weights, MASVisitor vis, const typename boost::graph_traits<Graph>::vertex_descriptor start, VertexAssignmentMap assignments, KeyedUpdatablePriorityQueue pq) {
|
||||
typedef typename boost::graph_traits<Graph>::vertex_descriptor vertex_descriptor;
|
||||
typedef typename boost::graph_traits<Graph>::vertices_size_type vertices_size_type;
|
||||
typedef typename boost::graph_traits<Graph>::edge_descriptor edge_descriptor;
|
||||
typedef typename boost::property_traits<WeightMap>::value_type weight_type;
|
||||
|
||||
std::set<vertex_descriptor> assignedVertices;
|
||||
@@ -197,7 +195,7 @@ maximum_adjacency_search(const Graph& g, WeightMap weights, MASVisitor vis, cons
|
||||
typedef typename boost::graph_traits<Graph>::edge_descriptor edge_descriptor;
|
||||
BOOST_CONCEPT_ASSERT((boost::Convertible<typename boost::graph_traits<Graph>::directed_category, boost::undirected_tag>));
|
||||
BOOST_CONCEPT_ASSERT((boost::ReadablePropertyMapConcept<WeightMap, edge_descriptor>));
|
||||
typedef typename boost::property_traits<WeightMap>::value_type weight_type;
|
||||
// typedef typename boost::property_traits<WeightMap>::value_type weight_type;
|
||||
boost::function_requires< MASVisitorConcept<MASVisitor, Graph> >();
|
||||
BOOST_CONCEPT_ASSERT((boost::ReadWritePropertyMapConcept<VertexAssignmentMap, vertex_descriptor>));
|
||||
BOOST_CONCEPT_ASSERT((boost::Convertible<vertex_descriptor, typename boost::property_traits<VertexAssignmentMap>::value_type>));
|
||||
|
||||
@@ -121,7 +121,6 @@ namespace boost {
|
||||
VertexEquivalencePredicate vertices_equivalent,
|
||||
bool only_connected_subgraphs)
|
||||
{
|
||||
typedef typename graph_traits<GraphFirst>::vertex_descriptor VertexFirst;
|
||||
typedef typename graph_traits<GraphSecond>::vertex_descriptor VertexSecond;
|
||||
|
||||
typedef typename graph_traits<GraphFirst>::edge_descriptor EdgeFirst;
|
||||
|
||||
@@ -173,7 +173,6 @@ namespace boost
|
||||
|
||||
// We build a custom graph in this algorithm.
|
||||
typedef adjacency_list <vecS, vecS, directedS, no_property, no_property > MSTImpl;
|
||||
typedef graph_traits<MSTImpl>::edge_descriptor Edge;
|
||||
typedef graph_traits<MSTImpl>::vertex_descriptor Vertex;
|
||||
typedef graph_traits<MSTImpl>::vertex_iterator VItr;
|
||||
|
||||
|
||||
@@ -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) \
|
||||
|
||||
@@ -41,10 +41,8 @@ namespace boost
|
||||
|
||||
typedef typename graph_traits<Graph>::vertex_descriptor vertex_t;
|
||||
typedef typename graph_traits<Graph>::edge_descriptor edge_t;
|
||||
typedef typename graph_traits<Graph>::vertex_iterator vertex_iterator_t;
|
||||
typedef typename graph_traits<Graph>::adjacency_iterator
|
||||
adjacency_iterator_t;
|
||||
typedef typename std::pair<vertex_t, vertex_t> vertex_pair_t;
|
||||
typedef typename property_traits<PlanarEmbedding>::value_type
|
||||
embedding_value_t;
|
||||
typedef typename embedding_value_t::const_iterator embedding_iterator_t;
|
||||
|
||||
@@ -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<Graph>::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<typename std::list<Splabel>::iterator>
|
||||
vec_last_valid_positions_for_dominance( num_vertices( g ) );
|
||||
for( int i = 0; i < static_cast<int>( 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<int> vec_last_valid_index_for_dominance( num_vertices( g ), 0 );
|
||||
std::vector<size_t> vec_last_valid_index_for_dominance( num_vertices( g ), 0 );
|
||||
std::vector<bool>
|
||||
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<Splabel>& list_labels_cur_vertex =
|
||||
vec_vertex_labels[i_cur_resident_vertex_num];
|
||||
if( static_cast<int>( 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<int>( list_labels_cur_vertex.size() ) )
|
||||
< list_labels_cur_vertex.size() )
|
||||
{
|
||||
typename std::list<Splabel>::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<int>( 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<int>( 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<int>( 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<Splabel>& 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<Graph>::edge_descriptor&
|
||||
ed_last_extended_arc )
|
||||
{
|
||||
int i_size_ed_vec_path = static_cast<int>( ed_vec_path.size() );
|
||||
size_t i_size_ed_vec_path = ed_vec_path.size();
|
||||
std::vector<typename graph_traits<Graph>::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,
|
||||
|
||||
@@ -86,8 +86,6 @@ namespace boost {
|
||||
template <typename Graph, typename WeightMap, typename RandomNumGen>
|
||||
typename graph_traits<Graph>::edge_descriptor
|
||||
weighted_random_out_edge(Graph& g, typename graph_traits<Graph>::vertex_descriptor src, WeightMap weight, RandomNumGen& gen) {
|
||||
typedef graph_traits<Graph> gt;
|
||||
typedef typename gt::vertex_descriptor vertex_descriptor;
|
||||
typedef typename property_traits<WeightMap>::value_type weight_type;
|
||||
weight_type weight_sum(0);
|
||||
BGL_FORALL_OUTEDGES_T(src, e, g, Graph) {weight_sum += get(weight, e);}
|
||||
|
||||
@@ -33,7 +33,6 @@ namespace boost {
|
||||
template <typename Graph, typename PredMap, typename ColorMap, typename NextEdge>
|
||||
void random_spanning_tree_internal(const Graph& g, typename graph_traits<Graph>::vertex_descriptor s, PredMap pred, ColorMap color, NextEdge next_edge) {
|
||||
typedef typename graph_traits<Graph>::vertex_descriptor vertex_descriptor;
|
||||
typedef typename graph_traits<Graph>::edge_descriptor edge_descriptor;
|
||||
|
||||
BOOST_ASSERT (num_vertices(g) >= 1); // g must also be undirected (or symmetric) and connected
|
||||
|
||||
|
||||
@@ -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<Graph>::vertices_size_type vertices_size_type;
|
||||
typedef typename graph_traits<Graph>::vertex_descriptor vertex_descriptor;
|
||||
typedef typename graph_traits<Graph>::edge_descriptor edge_descriptor;
|
||||
|
||||
|
||||
@@ -76,7 +76,6 @@ namespace boost {
|
||||
template < typename Vertex, typename Graph >
|
||||
void finish_vertex(Vertex u, const Graph & g)
|
||||
{
|
||||
typedef typename boost::property_traits<ParityMap>::value_type parity_type;
|
||||
typedef typename boost::property_traits<InternalParityMap>::value_type internal_parity_type;
|
||||
|
||||
++m_visited;
|
||||
@@ -131,10 +130,7 @@ namespace boost {
|
||||
typename boost::property_traits<WeightMap>::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<UndirectedGraph>::vertex_descriptor vertex_descriptor;
|
||||
typedef typename boost::graph_traits<UndirectedGraph>::vertices_size_type vertices_size_type;
|
||||
typedef typename boost::graph_traits<UndirectedGraph>::edge_descriptor edge_descriptor;
|
||||
typedef typename boost::property_traits<WeightMap>::value_type weight_type;
|
||||
typedef typename boost::property_traits<ParityMap>::value_type parity_type;
|
||||
|
||||
typename graph_traits<UndirectedGraph>::vertex_iterator u_iter, u_end;
|
||||
|
||||
@@ -185,9 +181,9 @@ namespace boost {
|
||||
typedef typename boost::graph_traits<UndirectedGraph>::edge_descriptor edge_descriptor;
|
||||
BOOST_CONCEPT_ASSERT((boost::Convertible<typename boost::graph_traits<UndirectedGraph>::directed_category, boost::undirected_tag>));
|
||||
BOOST_CONCEPT_ASSERT((boost::ReadablePropertyMapConcept<WeightMap, edge_descriptor>));
|
||||
typedef typename boost::property_traits<WeightMap>::value_type weight_type;
|
||||
// typedef typename boost::property_traits<WeightMap>::value_type weight_type;
|
||||
BOOST_CONCEPT_ASSERT((boost::WritablePropertyMapConcept<ParityMap, vertex_descriptor>));
|
||||
typedef typename boost::property_traits<ParityMap>::value_type parity_type;
|
||||
// typedef typename boost::property_traits<ParityMap>::value_type parity_type;
|
||||
BOOST_CONCEPT_ASSERT((boost::ReadWritePropertyMapConcept<VertexAssignmentMap, vertex_descriptor>));
|
||||
BOOST_CONCEPT_ASSERT((boost::Convertible<vertex_descriptor, typename boost::property_traits<VertexAssignmentMap>::value_type>));
|
||||
BOOST_CONCEPT_ASSERT((boost::KeyedUpdatableQueueConcept<KeyedUpdatablePriorityQueue>));
|
||||
|
||||
@@ -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 <numeric>
|
||||
|
||||
#include <boost/property_map/property_map.hpp>
|
||||
#include <boost/graph/graph_traits.hpp>
|
||||
#include <boost/graph/graph_concepts.hpp>
|
||||
#include <boost/pending/indirect_cmp.hpp>
|
||||
#include <boost/pending/relaxed_heap.hpp>
|
||||
#include <boost/graph/dijkstra_shortest_paths.hpp>
|
||||
#include <boost/graph/properties.hpp>
|
||||
#include <boost/graph/iteration_macros.hpp>
|
||||
#include <boost/graph/detail/augment.hpp>
|
||||
|
||||
namespace boost {
|
||||
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <class Graph, class Weight, class Distance, class Reversed>
|
||||
class MapReducedWeight :
|
||||
public put_get_helper<typename property_traits<Weight>::value_type, MapReducedWeight<Graph, Weight, Distance, Reversed> > {
|
||||
typedef graph_traits<Graph> gtraits;
|
||||
public:
|
||||
typedef boost::readable_property_map_tag category;
|
||||
typedef typename property_traits<Weight>::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 <class Graph, class Weight, class Distance, class Reversed>
|
||||
MapReducedWeight<Graph, Weight, Distance, Reversed>
|
||||
make_mapReducedWeight(const Graph & g, Weight w, Distance d, Reversed r) {
|
||||
return MapReducedWeight<Graph, Weight, Distance, Reversed>(g, w, d, r);
|
||||
}
|
||||
|
||||
}//detail
|
||||
|
||||
|
||||
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) {
|
||||
filtered_graph<const Graph, is_residual_edge<ResidualCapacity> >
|
||||
gres = detail::residual_graph(g, residual_capacity);
|
||||
typedef typename graph_traits<Graph>::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 <class Graph, class Capacity, class ResidualCapacity, class Weight, class Reversed, class Pred, class Distance, class Distance2, class VertexIndex>
|
||||
void successive_shortest_path_nonnegative_weights_dispatch3(
|
||||
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 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 <class Graph, class Capacity, class ResidualCapacity, class Weight, class Reversed, class Pred, class Distance, class VertexIndex>
|
||||
void successive_shortest_path_nonnegative_weights_dispatch3(
|
||||
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 dist,
|
||||
param_not_found) {
|
||||
typedef typename property_traits<Weight>::value_type D;
|
||||
|
||||
std::vector<D> 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 <class Graph, class P, class T, class R, class Capacity, class ResidualCapacity, class Weight, class Reversed, class Pred, class Distance, class VertexIndex>
|
||||
void successive_shortest_path_nonnegative_weights_dispatch2(
|
||||
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 dist,
|
||||
const bgl_named_params<P, T, R>& 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 <class Graph, class P, class T, class R, class Capacity, class ResidualCapacity, class Weight, class Reversed, class Pred, class VertexIndex>
|
||||
void successive_shortest_path_nonnegative_weights_dispatch2(
|
||||
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,
|
||||
param_not_found,
|
||||
const bgl_named_params<P, T, R>& params) {
|
||||
typedef typename property_traits<Weight>::value_type D;
|
||||
|
||||
std::vector<D> 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 <class Graph, class P, class T, class R, class Capacity, class ResidualCapacity, class Weight, class Reversed, class Pred, class VertexIndex>
|
||||
void successive_shortest_path_nonnegative_weights_dispatch1(
|
||||
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,
|
||||
const bgl_named_params<P, T, R>& 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 <class Graph, class P, class T, class R, class Capacity, class ResidualCapacity, class Weight, class Reversed, class VertexIndex>
|
||||
void successive_shortest_path_nonnegative_weights_dispatch1(
|
||||
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,
|
||||
param_not_found,
|
||||
const bgl_named_params<P, T, R>& params) {
|
||||
typedef typename graph_traits<Graph>::edge_descriptor edge_descriptor;
|
||||
std::vector<edge_descriptor> 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 <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) {
|
||||
|
||||
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 <class Graph>
|
||||
void successive_shortest_path_nonnegative_weights(
|
||||
Graph &g,
|
||||
typename graph_traits<Graph>::vertex_descriptor s,
|
||||
typename graph_traits<Graph>::vertex_descriptor t) {
|
||||
bgl_named_params<int, buffer_param_t> params(0);
|
||||
successive_shortest_path_nonnegative_weights(g, s, t, params);
|
||||
}
|
||||
|
||||
|
||||
}//boost
|
||||
#endif /* BOOST_GRAPH_SUCCESSIVE_SHORTEST_PATH_HPP */
|
||||
|
||||
@@ -212,7 +212,6 @@ namespace detail
|
||||
{
|
||||
BOOST_CONCEPT_ASSERT(( IncidenceGraphConcept<Graph> ));
|
||||
typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
|
||||
typedef typename graph_traits<Graph>::edge_descriptor Edge;
|
||||
typedef typename graph_traits<Graph>::out_edge_iterator OutIterator;
|
||||
|
||||
// get the current vertex
|
||||
|
||||
@@ -14,11 +14,11 @@
|
||||
#include <functional>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/bind.hpp>
|
||||
#include <boost/graph/vector_as_graph.hpp>
|
||||
#include <boost/graph/strong_components.hpp>
|
||||
#include <boost/graph/topological_sort.hpp>
|
||||
#include <boost/graph/graph_concepts.hpp>
|
||||
#include <boost/graph/named_function_params.hpp>
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/concept/assert.hpp>
|
||||
|
||||
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<std::vector<cg_vertex> > CG_t;
|
||||
typedef boost::adjacency_list<boost::vecS, boost::vecS, boost::directedS> 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<cg_vertex>::const_iterator i = adj.begin();
|
||||
i != adj.end(); ++i) {
|
||||
add_edge(s, *i, CG);
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<cg_vertex> 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<std::vector<cg_vertex> > CG_vec(num_vertices(CG));
|
||||
for (size_type i = 0; i < num_vertices(CG); ++i) {
|
||||
typedef typename boost::graph_traits<CG_t>::adjacency_iterator cg_adj_iter;
|
||||
std::pair<cg_adj_iter, cg_adj_iter> 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<cg_vertex>(),
|
||||
boost::bind(detail::subscript(topo_number), _1),
|
||||
boost::bind(detail::subscript(topo_number), _2)));
|
||||
}
|
||||
|
||||
std::vector<std::vector<cg_vertex> > chains;
|
||||
{
|
||||
std::vector<cg_vertex> in_a_chain(num_vertices(CG));
|
||||
std::vector<cg_vertex> in_a_chain(CG_vec.size());
|
||||
for (typename std::vector<cg_vertex>::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<CG_t>::adjacency_iterator adj_first, adj_last;
|
||||
boost::tie(adj_first, adj_last) = adjacent_vertices(v, CG);
|
||||
typename graph_traits<CG_t>::adjacency_iterator next
|
||||
= std::find_if(adj_first, adj_last,
|
||||
typename std::vector<cg_vertex>::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<size_type> chain_number(num_vertices(CG));
|
||||
std::vector<size_type> pos_in_chain(num_vertices(CG));
|
||||
std::vector<size_type> chain_number(CG_vec.size());
|
||||
std::vector<size_type> 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<std::vector<cg_vertex> > successors(num_vertices(CG),
|
||||
std::vector<std::vector<cg_vertex> > successors(CG_vec.size(),
|
||||
std::vector<cg_vertex>
|
||||
(chains.size(), inf));
|
||||
for (typename std::vector<cg_vertex>::reverse_iterator
|
||||
i = topo_order.rbegin(); i != topo_order.rend(); ++i) {
|
||||
cg_vertex u = *i;
|
||||
typename graph_traits<CG_t>::adjacency_iterator adj, adj_last;
|
||||
for (boost::tie(adj, adj_last) = adjacent_vertices(u, CG);
|
||||
typename std::vector<cg_vertex>::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<CG_t>::vertex_iterator si, si_end;
|
||||
for (boost::tie(si, si_end) = vertices(CG); si != si_end; ++si) {
|
||||
cg_vertex s = *si;
|
||||
typename graph_traits<CG_t>::adjacency_iterator i, i_end;
|
||||
for (boost::tie(i, i_end) = adjacent_vertices(s, CG); i != i_end; ++i) {
|
||||
typename std::vector<std::vector<cg_vertex> >::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<cg_vertex>::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 > ));
|
||||
|
||||
@@ -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<order_value_type, edge_descriptor>::value));
|
||||
BOOST_CONCEPT_ASSERT((Convertible<order_size_type, edges_size_type>));
|
||||
@@ -846,7 +840,6 @@ two_graphs_common_spanning_trees
|
||||
typedef graph_traits<Graph> 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<edge_descriptor> iGO, vGO;
|
||||
|
||||
@@ -46,18 +46,18 @@ namespace boost {
|
||||
typedef color_traits<ColorValue> Color;
|
||||
typedef color_traits<EColorValue> EColor;
|
||||
typedef typename graph_traits<IncidenceGraph>::out_edge_iterator Iter;
|
||||
typedef std::pair<Vertex, std::pair<Iter, Iter> > VertexInfo;
|
||||
typedef std::pair<Vertex, std::pair<boost::optional<Edge>, std::pair<Iter, Iter> > > VertexInfo;
|
||||
|
||||
std::vector<VertexInfo> 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<Edge>(), 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<Edge> 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);
|
||||
}
|
||||
|
||||
@@ -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<GraphSmall>::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<Graph1>::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),
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -51,10 +51,6 @@ void write_dimacs_max_flow(const Graph& g,
|
||||
typename graph_traits<Graph>::vertex_descriptor sink,
|
||||
std::ostream& out)
|
||||
{
|
||||
typedef typename graph_traits<Graph>::vertex_descriptor vertex_descriptor;
|
||||
typedef typename graph_traits<Graph>::vertices_size_type vertices_size_type;
|
||||
typedef typename graph_traits<Graph>::edge_descriptor edge_descriptor;
|
||||
typedef typename graph_traits<Graph>::edges_size_type edges_size_type;
|
||||
typedef typename graph_traits<Graph>::edge_iterator edge_iterator;
|
||||
|
||||
out << "c DIMACS max-flow file generated from boost::write_dimacs_max_flow" << std::endl;
|
||||
|
||||
@@ -43,6 +43,7 @@ test-suite graph_test :
|
||||
[ run csr_graph_test.cpp : : : : : <variant>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/<link>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/<link>static ]
|
||||
[ run cycle_canceling_test.cpp ../../test/build//boost_unit_test_framework/<link>static ]
|
||||
;
|
||||
|
||||
# Run SDB tests only when -sSDB= is set.
|
||||
|
||||
@@ -17,7 +17,6 @@ template <typename Graph>
|
||||
void test_graph_nonloop()
|
||||
{
|
||||
typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
|
||||
typedef typename graph_traits<Graph>::edge_descriptor Edge;
|
||||
|
||||
// Build a graph with 1 edge and turn it into a loop.
|
||||
Graph g(5);
|
||||
@@ -36,7 +35,6 @@ template <typename Graph>
|
||||
void test_multigraph_nonloop()
|
||||
{
|
||||
typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
|
||||
typedef typename graph_traits<Graph>::edge_descriptor Edge;
|
||||
|
||||
// Build a graph with 1 edge and turn it into a loop.
|
||||
Graph g(5);
|
||||
@@ -55,7 +53,6 @@ template <typename Graph>
|
||||
void test_graph_loop()
|
||||
{
|
||||
typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
|
||||
typedef typename graph_traits<Graph>::edge_descriptor Edge;
|
||||
|
||||
Graph g(5);
|
||||
Vertex v = *next(vertices(g).first, 2);
|
||||
@@ -70,7 +67,6 @@ template <typename Graph>
|
||||
void test_multigraph_loop()
|
||||
{
|
||||
typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
|
||||
typedef typename graph_traits<Graph>::edge_descriptor Edge;
|
||||
|
||||
Graph g(5);
|
||||
Vertex v = *next(vertices(g).first, 2);
|
||||
|
||||
@@ -122,9 +122,7 @@ int test_graph(const std::string& dimacs_filename)
|
||||
typedef graph_traits<graph>::edge_iterator edge_iterator_t;
|
||||
typedef graph_traits<graph>::vertex_iterator vertex_iterator_t;
|
||||
typedef graph_traits<graph>::edges_size_type e_size_t;
|
||||
typedef graph_traits<graph>::vertices_size_type v_size_t;
|
||||
typedef graph_traits<graph>::vertex_descriptor vertex_t;
|
||||
typedef std::pair<vertex_t, vertex_t> vertex_pair_t;
|
||||
typedef edge_index_update_visitor<property_map<graph, edge_index_t>::type>
|
||||
edge_visitor_t;
|
||||
|
||||
|
||||
@@ -122,7 +122,6 @@ int main(int, char **)
|
||||
typedef property_map<mygraph_t, edge_weight_t>::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<int, int> edge;
|
||||
|
||||
// specify data
|
||||
@@ -185,13 +184,18 @@ int main(int, char **)
|
||||
|
||||
vector<mygraph_t::vertex_descriptor> p(num_vertices(g));
|
||||
vector<cost> d(num_vertices(g));
|
||||
|
||||
boost::property_map<mygraph_t, boost::vertex_index_t>::const_type
|
||||
idx = get(boost::vertex_index, g);
|
||||
|
||||
try {
|
||||
// call astar named parameter interface
|
||||
astar_search
|
||||
(g, start,
|
||||
distance_heuristic<mygraph_t, cost, location*>
|
||||
(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<vertex>(goal)).distance_inf(my_float((std::numeric_limits<float>::max)())));
|
||||
|
||||
|
||||
|
||||
@@ -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<int>(),
|
||||
std::less<int>(),
|
||||
default_bellman_visitor());
|
||||
@@ -81,8 +81,10 @@ int test_main(int, char*[])
|
||||
std::vector<int> 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] << ": ";
|
||||
|
||||
28
test/bfs.cpp
28
test/bfs.cpp
@@ -140,20 +140,38 @@ struct bfs_test
|
||||
parent[*ui] = *ui;
|
||||
std::vector<boost::default_color_type> color(i);
|
||||
|
||||
// Get vertex index map
|
||||
typedef typename boost::property_map<Graph, boost::vertex_index_t>::const_type idx_type;
|
||||
idx_type idx = get(boost::vertex_index, g);
|
||||
|
||||
// Make property maps from vectors
|
||||
typedef
|
||||
boost::iterator_property_map<std::vector<int>::iterator, idx_type>
|
||||
distance_pm_type;
|
||||
distance_pm_type distance_pm(distance.begin(), idx);
|
||||
typedef
|
||||
boost::iterator_property_map<typename std::vector<vertex_descriptor>::iterator, idx_type>
|
||||
parent_pm_type;
|
||||
parent_pm_type parent_pm(parent.begin(), idx);
|
||||
typedef
|
||||
boost::iterator_property_map<std::vector<boost::default_color_type>::iterator, idx_type>
|
||||
color_pm_type;
|
||||
color_pm_type color_pm(color.begin(), idx);
|
||||
|
||||
// Create the testing visitor.
|
||||
bfs_testing_visitor<int*,vertex_descriptor*,Graph,
|
||||
boost::default_color_type*>
|
||||
vis(start, &distance[0], &parent[0], &color[0]);
|
||||
bfs_testing_visitor<distance_pm_type, parent_pm_type, Graph,
|
||||
color_pm_type>
|
||||
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<boost::default_color_type> 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
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -31,8 +31,6 @@ template <typename Graph>
|
||||
void build_graph(Graph& g,
|
||||
typename vertex_vector<Graph>::type& v)
|
||||
{
|
||||
typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
|
||||
|
||||
// add vertices
|
||||
for(size_t i = 0; i < N; ++i) {
|
||||
v[i] = add_vertex(g);
|
||||
|
||||
@@ -27,8 +27,6 @@ struct vertex_vector
|
||||
template <typename Graph>
|
||||
void build_graph(Graph& g, typename vertex_vector<Graph>::type& v)
|
||||
{
|
||||
typedef typename graph_traits<Graph>::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.
|
||||
|
||||
|
||||
63
test/cycle_canceling_test.cpp
Normal file
63
test/cycle_canceling_test.cpp
Normal file
@@ -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 <boost/test/unit_test.hpp>
|
||||
|
||||
#include <boost/graph/cycle_canceling.hpp>
|
||||
#include <boost/graph/edmonds_karp_max_flow.hpp>
|
||||
|
||||
#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<int> dist(N);
|
||||
typedef boost::graph_traits<Graph>::edge_descriptor edge_descriptor;
|
||||
std::vector<edge_descriptor> pred(N);
|
||||
|
||||
boost::property_map<Graph, boost::vertex_index_t>::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);
|
||||
}
|
||||
|
||||
@@ -331,7 +331,6 @@ int test_main(int argc, char* argv[])
|
||||
{
|
||||
GraphMInt gm(10);
|
||||
typedef graph_traits<GraphMInt>::vertex_iterator VertexItM;
|
||||
typedef graph_traits<GraphMInt>::edge_descriptor EdgeM;
|
||||
VertexItM vi1, vi2, vi_end;
|
||||
for (boost::tie(vi1, vi_end) = vertices(gm); vi1 != vi_end; ++vi1)
|
||||
{
|
||||
|
||||
80
test/cycle_test.hpp
Normal file
80
test/cycle_test.hpp
Normal file
@@ -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 <boost/assert.hpp>
|
||||
#include <boost/graph/directed_graph.hpp>
|
||||
#include <boost/graph/erdos_renyi_generator.hpp>
|
||||
#include <boost/graph/graph_traits.hpp>
|
||||
#include <boost/graph/graph_utility.hpp>
|
||||
#include <boost/graph/undirected_graph.hpp>
|
||||
#include <boost/next_prior.hpp>
|
||||
#include <boost/random/linear_congruential.hpp>
|
||||
#include <cstddef>
|
||||
#include <iostream>
|
||||
|
||||
|
||||
namespace cycle_test_detail {
|
||||
using namespace boost;
|
||||
|
||||
struct cycle_validator {
|
||||
explicit cycle_validator(std::size_t& number_of_cycles)
|
||||
: cycles(number_of_cycles)
|
||||
{ }
|
||||
|
||||
template <typename Path, typename Graph>
|
||||
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 <typename Graph, typename Algorithm>
|
||||
void test_one(Algorithm algorithm) {
|
||||
typedef erdos_renyi_iterator<minstd_rand, Graph> 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 <typename Algorithm>
|
||||
void cycle_test(Algorithm const& algorithm) {
|
||||
std::cout << "*** undirected ***\n";
|
||||
cycle_test_detail::test_one<boost::undirected_graph<> >(algorithm);
|
||||
|
||||
std::cout << "*** directed ***\n";
|
||||
cycle_test_detail::test_one<boost::directed_graph<> >(algorithm);
|
||||
}
|
||||
|
||||
#endif // !BOOST_GRAPH_TEST_CYCLE_TEST_HPP
|
||||
@@ -22,8 +22,6 @@ template <typename Graph>
|
||||
void build_graph(Graph& g,
|
||||
vector<typename graph_traits<Graph>::vertex_descriptor>& v)
|
||||
{
|
||||
typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
|
||||
|
||||
// add vertices
|
||||
for(size_t i = 0; i < N; ++i) {
|
||||
v[i] = add_vertex(g);
|
||||
|
||||
31
test/dfs.cpp
31
test/dfs.cpp
@@ -68,6 +68,12 @@ public:
|
||||
using namespace boost;
|
||||
BOOST_CHECK( get(m_color, target(e, g)) == Color::black() );
|
||||
}
|
||||
template <class Edge, class Graph>
|
||||
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 <class Vertex, class Graph>
|
||||
void finish_vertex(Vertex u, Graph&) {
|
||||
using namespace boost;
|
||||
@@ -116,9 +122,24 @@ struct dfs_test
|
||||
std::vector<int> discover_time(num_vertices(g)),
|
||||
finish_time(num_vertices(g));
|
||||
|
||||
dfs_test_visitor<ColorMap, vertex_descriptor*,
|
||||
int*, int*> vis(color, &parent[0],
|
||||
&discover_time[0], &finish_time[0]);
|
||||
// Get vertex index map
|
||||
typedef typename boost::property_map<Graph, boost::vertex_index_t>::const_type idx_type;
|
||||
idx_type idx = get(boost::vertex_index, g);
|
||||
|
||||
typedef
|
||||
boost::iterator_property_map<typename std::vector<vertex_descriptor>::iterator, idx_type>
|
||||
parent_pm_type;
|
||||
parent_pm_type parent_pm(parent.begin(), idx);
|
||||
typedef
|
||||
boost::iterator_property_map<std::vector<int>::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<ColorMap, parent_pm_type,
|
||||
time_pm_type, time_pm_type>
|
||||
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))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -94,9 +94,6 @@ int test_main(int argc, char* argv[])
|
||||
property<vertex_index_t, int >,
|
||||
property<edge_weight_t, double> > graph_t;
|
||||
|
||||
typedef graph_traits<graph_t>::vertex_descriptor vertex_t;
|
||||
typedef graph_traits<graph_t>::edge_descriptor edge_t;
|
||||
|
||||
graph_t graph;
|
||||
generate_random_graph(graph, vertices_to_create, edges_to_create, generator);
|
||||
|
||||
|
||||
@@ -31,8 +31,6 @@ template <typename Graph>
|
||||
void build_graph(Graph& g,
|
||||
typename vertex_vector<Graph>::type& v)
|
||||
{
|
||||
typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
|
||||
|
||||
// add vertices
|
||||
for(size_t i = 0; i < N; ++i) {
|
||||
v[i] = add_vertex(g);
|
||||
|
||||
@@ -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);
|
||||
|
||||
32
test/hawick_circuits.cpp
Normal file
32
test/hawick_circuits.cpp
Normal file
@@ -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 <boost/graph/hawick_circuits.hpp>
|
||||
#include <iostream>
|
||||
|
||||
|
||||
struct call_hawick_circuits {
|
||||
template <typename Graph, typename Visitor>
|
||||
void operator()(Graph const& g, Visitor const& v) const {
|
||||
boost::hawick_circuits(g, v);
|
||||
}
|
||||
};
|
||||
|
||||
struct call_hawick_unique_circuits {
|
||||
template <typename Graph, typename Visitor>
|
||||
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());
|
||||
}
|
||||
@@ -64,7 +64,6 @@ void test()
|
||||
template <typename Graph>
|
||||
void build()
|
||||
{
|
||||
typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
|
||||
typedef typename graph_traits<Graph>::vertex_iterator Iterator;
|
||||
typedef typename property_map<Graph, vertex_index_t>::type IndexMap;
|
||||
|
||||
|
||||
@@ -78,10 +78,8 @@ template<typename Graph>
|
||||
void
|
||||
test_circle_layout(Graph*, typename graph_traits<Graph>::vertices_size_type n)
|
||||
{
|
||||
typedef typename graph_traits<Graph>::vertex_descriptor vertex;
|
||||
typedef typename graph_traits<Graph>::vertex_iterator vertex_iterator;
|
||||
typedef typename graph_traits<Graph>::vertices_size_type vertices_size_type;
|
||||
typedef typename graph_traits<Graph>::edges_size_type edges_size_type;
|
||||
|
||||
Graph g(n);
|
||||
|
||||
|
||||
@@ -114,10 +114,14 @@ int test_main(int, char* [])
|
||||
make_disconnected_cycles(gVV, num_cycles, cycle_size);
|
||||
reset_edge_index(gVV);
|
||||
std::vector<int> gVV_components(num_vertices(gVV));
|
||||
BOOST_CHECK(connected_components(gVV, &gVV_components[0]) ==
|
||||
boost::iterator_property_map<
|
||||
std::vector<int>::iterator,
|
||||
typename boost::property_map<VVgraph_t, boost::vertex_index_t>::const_type
|
||||
> gVV_components_pm(gVV_components.begin(), get(boost::vertex_index, gVV));
|
||||
BOOST_CHECK(connected_components(gVV, gVV_components_pm) ==
|
||||
static_cast<int>(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<int> gLV_components(num_vertices(gLV));
|
||||
BOOST_CHECK(connected_components(gLV, &gLV_components[0]) ==
|
||||
boost::iterator_property_map<
|
||||
std::vector<int>::iterator,
|
||||
typename boost::property_map<VVgraph_t, boost::vertex_index_t>::const_type
|
||||
> gLV_components_pm(gLV_components.begin(), get(boost::vertex_index, gLV));
|
||||
BOOST_CHECK(connected_components(gLV, gLV_components_pm) ==
|
||||
static_cast<int>(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;
|
||||
|
||||
@@ -131,7 +131,6 @@ void matching_test(std::size_t num_v, const std::string& graph_name)
|
||||
typedef vector_property_map< typename graph_traits<Graph>::vertex_descriptor, vertex_index_map_t > mate_t;
|
||||
typedef typename graph_traits<Graph>::vertex_iterator vertex_iterator_t;
|
||||
typedef typename graph_traits<Graph>::vertex_descriptor vertex_descriptor_t;
|
||||
typedef typename graph_traits<Graph>::vertices_size_type v_size_t;
|
||||
|
||||
const std::size_t double_num_v = num_v * 2;
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user