2
0
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:
Jeremiah Willcock
2013-09-21 20:17:00 +00:00
parent 5e88d92265
commit 5922324c2b
115 changed files with 3392 additions and 321 deletions

View File

@@ -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
:
:
;

View File

@@ -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
View 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 &lt;class <a href="./Graph.html">Graph</a>, class P, class T, class R&gt;
void cycle_canceling(
Graph &amp;g,
const bgl_named_params&lt;P, T, R&gt; &amp; params = <i>all defaults</i>)
<i>// non-named parameter version</i>
template &lt;class <a href="./Graph.html">Graph</a>, class Pred, class Distance, class Reversed, class ResidualCapacity, class Weight&gt;
void cycle_canceling(const Graph &amp; 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&amp; 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 &copy; 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 -->

View File

@@ -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

View File

@@ -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
View 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 &lt;class Graph, class ColorMap&gt;
typename boost::property_traits<ColorMap>::value_type
edge_coloring(const Graph &amp;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&amp; 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 &copy; 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
View 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 &lt;class <a href="./Graph.html">Graph</a>&gt;
typename property_traits&lt;typename property_map &lt; Graph, edge_capacity_t &gt;::type&gt;::value_type
find_flow_cost(const Graph &amp; g,
const bgl_named_params&lt;P, T, R&gt; &amp; params = <i>all defaults</i>)
<i>// non-named parameter version</i>
template&lt;class <a href="./Graph.html">Graph</a>, class Capacity, class ResidualCapacity, class Weight&gt;
typename property_traits&lt;typename property_map &lt; Graph, edge_capacity_t &gt;::type&gt;::value_type
find_flow_cost(const Graph &amp; 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&amp; 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 &copy; 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 -->

View File

@@ -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
View 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 &lt;typename Graph, typename Visitor, typename VertexIndexMap&gt;
void hawick_circuits(Graph const&amp; graph, Visitor visitor, VertexIndexMap const&amp; vim = get(vertex_index, graph));
template &lt;typename Graph, typename Visitor, typename VertexIndexMap&gt;
void hawick_unique_circuits(Graph const&amp; graph, Visitor visitor, VertexIndexMap const&amp; 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 &lt;boost/graph/hawick_circuits.hpp&gt;</code></a></p>
<h3 id="parameters">Parameters</h3>
<p><strong>IN:</strong> <code>Graph const&amp; 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 -&gt; v -&gt; w -&gt; 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&amp; 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">
&copy; 2013 Louis Dionne
</div>

53
doc/hawick_circuits.md Normal file
View File

@@ -0,0 +1,53 @@
<body bgcolor="#ffffff" link="#0000ee" text="#000000" vlink="#551a8b" alink="#ff0000">
![C++ Boost](../../../boost.png)
# `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">
&copy; 2013 Louis Dionne
</div>

View 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 &lt;class <a href="./Graph.html">Graph</a>, class P, class T, class R&gt;
void successive_shortest_path_nonnegative_weights(
Graph &amp;g,
typename graph_traits&lt;Graph&gt;::vertex_descriptor s,
typename graph_traits&lt;Graph&gt;::vertex_descriptor t,
const bgl_named_params&lt;P, T, R&gt; &amp; params = <i>all defaults</i>)
<i>// non-named parameter version</i>
template &lt;class <a href="./Graph.html">Graph</a>, class Capacity, class ResidualCapacity, class Reversed, class Pred, class Weight, class Distance, class Distance2, class VertexIndex&gt;
void successive_shortest_path_nonnegative_weights(
const Graph &amp; g,
typename graph_traits&lt;Graph&gt;::vertex_descriptor s,
typename graph_traits&lt;Graph&gt;::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&amp; 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 &copy; 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 -->

View File

@@ -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>

View File

@@ -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

View File

@@ -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 ;

View File

@@ -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)));

View File

@@ -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)

View File

@@ -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)

View File

@@ -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();

View 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;
}

View File

@@ -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]] << " ";

View File

@@ -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>

View File

@@ -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

View File

@@ -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;

View File

@@ -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;

View File

@@ -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
View 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;
}

View 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;
}

View File

@@ -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) {

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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),

View File

@@ -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;

View File

@@ -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>());
}
};

View File

@@ -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;

View File

@@ -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()));

View File

@@ -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;

View File

@@ -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;

View File

@@ -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);
}

View File

@@ -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],

View 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 */

View File

@@ -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:

View File

@@ -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);

View 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 */

View File

@@ -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 {

View File

@@ -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);

View 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

View File

@@ -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;

View 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 */

View File

@@ -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;

View File

@@ -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.
*/

View File

@@ -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)

View File

@@ -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);

View 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

View File

@@ -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;

View File

@@ -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,

View File

@@ -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);

View File

@@ -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>));

View File

@@ -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;

View File

@@ -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;

View File

@@ -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) \

View File

@@ -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;

View File

@@ -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,

View File

@@ -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);}

View File

@@ -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

View File

@@ -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;

View File

@@ -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>));

View File

@@ -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 */

View File

@@ -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

View File

@@ -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 > ));

View File

@@ -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;

View File

@@ -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);
}

View File

@@ -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),

View File

@@ -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 {

View File

@@ -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;

View File

@@ -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.

View File

@@ -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);

View File

@@ -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;

View File

@@ -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)())));

View File

@@ -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] << ": ";

View File

@@ -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

View File

@@ -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);

View File

@@ -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);

View File

@@ -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.

View 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);
}

View File

@@ -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
View 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

View File

@@ -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);

View File

@@ -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))
);
}
}

View File

@@ -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),

View File

@@ -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);

View File

@@ -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);

View File

@@ -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
View 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());
}

View File

@@ -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;

View File

@@ -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);

View File

@@ -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;

View File

@@ -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