mirror of
https://github.com/boostorg/graph.git
synced 2025-05-09 23:14:00 +00:00
Merge from graph_devel_1_33_0 branch
[SVN r25893]
This commit is contained in:
parent
63cfb2e00b
commit
71b302bc49
142
doc/AStarHeuristic.html
Normal file
142
doc/AStarHeuristic.html
Normal file
@ -0,0 +1,142 @@
|
||||
<HTML>
|
||||
<!--
|
||||
-- Copyright (c) 2004 Kris Beevers
|
||||
--
|
||||
-- Permission to use, copy, modify, distribute and sell this software
|
||||
-- and its documentation for any purpose is hereby granted without fee,
|
||||
-- provided that the above copyright notice appears in all copies and
|
||||
-- that both that copyright notice and this permission notice appear
|
||||
-- in supporting documentation. We make no
|
||||
-- representations about the suitability of this software for any
|
||||
-- purpose. It is provided "as is" without express or implied warranty.
|
||||
-->
|
||||
<Head>
|
||||
<Title>Boost Graph Library: AStarHeuristic</Title>
|
||||
<BODY BGCOLOR="#ffffff" LINK="#0000ee" TEXT="#000000" VLINK="#551a8b"
|
||||
ALINK="#ff0000">
|
||||
<IMG SRC="../../../c++boost.gif"
|
||||
ALT="C++ Boost" width="277" height="86">
|
||||
|
||||
<BR Clear>
|
||||
|
||||
<H1>AStar Heuristic Concept</H1>
|
||||
|
||||
This concept defines the interface for the heuristic function of an A*
|
||||
search, which is responsible for estimating the remaining cost from
|
||||
some vertex to a goal. The user can create a class that matches this
|
||||
interface, and then pass objects of the class into <a
|
||||
href="./astar_search.html"><tt>astar_search()</tt></a> to guide the
|
||||
order of vertex examination of the search. The heuristic instance
|
||||
must incorporate any necessary information about goal vertices in the
|
||||
graph.
|
||||
|
||||
For further discussion of the use of heuristics in an A* search, see
|
||||
the documentation of <a
|
||||
href="./astar_search.html">astar_search()</a>.
|
||||
|
||||
<h3>Refinement of</h3>
|
||||
|
||||
<a href="http://www.sgi.com/tech/stl/UnaryFunction.html">Unary
|
||||
Function</a> (must take a single argument -- a graph vertex -- and
|
||||
return a cost value) and <a
|
||||
href="../../utility/CopyConstructible.html">Copy Constructible</a>
|
||||
(copying a heuristic should be a lightweight operation).
|
||||
|
||||
|
||||
<h3>Notation</h3>
|
||||
|
||||
<Table>
|
||||
<TR>
|
||||
<TD><tt>H</tt></TD>
|
||||
<TD>A type that is a model of AStar Heuristic.</TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD><tt>h</tt></TD>
|
||||
<TD>An object of type <tt>H</tt>.</TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD><tt>G</tt></TD>
|
||||
<TD>A type that is a model of Graph.</TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD><tt>g</tt></TD>
|
||||
<TD>An object of type <tt>G</tt>.</TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD><tt>u</tt></TD>
|
||||
<TD>An object of type <tt>boost::graph_traits<G>::vertex_descriptor</tt>.</TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD><tt>CostType</tt></TD>
|
||||
<TD>A type that can be used with the <tt>compare</tt> and
|
||||
<tt>combine</tt> functions passed to A*.</TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD><tt>c</tt></TD>
|
||||
<TD>An object of type <tt>CostType</tt>.</TD>
|
||||
</TR>
|
||||
|
||||
</table>
|
||||
|
||||
<h3>Associated Types</h3>
|
||||
|
||||
none
|
||||
<p>
|
||||
|
||||
<h3>Valid Expressions</h3>
|
||||
|
||||
<table border>
|
||||
<tr>
|
||||
<th>Name</th><th>Expression</th><th>Return Type</th><th>Description</th>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Call Heuristic</td>
|
||||
<td><tt>CostType c = h(u)</tt></td>
|
||||
<td><tt>CostType</tt></td>
|
||||
<td>
|
||||
Called for the target of every out edge of a vertex being examined.
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
|
||||
<h3>Models</h3>
|
||||
|
||||
<ul>
|
||||
<li><a href="./astar_heuristic.html"><tt>astar_heuristic</tt></a>
|
||||
</ul>
|
||||
|
||||
<h3>Concept Checking Class</h3>
|
||||
|
||||
<pre>
|
||||
template <class Heuristic, class Graph>
|
||||
struct AStarHeuristicConcept {
|
||||
void constraints()
|
||||
{
|
||||
function_requires< CopyConstructibleConcept<Heuristic> >();
|
||||
h(u);
|
||||
}
|
||||
Heuristic h;
|
||||
typename graph_traits<Graph>::vertex_descriptor u;
|
||||
};
|
||||
</pre>
|
||||
|
||||
<br>
|
||||
<HR>
|
||||
<TABLE>
|
||||
<TR valign=top>
|
||||
<TD nowrap>Copyright © 2004</TD><TD>
|
||||
<A HREF="http://www.cs.rpi.edu/~beevek/">Kristopher Beevers</A>,
|
||||
Rensselaer Polytechnic Institute (<A
|
||||
HREF="mailto:beevek@cs.rpi.edu">beevek@cs.rpi.edu</A>)
|
||||
</TD></TR></TABLE>
|
||||
|
||||
</BODY>
|
||||
</HTML>
|
217
doc/AStarVisitor.html
Normal file
217
doc/AStarVisitor.html
Normal file
@ -0,0 +1,217 @@
|
||||
<HTML>
|
||||
<!--
|
||||
-- Copyright (c) 2004 Kris Beevers
|
||||
--
|
||||
-- Permission to use, copy, modify, distribute and sell this software
|
||||
-- and its documentation for any purpose is hereby granted without fee,
|
||||
-- provided that the above copyright notice appears in all copies and
|
||||
-- that both that copyright notice and this permission notice appear
|
||||
-- in supporting documentation. We make no
|
||||
-- representations about the suitability of this software for any
|
||||
-- purpose. It is provided "as is" without express or implied warranty.
|
||||
-->
|
||||
<Head>
|
||||
<Title>Boost Graph Library: AStarVisitor</Title>
|
||||
<BODY BGCOLOR="#ffffff" LINK="#0000ee" TEXT="#000000" VLINK="#551a8b"
|
||||
ALINK="#ff0000">
|
||||
<IMG SRC="../../../c++boost.gif"
|
||||
ALT="C++ Boost" width="277" height="86">
|
||||
|
||||
<BR Clear>
|
||||
|
||||
<H1>AStar Visitor Concept</H1>
|
||||
|
||||
This concept defines the visitor interface for <a
|
||||
href="./astar_search.html"><tt>astar_search()</tt></a>. Users can
|
||||
define a class with the AStar Visitor interface and pass an object of
|
||||
the class to <tt>astar_search()</tt>, thereby augmenting the actions
|
||||
taken during the graph search.
|
||||
|
||||
<h3>Refinement of</h3>
|
||||
|
||||
<a href="../../utility/CopyConstructible.html">Copy Constructible</a>
|
||||
(copying a visitor should be a lightweight operation).
|
||||
|
||||
|
||||
<h3>Notation</h3>
|
||||
|
||||
<Table>
|
||||
<TR>
|
||||
<TD><tt>V</tt></TD>
|
||||
<TD>A type that is a model of AStar Visitor.</TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD><tt>vis</tt></TD>
|
||||
<TD>An object of type <tt>V</tt>.</TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD><tt>G</tt></TD>
|
||||
<TD>A type that is a model of Graph.</TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD><tt>g</tt></TD>
|
||||
<TD>An object of type <tt>G</tt>.</TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD><tt>e</tt></TD>
|
||||
<TD>An object of type <tt>boost::graph_traits<G>::edge_descriptor</tt>.</TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD><tt>s,u,v</tt></TD>
|
||||
<TD>An object of type <tt>boost::graph_traits<G>::vertex_descriptor</tt>.</TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD><tt>d</tt></TD>
|
||||
<TD>An object of type <tt>DistanceMap</tt>.</TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD><tt>WeightMap</tt></TD>
|
||||
<TD>A type that is a model of <a
|
||||
href="../../property_map/ReadablePropertyMap.html">Readable Property
|
||||
Map</a>.</TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD><tt>w</tt></TD>
|
||||
<TD>An object of type <tt>WeightMap</tt>.</TD>
|
||||
</TR>
|
||||
|
||||
</table>
|
||||
|
||||
<h3>Associated Types</h3>
|
||||
|
||||
none
|
||||
<p>
|
||||
|
||||
<h3>Valid Expressions</h3>
|
||||
|
||||
<table border>
|
||||
<tr>
|
||||
<th>Name</th><th>Expression</th><th>Return Type</th><th>Description</th>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Initialize Vertex</td>
|
||||
<td><tt>vis.initialize_vertex(u, g)</tt></td>
|
||||
<td><tt>void</tt></td>
|
||||
<td>
|
||||
This is invoked on each vertex of the graph when it is first
|
||||
initialized (i.e., when its property maps are initialized).
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Discover Vertex</td>
|
||||
<td><tt>vis.discover_vertex(u, g)</tt></td>
|
||||
<td><tt>void</tt></td>
|
||||
<td>
|
||||
This is invoked when a vertex is first discovered and is added to the
|
||||
OPEN list.
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Examine Vertex</td>
|
||||
<td><tt>vis.examine_vertex(u, g)</tt></td>
|
||||
<td><tt>void</tt></td>
|
||||
<td>
|
||||
This is invoked on a vertex as it is popped from the queue (i.e. it
|
||||
has the lowest cost on the OPEN list). This happens immediately before
|
||||
<tt>examine_edge()</tt> is invoked on each of the out-edges of vertex
|
||||
<tt>u</tt>.
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Examine Edge</td>
|
||||
<td><tt>vis.examine_edge(e, g)</tt></td>
|
||||
<td><tt>void</tt></td>
|
||||
<td>
|
||||
This is invoked on every out-edge of each vertex after it is
|
||||
examined.
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
|
||||
<tr>
|
||||
<td>Edge Relaxed</td>
|
||||
<td><tt>vis.edge_relaxed(e, g)</tt></td>
|
||||
<td><tt>void</tt></td>
|
||||
<td>
|
||||
Upon examination, if the following condition holds then the edge is
|
||||
relaxed (the distance of its target vertex is reduced) and this method
|
||||
is invoked:
|
||||
<blockquote>
|
||||
<pre>
|
||||
tie(u, s) = incident(e, g);
|
||||
D d_u = get(d, u), d_v = get(d, s);
|
||||
W w_e = get(w, e);
|
||||
assert(compare(combine(d_u, w_e), d_s));
|
||||
</pre>
|
||||
</blockquote>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Edge Not Relaxed</td>
|
||||
<td><tt>vis.edge_not_relaxed(e, g)</tt></td>
|
||||
<td><tt>void</tt></td>
|
||||
<td>
|
||||
Upon examination, if an edge is not relaxed (see above), then this
|
||||
method is invoked.
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Black Target</td>
|
||||
<td><tt>vis.black_target(e, g)</tt></td>
|
||||
<td><tt>void</tt></td>
|
||||
<td>
|
||||
This is invoked when a vertex that is on the CLOSED list is
|
||||
``rediscovered'' via a more efficient path, and is re-added to the
|
||||
OPEN list.
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Finish Vertex</td>
|
||||
<td><tt>vis.finish_vertex(u, g)</tt></td>
|
||||
<td><tt>void</tt></td>
|
||||
<td>
|
||||
This is invoked on a vertex when it is added to the CLOSED list, which
|
||||
happens after all of its out edges have been examined.
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
|
||||
<h3>Models</h3>
|
||||
|
||||
<ul>
|
||||
<li><a href="./astar_visitor.html"><tt>astar_visitor</tt></a>
|
||||
</ul>
|
||||
|
||||
|
||||
<h3>See also</h3>
|
||||
|
||||
<a href="./visitor_concepts.html">Visitor concepts</a>
|
||||
|
||||
<br>
|
||||
<HR>
|
||||
<TABLE>
|
||||
<TR valign=top>
|
||||
<TD nowrap>Copyright © 2004</TD><TD>
|
||||
<A HREF="http://www.cs.rpi.edu/~beevek/">Kristopher Beevers</A>,
|
||||
Rensselaer Polytechnic Institute (<A
|
||||
HREF="mailto:beevek@cs.rpi.edu">beevek@cs.rpi.edu</A>)
|
||||
</TD></TR></TABLE>
|
||||
|
||||
</BODY>
|
||||
</HTML>
|
100
doc/astar_heuristic.html
Normal file
100
doc/astar_heuristic.html
Normal file
@ -0,0 +1,100 @@
|
||||
<HTML>
|
||||
<!--
|
||||
-- Copyright (c) 2004 Kris Beevers
|
||||
--
|
||||
-- Permission to use, copy, modify, distribute and sell this software
|
||||
-- and its documentation for any purpose is hereby granted without fee,
|
||||
-- provided that the above copyright notice appears in all copies and
|
||||
-- that both that copyright notice and this permission notice appear
|
||||
-- in supporting documentation. We make no
|
||||
-- representations about the suitability of this software for any
|
||||
-- purpose. It is provided "as is" without express or implied warranty.
|
||||
-->
|
||||
<Head>
|
||||
<Title>Boost Graph Library: astar_heuristic</Title>
|
||||
<BODY BGCOLOR="#ffffff" LINK="#0000ee" TEXT="#000000" VLINK="#551a8b"
|
||||
ALINK="#ff0000">
|
||||
<IMG SRC="../../../c++boost.gif"
|
||||
ALT="C++ Boost" width="277" height="86">
|
||||
|
||||
<BR Clear>
|
||||
|
||||
<H1>
|
||||
<pre>
|
||||
astar_heuristic<Graph, CostType>
|
||||
</pre>
|
||||
</H1>
|
||||
|
||||
This class is a default implementation of the <a
|
||||
href="./AStarHeuristic.html">AStarHeuristic</a> concept. It
|
||||
implements a "zero" heuristic -- a heuristic function that returns a
|
||||
cost of zero regardless of the vertex it is passed.
|
||||
|
||||
<h3>Model of</h3>
|
||||
|
||||
<a href="./AStarHeuristic.html">AStarHeuristic</a>
|
||||
|
||||
<H3>Template Parameters</H3>
|
||||
|
||||
<P>
|
||||
<TABLE border>
|
||||
<TR>
|
||||
<th>Parameter</th><th>Description</th><th>Default</th>
|
||||
</tr>
|
||||
|
||||
<TR><TD><TT>Graph</TT></TD>
|
||||
<TD>
|
||||
The type of the graph being searched.
|
||||
</TD>
|
||||
<TD></TD>
|
||||
</TR>
|
||||
|
||||
<TR><TD><TT>CostType</TT></TD>
|
||||
<TD>
|
||||
A type that can be used with the <tt>compare</tt> and
|
||||
<tt>combine</tt> functions passed to A*. Typically an integer or
|
||||
floating point type.
|
||||
</TD>
|
||||
<TD></TD>
|
||||
</TR>
|
||||
|
||||
</table>
|
||||
|
||||
<H3>Where Defined</H3>
|
||||
|
||||
<P>
|
||||
<a href="../../../boost/graph/astar_search.hpp">
|
||||
<TT>boost/graph/astar_search.hpp</TT></a>
|
||||
|
||||
<h3>Member Functions</h3>
|
||||
|
||||
This class implements the single member function required by <a
|
||||
href="./AStarHeuristic.html">AStarHeuristic</a>:
|
||||
|
||||
<table border>
|
||||
<tr>
|
||||
<th>Function</th><th>Description</th>
|
||||
</tr>
|
||||
|
||||
<tr><td><tt>
|
||||
CostType operator()(graph_traits<Graph>::vertex_descriptor u);
|
||||
</tt></td><td>
|
||||
Called for the target of every out edge of a vertex being examined.
|
||||
Returns the cost, estimated by the heuristic, from vertex <tt>u</tt>
|
||||
to a goal.
|
||||
</td></tr>
|
||||
|
||||
</table>
|
||||
|
||||
<br>
|
||||
<HR>
|
||||
<TABLE>
|
||||
<TR valign=top>
|
||||
<TD nowrap>Copyright © 2004</TD><TD>
|
||||
<A HREF="http://www.cs.rpi.edu/~beevek/">Kristopher Beevers</A>,
|
||||
Rensselaer Polytechnic Institute (<A
|
||||
HREF="mailto:beevek@cs.rpi.edu">beevek@cs.rpi.edu</A>)
|
||||
</TD></TR></TABLE>
|
||||
|
||||
</BODY>
|
||||
</HTML>
|
477
doc/astar_search.html
Normal file
477
doc/astar_search.html
Normal file
@ -0,0 +1,477 @@
|
||||
<HTML>
|
||||
<!--
|
||||
-- Copyright (c) 2004 Kris Beevers
|
||||
--
|
||||
-- Permission to use, copy, modify, distribute and sell this software
|
||||
-- and its documentation for any purpose is hereby granted without fee,
|
||||
-- provided that the above copyright notice appears in all copies and
|
||||
-- that both that copyright notice and this permission notice appear
|
||||
-- in supporting documentation. We make no
|
||||
-- representations about the suitability of this software for any
|
||||
-- purpose. It is provided "as is" without express or implied warranty.
|
||||
-->
|
||||
<Head>
|
||||
<Title>Boost Graph Library: A* Heuristic Search</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:astar"></A>
|
||||
<TT>astar_search</TT>
|
||||
</H1>
|
||||
|
||||
|
||||
<P>
|
||||
<PRE>
|
||||
<i>// Named parameter interface</i>
|
||||
template <typename VertexListGraph,
|
||||
typename AStarHeuristic,
|
||||
typename P, typename T, typename R>
|
||||
void
|
||||
astar_search
|
||||
(VertexListGraph &g,
|
||||
typename graph_traits<VertexListGraph>::vertex_descriptor s,
|
||||
<a href="AStarHeuristic.html">AStarHeuristic</a> h, const bgl_named_params<P, T, R>& params);
|
||||
|
||||
<i>// Non-named parameter interface</i>
|
||||
template <typename VertexListGraph, typename AStarHeuristic,
|
||||
typename <a href="AStarVisitor.html">AStarVisitor</a>, typename PredecessorMap,
|
||||
typename CostMap, typename DistanceMap,
|
||||
typename WeightMap, typename VertexIndexMap,
|
||||
typename ColorMap,
|
||||
typename <a href="http://www.sgi.com/tech/stl/BinaryPredicate.html">CompareFunction</a>, typename <a href="http://www.sgi.com/tech/stl/BinaryFunction.html">CombineFunction</a>,
|
||||
typename CostInf, typename CostZero>
|
||||
inline void
|
||||
astar_search
|
||||
(VertexListGraph &g,
|
||||
typename graph_traits<VertexListGraph>::vertex_descriptor s,
|
||||
AStarHeuristic h, AStarVisitor vis,
|
||||
PredecessorMap predecessor, CostMap cost,
|
||||
DistanceMap distance, WeightMap weight,
|
||||
VertexIndexMap index_map, ColorMap color,
|
||||
CompareFunction compare, CombineFunction combine,
|
||||
CostInf inf, CostZero zero);
|
||||
</PRE>
|
||||
|
||||
<P>
|
||||
This algorithm implements a heuristic search on a weighted, directed
|
||||
or undirected graph for the case where all edge weights are
|
||||
non-negative.
|
||||
</P>
|
||||
|
||||
<P>
|
||||
The A* algorithm is a <i>heuristic graph search algorithm</i>: an A*
|
||||
search is "guided" by a <i>heuristic function</i>. A heuristic
|
||||
function <i>h(v)</i> is one which estimates the cost from a non-goal
|
||||
state (<i>v</i>) in the graph to some goal state, <i>g</i>.
|
||||
Intuitively, A* follows paths (through the graph) to the goal that are
|
||||
estimated by the heuristic function to be the best paths. Unlike
|
||||
best-first search, A* takes into account the known cost from the start
|
||||
of the search to <i>v</i>; the paths A* takes are guided by a function
|
||||
<i>f(v) = g(v) + h(v)</i>, where <i>h(v)</i> is the heuristic
|
||||
function, and <i>g(v)</i> (sometimes denoted <i>c(s, v)</i>) is the
|
||||
known cost from the start to <i>v</i>. Clearly, the efficiency of A*
|
||||
is highly dependent on the heuristic function with which it is used.
|
||||
</P>
|
||||
|
||||
<P>
|
||||
The A* algorithm is very similar to Dijkstra's Shortest Paths
|
||||
algorithm. This implementation finds all the shortest paths from the
|
||||
start vertex to every other vertex by creating a search tree,
|
||||
examining vertices according to their remaining cost to some goal, as
|
||||
estimated by a heuristic function. Most commonly, A* is used to find
|
||||
some specific goal vertex or vertices in a graph, after which the
|
||||
search is terminated.
|
||||
</P>
|
||||
|
||||
<P>
|
||||
A* is particularly useful for searching <i>implicit</i> graphs.
|
||||
Implicit graphs are graphs that are not completely known at the
|
||||
beginning of the search. Upon visiting a vertex, its neighbors are
|
||||
"generated" and added to the search. Implicit graphs are particularly
|
||||
useful for searching large state spaces -- in gameplaying scenarios
|
||||
(e.g. chess), for example -- in which it may not be possible to store
|
||||
the entire graph. Implicit searches can be performed with this
|
||||
implementation of A* by creating special visitors that generate
|
||||
neighbors of newly-expanded vertices.
|
||||
</P>
|
||||
|
||||
<P>
|
||||
This implementation of A* is based on an OPEN/CLOSED list formulation
|
||||
of the algorithm. Vertices on the OPEN list have been ``discovered''
|
||||
by the algorithm, but not ``expanded'' (we have not discovered their
|
||||
adjacent vertices). Vertices on the CLOSED list have been completely
|
||||
examined by our search (we have expanded them and added their children
|
||||
to the OPEN list). Vertices that are on neither list have not been
|
||||
encountered in any context so far in our search. A major advantage of
|
||||
this formulation of the A* algorithm over other approaches is that it
|
||||
avoids ``cycles'' in the state space; the search will not become
|
||||
trapped by loops in the graph. The OPEN/CLOSED lists are implemented
|
||||
using BGL's vertex coloring mechanisms. Vertices in OPEN are colored
|
||||
gray, vertices in CLOSED are colored black, and undiscovered vertices
|
||||
are colored white.
|
||||
</P>
|
||||
|
||||
<P>
|
||||
The criteria for expanding a vertex on the OPEN list is that it has
|
||||
the lowest <i>f(v) = g(v) + h(v)</i> value of all vertices on OPEN.
|
||||
Cost information about vertices is stored in a property map.
|
||||
</P>
|
||||
|
||||
<P>
|
||||
The following is the pseudocode for the A* heuristic search algorithm.
|
||||
In the pseudocode, <i>h</i> is the heuristic function, <i>w</i> is the
|
||||
edge weight, <i>d</i> is the distance of a vertex from <i>s</i>, and
|
||||
<i>Q</i> is a priority queue, sorted by <i>f</i>, the estimated cost
|
||||
to the goal of the path through a vertex. <i>p</i> is a predecessor
|
||||
map. The visitor event points for the algorithm are indicated by the
|
||||
labels on the right.
|
||||
</P>
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td valign="top">
|
||||
<pre>
|
||||
A*(<i>G</i>, <i>s</i>, <i>h</i>)
|
||||
<b>for</b> each vertex <i>u in V</i>
|
||||
<i>d[u] := f[u] := infinity</i>
|
||||
<i>color[u] :=</i> WHITE
|
||||
<i>p[u] := u</i>
|
||||
<b>end for</b>
|
||||
<i>color[s] :=</i> GRAY
|
||||
<i>d[s] := 0</i>
|
||||
<i>f[s] := h(s)</i>
|
||||
INSERT(<i>Q, s</i>)
|
||||
<b>while</b> (<i>Q != Ø</i>)
|
||||
<i>u :=</i> EXTRACT-MIN(<i>Q</i>)
|
||||
<b>for</b> each vertex <i>v in Adj[u]</i>
|
||||
<b>if</b> (<i>w(u,v) + d[u] < d[v]</i>)
|
||||
<i>d[v] := w(u,v) + d[u]</i>
|
||||
<i>f[v] := d[v] + h(v)</i>
|
||||
<i>p[v] := u</i>
|
||||
<b>if</b> (<i>color[v] =</i> WHITE)
|
||||
<i>color[v] :=</i> GRAY
|
||||
INSERT(<i>Q, v</i>)
|
||||
<b>else if</b> (<i>color[v] =</i> BLACK)
|
||||
<i>color[v] :=</i> GRAY
|
||||
INSERT(<i>Q, v</i>)
|
||||
<b>end if</b>
|
||||
<b>else</b>
|
||||
<i>...</i>
|
||||
<b>end for</b>
|
||||
<i>color[u] :=</i> BLACK
|
||||
<b>end while</b>
|
||||
</pre>
|
||||
</td>
|
||||
<td valign="top">
|
||||
<pre>
|
||||
|
||||
initialize vertex <i>u</i>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
discover vertex <i>s</i>
|
||||
|
||||
examine vertex <i>u</i>
|
||||
examine edge <i>(u,v)</i>
|
||||
|
||||
edge <i>(u,v)</i> relaxed
|
||||
|
||||
|
||||
|
||||
|
||||
discover vertex <i>v</i>
|
||||
|
||||
|
||||
reopen vertex <i>v</i>
|
||||
|
||||
|
||||
edge <i>(u,v)</i> not relaxed
|
||||
|
||||
finish vertex <i>u</i>
|
||||
</pre>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h3>Where Defined</h3>
|
||||
|
||||
<a href="../../../boost/graph/astar_search.hpp"><tt>boost/graph/astar_search.hpp</tt></a>
|
||||
|
||||
<h3>Parameters</h3>
|
||||
|
||||
IN: <tt>VertexListGraph& g</tt>
|
||||
<blockquote>
|
||||
The graph object on which the algorithm will be applied. The type
|
||||
<tt>VertexListGraph</tt> must be a model of the <a
|
||||
href="VertexListGraph.html">
|
||||
Vertex List Graph</a> concept.
|
||||
</blockquote>
|
||||
|
||||
IN: <tt>vertex_descriptor s</tt>
|
||||
<blockquote>
|
||||
The start vertex for the search. All distances will be calculated
|
||||
from this vertex, and the shortest paths tree (recorded in the
|
||||
predecessor map) will be rooted at this vertex.
|
||||
</blockquote>
|
||||
|
||||
IN: <tt>AStarHeuristic h</tt>
|
||||
<blockquote>
|
||||
The heuristic function that guides the search. The type
|
||||
<tt>AStarHeuristic</tt> must be a model of the <a href="AStarHeuristic.html">AStarHeuristic</a>
|
||||
concept.
|
||||
</blockquote>
|
||||
|
||||
<h3>Named Parameters</h3>
|
||||
|
||||
IN: <tt>weight_map(WeightMap w_map)</tt>
|
||||
<blockquote>
|
||||
The weight or ``length'' of each edge in the graph. The weights
|
||||
must all be non-negative; 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/ReadablePropertyMap.html"><tt>Readable
|
||||
Property Map</tt></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>
|
||||
</blockquote>
|
||||
|
||||
IN: <tt>vertex_index_map(VertexIndexMap i_map)</tt>
|
||||
<blockquote>
|
||||
This maps each vertex to an integer in the range <tt>[0,
|
||||
num_vertices(g))</tt>. This is necessary for efficient updates of
|
||||
the heap data structure when an edge is relaxed. The type
|
||||
<tt>VertexIndexMap</tt> must be a model of <a
|
||||
href="../../property_map/ReadablePropertyMap.html"><tt>Readable
|
||||
Property Map</tt></a>. The value type of the map must be an integer
|
||||
type. The vertex descriptor type of the graph needs to be usable as
|
||||
the key type of the map.<br>
|
||||
|
||||
<b>Default:</b> <tt>get(vertex_index, g)</tt>
|
||||
</blockquote>
|
||||
|
||||
OUT: <tt>predecessor_map(PredecessorMap p_map)</tt>
|
||||
<blockquote>
|
||||
|
||||
The predecessor map records the edges in the minimum spanning tree.
|
||||
Upon completion of the algorithm, the edges <tt>(p[u],u)</tt> for
|
||||
all <tt>u</tt> in <tt>V</tt> are in the minimum spanning tree. If
|
||||
<tt>p[u] = u</tt> then <tt>u</tt> is either the start vertex or a
|
||||
vertex that is not reachable from the start. The
|
||||
<tt>PredecessorMap</tt> type must be a <a
|
||||
href="../../property_map/ReadWritePropertyMap.html"><tt>Read/Write
|
||||
Property Map</tt></a> with key and vertex types the same as the
|
||||
vertex descriptor type of the graph.<br>
|
||||
|
||||
<b>Default:</b> <tt>dummy_property_map</tt>
|
||||
</blockquote>
|
||||
|
||||
UTIL/OUT: <tt>distance_map(DistanceMap d_map)</tt>
|
||||
<blockquote>
|
||||
|
||||
The shortest path weight from the start 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/ReadWritePropertyMap.html"><tt>Read/Write
|
||||
Property Map</tt></a>. The vertex descriptor type of the graph
|
||||
needs to be usable as the key type of the distance map. The value
|
||||
type of the distance map is the element type of a <a
|
||||
href="./Monoid.html"><tt>Monoid</tt></a> formed with the
|
||||
<tt>combine</tt> function object and the zero object for the
|
||||
identity element. Also the distance value type must have a <a
|
||||
href="http://www.sgi.com/tech/stl/StrictWeakOrdering.html"><tt>StrictWeakOrdering</tt></a>
|
||||
provided by the <tt>compare</tt> function object.<br>
|
||||
|
||||
<b>Default:</b> <tt>iterator_property_map</tt> created from a
|
||||
<tt>std::vector</tt> with the same value type as the
|
||||
<tt>WeightMap</tt>, and of size <tt>num_vertices(g)</tt>, and using
|
||||
the <tt>i_map</tt> for the index map.
|
||||
</blockquote>
|
||||
|
||||
UTIL/OUT: <tt>rank_map(CostMap c_map)</tt>
|
||||
<blockquote>
|
||||
|
||||
The <i>f</i>-value for each vertex. The <i>f</i>-value is defined
|
||||
as the sum of the cost to get to a vertex from the start vertex, and
|
||||
the estimated cost (as returned by the heuristic function
|
||||
<tt>h</tt>) from the vertex to a goal. The type <tt>CostMap</tt>
|
||||
must be a model of <a
|
||||
href="../../property_map/ReadWritePropertyMap.html"><tt>Read/Write
|
||||
Property Map</tt></a>. The vertex descriptor type of the graph
|
||||
needs to be usable as the key type of the distance map. The value
|
||||
type of the distance map is the element type of a <a
|
||||
href="./Monoid.html"><tt>Monoid</tt></a> formed with the
|
||||
<tt>combine</tt> function object and the zero object for the
|
||||
identity element. Also the distance value type must have a <a
|
||||
href="http://www.sgi.com/tech/stl/StrictWeakOrdering.html"><tt>StrictWeakOrdering</tt></a>
|
||||
provided by the <tt>compare</tt> function object. The value type
|
||||
for this map must be the same as the value type for the distance
|
||||
map.<br>
|
||||
|
||||
<b>Default:</b> <tt>iterator_property_map</tt> created from a
|
||||
<tt>std::vector</tt> with the same value type as the
|
||||
<tt>WeightMap</tt>, and of size <tt>num_vertices(g)</tt>, and using
|
||||
the <tt>i_map</tt> for the index map.
|
||||
</blockquote>
|
||||
|
||||
UTIL/OUT: <tt>color_map(ColorMap c_map)</tt>
|
||||
<blockquote>
|
||||
|
||||
This is used during the execution of the algorithm to mark the
|
||||
vertices, indicating whether they are on the OPEN or CLOSED lists.
|
||||
The vertices start out white and become gray when they are inserted
|
||||
into the OPEN list. They then turn black when they are examined and
|
||||
placed on the CLOSED list. At the end of the algorithm, vertices
|
||||
reachable from the source vertex will have been colored black. All
|
||||
other vertices will still be white. The type <tt>ColorMap</tt> must
|
||||
be a model of <a
|
||||
href="../../property_map/ReadWritePropertyMap.html"><tt>Read/Write
|
||||
Property Map</tt></a>. A vertex descriptor must be usable as the
|
||||
key type of the map, and the value type of the map must be a model
|
||||
of <a href="./ColorValue.html"><tt>Color Value</tt></a>.<br>
|
||||
|
||||
<b>Default:</b> <tt>iterator_property_map</tt> created from a
|
||||
<tt>std::vector</tt> of value type <tt>default_color_type</tt>, with
|
||||
size <tt>num_vertices(g)</tt>, and using the <tt>i_map</tt> for the
|
||||
index map.
|
||||
</blockquote>
|
||||
|
||||
IN: <tt>distance_compare(CompareFunction cmp)</tt>
|
||||
<blockquote>
|
||||
|
||||
This function is use to compare distances to determine which vertex
|
||||
is closer to the start vertex, and to compare <i>f</i>-values to
|
||||
determine which vertex on the OPEN list to examine next. The
|
||||
<tt>CompareFunction</tt> type must be a model of <a
|
||||
href="http://www.sgi.com/tech/stl/BinaryPredicate.html"><tt>Binary
|
||||
Predicate</tt></a> and have argument types that match the value type
|
||||
of the <tt>DistanceMap</tt> property map.<br>
|
||||
|
||||
<b>Default:</b> <tt>std::less<D></tt> with <tt>D = typename
|
||||
property_traits<DistanceMap>::value_type</tt>.
|
||||
</blockquote>
|
||||
|
||||
IN: <tt>distance_combine(CombineFunction cmb)</tt>
|
||||
<blockquote>
|
||||
|
||||
This function is used to combine distances to compute the distance
|
||||
of a path, and to combine distance and heuristic values to compute
|
||||
the <i>f</i>-value of a vertex. The <tt>CombineFunction</tt> type
|
||||
must be a model of <a
|
||||
href="http://www.sgi.com/tech/stl/BinaryFunction.html"><tt>Binary
|
||||
Function</tt></a>. Both argument types of the binary function must
|
||||
match the value type of the <tt>DistanceMap</tt> property map (which
|
||||
is the same as that of the <tt>WeightMap</tt> and <tt>CostMap</tt>
|
||||
property maps). The result type must be the same type as the
|
||||
distance value type.<br>
|
||||
|
||||
<b>Default:</b> <tt>std::plus<D></tt> with <tt>D = typename
|
||||
property_traits<DistanceMap>::value_type</tt>.
|
||||
</blockquote>
|
||||
|
||||
IN: <tt>distance_inf(D inf)</tt>
|
||||
<blockquote>
|
||||
|
||||
The <tt>inf</tt> object must be the greatest value of any <tt>D</tt>
|
||||
object. That is, <tt>compare(d, inf) == true</tt> for any <tt>d !=
|
||||
inf</tt>. The type <tt>D</tt> is the value type of the
|
||||
<tt>DistanceMap</tt>.<br>
|
||||
|
||||
<b>Default:</b> <tt>std::numeric_limits<D>::max()</tt>
|
||||
</blockquote>
|
||||
|
||||
IN: <tt>distance_zero(D zero)</tt>
|
||||
<blockquote>
|
||||
|
||||
The <tt>zero</tt> value must be the identity element for the <a
|
||||
href="./Monoid.html"><tt>Monoid</tt></a> formed by the distance
|
||||
values and the <tt>combine</tt> function object. The type
|
||||
<tt>D</tt> is the value type of the <tt>DistanceMap</tt>.<br>
|
||||
|
||||
<b>Default</b>: <tt>D()</tt> with <tt>D = typename
|
||||
property_traits<DistanceMap>::value_type</tt>.
|
||||
</blockquote>
|
||||
|
||||
OUT: <tt>visitor(AStarVisitor v)</tt>
|
||||
<blockquote>
|
||||
|
||||
Use this to specify actions that you would like to happen during
|
||||
certain event points within the algorithm. The type
|
||||
<tt>AStarVisitor</tt> must be a model of the <a
|
||||
href="AStarVisitor.html"><tt>AStarVisitor</tt></a> concept. The
|
||||
visitor object is passed by value <a href="#1">[1]</a>.<br>
|
||||
|
||||
<b>Default:</b> <tt>astar_visitor<null_visitor></tt>
|
||||
</blockquote>
|
||||
|
||||
<H3>Complexity</H3>
|
||||
|
||||
<P>
|
||||
The time complexity is <i>O((E + V) log V)</i>.
|
||||
|
||||
<h3>Visitor Event Points</h3>
|
||||
|
||||
<ul>
|
||||
<li><b><tt>vis.initialize_vertex(u, g)</tt></b>
|
||||
is invoked on each vertex in the graph before the start of the
|
||||
algorithm.
|
||||
<li><b><tt>vis.discover_vertex(v, g)</tt></b>
|
||||
is invoked when a vertex is first discovered and is added to the
|
||||
OPEN list.
|
||||
<li><b><tt>vis.examine_vertex(u, g)</tt></b>
|
||||
is invoked when a vertex is popped from
|
||||
the queue (i.e., it has the lowest cost on the OPEN list).
|
||||
<li><b><tt>vis.examine_edge(e, g)</tt></b>
|
||||
is invoked on each out-edge of a vertex immediately after it is
|
||||
examined.
|
||||
<li><b><tt>vis.edge_relaxed(e, g)</tt></b>
|
||||
is invoked on edge <i>(u,v)</i> if <i>d[u] + w(u,v) < d[v]</i>.
|
||||
<li><b><tt>vis.edge_not_relaxed(e, g)</tt></b>
|
||||
is invoked if the edge is not relaxed (see above).
|
||||
<li><b><tt>vis.black_target(u, g)</tt></b>
|
||||
is invoked when a vertex that is on the CLOSED list is
|
||||
"rediscovered" via a more efficient path, and is re-added to the
|
||||
OPEN list.
|
||||
<li><b><tt>vis.finish_vertex(u, g)</tt></b>
|
||||
is invoked on a vertex when it is added to the CLOSED list, which
|
||||
happens after all of its out edges have been examined.
|
||||
</ul>
|
||||
|
||||
<H3>Example</H3>
|
||||
|
||||
<P>
|
||||
See <a href="../example/astar-cities.cpp">
|
||||
<TT>example/astar-cities.cpp</TT></a> for an example of
|
||||
using A* search.
|
||||
|
||||
<H3>Notes</H3>
|
||||
|
||||
<a name="1">[1]</a> Since the visitor parameter is passed by value, if
|
||||
your visitor contains state then any changes to the state during the
|
||||
algorithm will be made to a copy of the visitor object, not the
|
||||
visitor object passed in. Therefore you may want the visitor to hold
|
||||
this state by pointer or reference.
|
||||
|
||||
<br>
|
||||
<HR>
|
||||
<TABLE>
|
||||
<TR valign=top>
|
||||
<TD nowrap>Copyright © 2004</TD><TD>
|
||||
<A HREF="http://www.cs.rpi.edu/~beevek/">Kristopher Beevers</A>,
|
||||
Rensselaer Polytechnic Institute (<A
|
||||
HREF="mailto:beevek@cs.rpi.edu">beevek@cs.rpi.edu</A>)
|
||||
</TD></TR></TABLE>
|
||||
|
||||
</BODY>
|
||||
</HTML>
|
112
doc/astar_visitor.html
Normal file
112
doc/astar_visitor.html
Normal file
@ -0,0 +1,112 @@
|
||||
<HTML>
|
||||
<!--
|
||||
-- Copyright (c) 2004 Kris Beevers
|
||||
--
|
||||
-- Permission to use, copy, modify, distribute and sell this software
|
||||
-- and its documentation for any purpose is hereby granted without fee,
|
||||
-- provided that the above copyright notice appears in all copies and
|
||||
-- that both that copyright notice and this permission notice appear
|
||||
-- in supporting documentation. We make no
|
||||
-- representations about the suitability of this software for any
|
||||
-- purpose. It is provided "as is" without express or implied warranty.
|
||||
-->
|
||||
<Head>
|
||||
<Title>Boost Graph Library: astar_visitor</Title>
|
||||
<BODY BGCOLOR="#ffffff" LINK="#0000ee" TEXT="#000000" VLINK="#551a8b"
|
||||
ALINK="#ff0000">
|
||||
<IMG SRC="../../../c++boost.gif"
|
||||
ALT="C++ Boost" width="277" height="86">
|
||||
|
||||
<BR Clear>
|
||||
|
||||
<H1>
|
||||
<pre>
|
||||
astar_visitor<EventVisitorList>
|
||||
</pre>
|
||||
</H1>
|
||||
|
||||
This class is an adapter that converts a list of <a
|
||||
href="./EventVisitor.html">EventVisitor</a>'s (constructed using
|
||||
<tt>std::pair</tt>) into a <a
|
||||
href="./AStarVisitor.html">AStarVisitor</a>.
|
||||
|
||||
|
||||
<h3>Example</h3>
|
||||
|
||||
See the example for <a href="./EventVisitor.html">EventVisitor</a>.
|
||||
|
||||
<h3>Model of</h3>
|
||||
|
||||
<a href="./AStarVisitor.html">AStarVisitor</a>
|
||||
|
||||
<H3>Template Parameters</H3>
|
||||
|
||||
<P>
|
||||
<TABLE border>
|
||||
<TR>
|
||||
<th>Parameter</th><th>Description</th><th>Default</th>
|
||||
</tr>
|
||||
|
||||
<TR><TD><TT>EventVisitorList</TT></TD>
|
||||
<TD>
|
||||
A list of <a href="./EventVisitor.html">EventVisitor</a>'s created
|
||||
with <tt>std::pair</tt>.
|
||||
</TD>
|
||||
<TD><TT><a href="./null_visitor.html"><tt>null_visitor</tt></a></TT></TD>
|
||||
</TR>
|
||||
|
||||
</table>
|
||||
|
||||
<H3>Where Defined</H3>
|
||||
|
||||
<P>
|
||||
<a href="../../../boost/graph/astar_search.hpp">
|
||||
<TT>boost/graph/astar_search.hpp</TT></a>
|
||||
|
||||
<h3>Member Functions</h3>
|
||||
|
||||
This class implements all of the member functions required by <a
|
||||
href="./AStarVisitor.html">AStarVisitor</a>. In each function the
|
||||
appropriate event is dispatched to the <a
|
||||
href="./EventVisitor.html">EventVisitor</a>'s in the
|
||||
EventVisitorList.
|
||||
|
||||
<h3>Non-Member Functions</h3>
|
||||
|
||||
<table border>
|
||||
<tr>
|
||||
<th>Function</th><th>Description</th>
|
||||
</tr>
|
||||
|
||||
<tr><td><tt>
|
||||
template <class EventVisitorList><br>
|
||||
astar_visitor<EventVisitorList><br>
|
||||
make_astar_visitor(EventVisitorList ev_list);
|
||||
</tt></td><td>
|
||||
Returns the event visitor list adapted to be an A* visitor.
|
||||
</td></tr>
|
||||
|
||||
</table>
|
||||
|
||||
<h3>See Also</h3>
|
||||
|
||||
<a href="./visitor_concepts.html">Visitor concepts</a>
|
||||
<p>
|
||||
The following are event visitors: <a
|
||||
href="./predecessor_recorder.html"><tt>predecessor_recorder</tt></a>,
|
||||
<a href="./distance_recorder.html"><tt>distance_recorder</tt></a>,
|
||||
<a href="./time_stamper.html"><tt>time_stamper</tt></a>,
|
||||
and <a href="./property_writer.html"><tt>property_writer</tt></a>.
|
||||
|
||||
<br>
|
||||
<HR>
|
||||
<TABLE>
|
||||
<TR valign=top>
|
||||
<TD nowrap>Copyright © 2004</TD><TD>
|
||||
<A HREF="http://www.cs.rpi.edu/~beevek/">Kristopher Beevers</A>,
|
||||
Rensselaer Polytechnic Institute (<A
|
||||
HREF="mailto:beevek@cs.rpi.edu">beevek@cs.rpi.edu</A>)
|
||||
</TD></TR></TABLE>
|
||||
|
||||
</BODY>
|
||||
</HTML>
|
@ -352,7 +352,12 @@ Technical Report BN9/71, Stichting Mahtematisch Centrum, Amsterdam, 1971.
|
||||
<dd>T. Kamada and S. Kawai<br>
|
||||
<em>An algorithm for drawing general undirected graphs.</em><br>
|
||||
Information Processing Letters, 31, pp. 7-15, 1989.
|
||||
</DL>
|
||||
|
||||
<p></p><dt><a name="fruchterman91">58</a>
|
||||
<dd>T. Fruchterman and E. Reingold<br>
|
||||
<em>Graph drawing by force-directed placement.</em><br>
|
||||
Software--Practice & Experience, 21 (11), pp. 1129-1164, 1991.
|
||||
</dl>
|
||||
|
||||
<br>
|
||||
<HR>
|
||||
|
160
doc/floyd_warshall_shortest.html
Normal file
160
doc/floyd_warshall_shortest.html
Normal file
@ -0,0 +1,160 @@
|
||||
<HTML>
|
||||
<Head>
|
||||
<Title>Johnson All Pairs Shortest Paths</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:floyd-warshall">
|
||||
<TT>floyd_warshall_all_pairs_shortest_paths</TT>
|
||||
</H1>
|
||||
|
||||
<PRE><em>// Named parameters version</em>
|
||||
template <class VertexListGraph, class DistanceMatrix,
|
||||
class P, class T, class R>
|
||||
bool floyd_warshall_initialized_all_pairs_shortest_paths(
|
||||
const VertexListGraph& g, DistanceMatrix& d,
|
||||
const bgl_named_params<P, T, R>& params)
|
||||
|
||||
template <class VertexAndEdgeListGraph, class DistanceMatrix,
|
||||
class P, class T, class R>
|
||||
bool floyd_warshall_all_pairs_shortest_paths(
|
||||
const VertexAndEdgeListGraph& g, DistanceMatrix& d,
|
||||
const bgl_named_params<P, T, R>& params)
|
||||
|
||||
<em>// Positional parameter versions</em>
|
||||
\begin{verbatim}
|
||||
template <typename VertexListGraph, typename DistanceMatrix,
|
||||
typename BinaryPredicate, typename BinaryFunction,
|
||||
typename Infinity, typename Zero>
|
||||
bool floyd_warshall_initialized_all_pairs_shortest_paths(
|
||||
const VertexListGraph& g, DistanceMatrix& d,
|
||||
const BinaryPredicate& compare, const BinaryFunction& combine,
|
||||
const Infinity& inf, const Zero& zero)
|
||||
|
||||
template <typename VertexAndEdgeListGraph, typename DistanceMatrix,
|
||||
typename WeightMap, typename BinaryPredicate,
|
||||
typename BinaryFunction, typename Infinity, typename Zero>
|
||||
bool floyd_warshall_all_pairs_shortest_paths(
|
||||
const VertexAndEdgeListGraph& g, DistanceMatrix& d,
|
||||
const WeightMap& w, const BinaryPredicate& compare,
|
||||
const BinaryFunction& combine,
|
||||
const Infinity& inf, const Zero& zero)</PRE>
|
||||
|
||||
<P>
|
||||
These algorithms find the shortest distance between every pair of
|
||||
vertices in the graph. The algorithms return false if there is a
|
||||
negative weight cycle in the graph, true otherwise. The shortest
|
||||
distance between each pair of vertices is stored in the distance
|
||||
matrix <code>d</code>. The difference between the two algorithms is in
|
||||
whether the distance matrix is assumed to be initialized or not, as
|
||||
discussed below under the OUT parameter description.
|
||||
|
||||
<P>This algorithm should be used to compute shortest paths between
|
||||
every pair of vertices for dense graphs. For sparse graphs, use <a
|
||||
href="johnson_all_pairs_shortest.html"><code>johnson_all_pairs_shortest_paths</code></a>.
|
||||
|
||||
<H3>Where Defined</H3>
|
||||
|
||||
<P>
|
||||
<a href="../../../boost/graph/floyd_warshall_shortest.hpp"><TT>boost/graph/floyd_warshall_shortest.hpp</TT></a>
|
||||
|
||||
<h3>Parameters</h3>
|
||||
IN: <code>Graph& g</code>
|
||||
<blockquote>
|
||||
A directed or undirected graph. The graph must be a model of <a href="VertexListGraph.html">Vertex List Graph</a> for calls to
|
||||
<code>floyd_warshall_initialized_all_pairs_shortest_paths</code>, and
|
||||
<a href="VertexAndEdgeListGraph.html">Vertex And Edge List Graph</a> for calls to
|
||||
<code>floyd_warshall_all_pairs_shortest_paths</code>.<br>
|
||||
</blockquote>
|
||||
|
||||
OUT: <code>DistanceMatrix& d</code>
|
||||
<blockquote>
|
||||
The length of the shortest path between each pair of vertices
|
||||
<code>u</code>,<code>v</code> are
|
||||
stored in the matrix at location <code>D[u][v]</code>. The
|
||||
DistanceMatrix must be
|
||||
of type <code>{M, I, V}</code> where <code>I</code> is of type
|
||||
<code>vertex_descriptor</code> and <code>V</code> is the
|
||||
type of the <code>weight_map</code>. The set of types must be a model of
|
||||
<a href="BasicMatrix.html">BasicMatrix</a>, with the exceptions that
|
||||
it isn't required to
|
||||
run in constant time, and it must be mutable. The matrix must be
|
||||
properly initialized when it is passed to the function
|
||||
<code>floyd_warshall_initialized_all_pairs_shortest_paths</code>. If the
|
||||
function <code>floyd_warshall_all_pairs_shortest_paths</code> is used then the
|
||||
matrix will be initialized for the user.
|
||||
</blockquote>
|
||||
|
||||
<h3>Named Parameters</h3>
|
||||
|
||||
IN: <code>weight_map(WeightMap w)</code>
|
||||
<blockquote>
|
||||
The weight of length of each edge in the graph. The <code>WeightMap</code>
|
||||
must be a model of <a href="../../property_map/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 <code>value_type</code> of the weight map must be the type of the
|
||||
<code>DistanceMatrix</code>, and must always either be part of the
|
||||
graph passed to the function, or passed in as a parameter.<br>
|
||||
<b>Default:</b> <code>get(edge_weight, g)</code>
|
||||
</blockquote>
|
||||
|
||||
IN: <code>distance_compare(CompareFunction cmp)</code>
|
||||
<blockquote>
|
||||
The function used to compare distances to determine which target
|
||||
vertex is closer to the source vertex. The CompareFunction must be a
|
||||
model of <code>BinaryPredicate</code>. The argument types must match the
|
||||
value type of the <code>WeightMap</code>.<br>
|
||||
|
||||
<b>Default:</b> <code>std::less<WM></code>with <code>WM = typename property_traits<WeightMap>::value_type</code>
|
||||
</blockquote>
|
||||
|
||||
IN: <code>distance_combine(CombineFunction cmb)</code>
|
||||
<blockquote>
|
||||
The function used to combine distance to compute the distance of a
|
||||
path. The CombineFunction must be a model of <code>BinaryFunction</code>.
|
||||
The argument types must match the value type of the <code>WeightMap</code>.
|
||||
The result type must be the same as the distance value type.<br>
|
||||
|
||||
<b>Default:</b> <code>std::plus<WM></code> with <code>WM = typename property_traits<WeightMap>::value_type</code>
|
||||
</blockquote>
|
||||
|
||||
IN: <code>distance_inf(WM inf)</code>
|
||||
<blockquote>
|
||||
The value used to initialize the distance for each vertex before
|
||||
starting the algorithm, and to represent the distance between vertices
|
||||
for which there is not path. Should be larger than any possible valid
|
||||
path length. The argument type must match the value type of the <code>
|
||||
WeightMap</code>.<br>
|
||||
|
||||
<b>Default:</b> <code>std::numeric_limits<WM>::max()</code> with <code>WM = typename property_traits<WeightMap>::value_type</code>
|
||||
</blockquote>
|
||||
|
||||
IN: <code>distance_zero(WM zero)</code>
|
||||
<blockquote>
|
||||
The value used to represent the distance from a vertex to itself, and
|
||||
to determine if a value is negative. The argument type must match the
|
||||
value type of the <code>WeightMap</code>.<br>
|
||||
<b>Default:</b> <code>0</code>
|
||||
</blockquote>
|
||||
|
||||
<h3>Complexity</h3>
|
||||
|
||||
The time complexity is <i>O(V<sup>3</sup>)</i>.
|
||||
|
||||
<br>
|
||||
<HR>
|
||||
<TABLE>
|
||||
<TR valign=top>
|
||||
<TD nowrap>Copyright © 2002-2004</TD><TD>
|
||||
Lauren Foutz, Rensselaer Polytechnic Institute</td>
|
||||
</tr><tr valign="top"><td></td>
|
||||
<td>Scott Hill, Rensselaer Polytechnic Institute
|
||||
</TD></TR></TABLE>
|
||||
|
||||
</BODY>
|
||||
</HTML>
|
206
doc/fruchterman_reingold.html
Normal file
206
doc/fruchterman_reingold.html
Normal file
@ -0,0 +1,206 @@
|
||||
<HTML>
|
||||
<Head>
|
||||
<Title>Boost Graph Library: Fruchterman-Reingold Force-Directed Layout</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>
|
||||
|
||||
<TT>fruchterman_reingold_force_directed_layout</TT>
|
||||
</H1>
|
||||
|
||||
|
||||
<P>
|
||||
<PRE>
|
||||
<i>// named parameter version</i>
|
||||
template<typename Graph, typename PositionMap, typename Dim, typename Param,
|
||||
typename Tag, typename Rest>
|
||||
void
|
||||
fruchterman_reingold_force_directed_layout
|
||||
(const Graph& g,
|
||||
PositionMap position,
|
||||
Dim width,
|
||||
Dim height,
|
||||
const bgl_named_params<Param, Tag, Rest>& params);
|
||||
|
||||
<i>// non-named parameter version</i>
|
||||
template<typename Graph, typename PositionMap, typename Dim,
|
||||
typename AttractiveForce, typename RepulsiveForce,
|
||||
typename ForcePairs, typename DisplacementMap, typename Cooling>
|
||||
void
|
||||
fruchterman_reingold_force_directed_layout
|
||||
(const Graph& g,
|
||||
PositionMap position,
|
||||
Dim width,
|
||||
Dim height,
|
||||
AttractiveForce fa,
|
||||
RepulsiveForce fr,
|
||||
ForcePairs fp,
|
||||
Cooling cool,
|
||||
DisplacementMap displacement);
|
||||
|
||||
template<typename Graph, typename PositionMap, typename Dim>
|
||||
void
|
||||
fruchterman_reingold_force_directed_layout(const Graph& g,
|
||||
PositionMap position,
|
||||
Dim width,
|
||||
Dim height);
|
||||
</PRE>
|
||||
|
||||
<P> This algorithm [<A
|
||||
HREF="bibliography.html#fruchterman91">58</A>] performs layout of
|
||||
unweighted, undirected graphs. Unlike the <a
|
||||
href="kamada_kawai_spring_layout.html">Kamada-Kawai</a> layout
|
||||
algorithm, this algorithm directly supports the layout of disconnected
|
||||
graphs (but see the <tt>force_pairs</tt> named parameter). It is a
|
||||
<em>force-directed</em> algorithm, meaning that vertex layout is
|
||||
determined by the forces pulling vertices together and pushing them
|
||||
apart. Attractive forces occur between adjacent vertices only, whereas
|
||||
repulsive forces occur between every pair of vertices. Each iteration
|
||||
computes the sum of the forces on each vertex, then moves the vertices
|
||||
to their new positions. The movement of vertices is mitigated by the
|
||||
<i>temperature</i> of the system for that iteration: as the algorithm
|
||||
progresses through successive iterations, the temperature should
|
||||
decrease so that vertices settle in place. The cooling schedule,
|
||||
attractive forces, and repulsive forces can be provided by the user.
|
||||
|
||||
<p> The vertices are often placed randomly prior to execution of this algorithm via <a href="random_layout.html"><tt>random_graph_layout</tt></a>.
|
||||
|
||||
<h3>Where Defined</h3>
|
||||
|
||||
<a href="../../../boost/graph/fruchterman_reingold.hpp"><tt>boost/graph/fruchterman_reingold.hpp</tt></a>
|
||||
|
||||
<h3>Parameters</h3>
|
||||
|
||||
IN: <tt>const Graph& g</tt>
|
||||
<blockquote>
|
||||
The graph object on which the algorithm will be applied.
|
||||
The type <tt>Graph</tt> must be a model of
|
||||
<a href="./VertexAndEdgeListGraph.html">Vertex And Edge List Graph</a>.
|
||||
</blockquote>
|
||||
|
||||
IN/OUT: <tt>PositionMap position</tt>
|
||||
<blockquote>
|
||||
The property map that stores the position of each vertex. It should
|
||||
typically be initialized with the vertices at random locations (use
|
||||
<a href="random_layout.html"><tt>random_graph_layout</tt></a>). The
|
||||
type <tt>PositionMap</tt> must be a model of <a
|
||||
href="../../property_map/LvaluePropertyMap.html">Lvalue Property
|
||||
Map</a> such that the vertex descriptor type of <tt>Graph</tt> is
|
||||
convertible to its key type. Its value type must be a structure
|
||||
with fields <tt>x</tt> and <tt>y</tt>, representing the coordinates
|
||||
of the vertex.
|
||||
</blockquote>
|
||||
|
||||
IN: <tt>Dim width</tt>
|
||||
<blockquote>
|
||||
The width of the display area in which layout should occur. On
|
||||
termination of the algorithm, the <tt>x</tt> coordinates of all
|
||||
vertices will fall in <tt>[-width/2, width/2]</tt>.
|
||||
</blockquote>
|
||||
|
||||
IN: <tt>Dim height</tt>
|
||||
<blockquote>
|
||||
The height of the display area in which layout should occur. On
|
||||
termination of the algorithm, the <tt>y</tt> coordinates of all
|
||||
vertices will fall in <tt>[-height/2, height/2]</tt>.
|
||||
</blockquote>
|
||||
|
||||
<h3>Named Parameters</h3>
|
||||
|
||||
IN: <tt>attractive_force(AttractiveForce fa)</tt>
|
||||
<blockquote>
|
||||
Computes the magnitude of the attractive force between two adjacent
|
||||
vertices. The function object <tt>fa</tt> must accept four
|
||||
parameters: the edge descriptor, <tt>k</tt>, the distance between the
|
||||
vertices, and the graph. <tt>k</tt> is the square root of the ratio
|
||||
of the display area to the number of vertices. <br>
|
||||
<b>Default:</b> <tt>square_distance_attractive_force()</tt>, which
|
||||
computes the attractive force as <code>dist<sup>2</sup>/k</code>.
|
||||
</blockquote>
|
||||
|
||||
IN: <tt>repulsive_force(RepulsiveForce fr)</tt>
|
||||
<blockquote>
|
||||
Computes the magnitude of the repulsive force between any two
|
||||
vertices. The function object <tt>fa</tt> must accept five
|
||||
parameters: the two vertex descriptors, <tt>k</tt>, the distance between the
|
||||
vertices, and the graph. <tt>k</tt> is the square root of the ratio
|
||||
of the display area to the number of vertices. <br>
|
||||
<b>Default:</b> <tt>square_distance_repsulsive_force()</tt>, which
|
||||
computes the repulsive force as <code>k<sup>2</sup>/dist</code>.
|
||||
</blockquote>
|
||||
|
||||
IN: <tt>force_pairs(ForcePairs fp)</tt>
|
||||
<blockquote>
|
||||
Enumerates the pairs of vertices on which the repulsive force should
|
||||
be applied. <tt>fp</tt> is a function object taking two parameters:
|
||||
the graph <tt>g</tt> and a binary function object that should be
|
||||
passed each pair of vertices to be considered. The basic formulation
|
||||
of the Fruchterman-Reingold algorithm computes repulsive forces
|
||||
between all pairs of vertices (pass <tt>all_force_pairs()</tt> for
|
||||
this parameter), which is functional for disconnected graphs but
|
||||
tends to push the connected components toward the edges of the
|
||||
display area. The grid variant of the algorithm places a grid over
|
||||
the display area and only computes repulsive forces among vertices
|
||||
within each rectangle in the grid. The grid variant can be more
|
||||
efficient than the basic formulation and tends to produce better
|
||||
layouts for disconnected graphs, but is not better overall: pass
|
||||
<tt>make_grid_force_pairs(width, height, position)</tt> as this
|
||||
parameter to use the grid variant. Other enumeration strategies may
|
||||
yield better results for particular graphs. <br>
|
||||
<b>Default:</b> <tt>make_grid_force_pairs(width, height, position)</tt>
|
||||
</blockquote>
|
||||
|
||||
IN: <tt>cooling(Cooling cool)</tt>
|
||||
<blockquote>
|
||||
Determines the cooling schedule for the algorithm, which affects the
|
||||
rate of movement of vertices and termination of the algorithm. The
|
||||
<tt>cool</tt> parameter is a nullary function object (i.e., one that
|
||||
takes no arguments) and returns the temperature for the current
|
||||
iteration. When the returned temperature is zero, the algorithm
|
||||
terminates. Cooling schedules should begin with some initial
|
||||
temperature and gradually reduce the temperature to zero.<br>
|
||||
<b>Default:</b> <tt>linear_cooling<double>(100)</tt>
|
||||
</blockquote>
|
||||
|
||||
UTIL: <tt>displacement_map(DisplacementMap displacement)</tt>
|
||||
<blockquote>
|
||||
The displacement map is used to compute the amount by which each
|
||||
vertex will move in each step. The <tt>DisplacementMap</tt> type
|
||||
carries the same requirements as the <tt>PositionMap</tt> type.<br>
|
||||
<b>Default:</b> An <tt>iterator_property_map</tt> with a value type
|
||||
of <tt>simple_point<double></tt> and using the given vertex index map.
|
||||
</blockquote>
|
||||
|
||||
IN: <tt>vertex_index_map(VertexIndexMap i_map)</tt>
|
||||
<blockquote>
|
||||
This maps each vertex to an integer in the range <tt>[0,
|
||||
num_vertices(g))</tt>. This is only necessary when no
|
||||
displacement map is provided.
|
||||
The type <tt>VertexIndexMap</tt> must be a model of <a
|
||||
href="../../property_map/ReadablePropertyMap.html">Readable Property
|
||||
Map</a>. The value type of the map must be an integer type. The
|
||||
vertex descriptor type of the graph needs to be usable as the key
|
||||
type of the map.<br>
|
||||
<b>Default:</b> <tt>get(vertex_index, g)</tt>
|
||||
</blockquote>
|
||||
|
||||
<H3>Complexity</H3>
|
||||
|
||||
<P> The time complexity is <i>O(|V|<sup>2</sup> + |E|)</i> for each
|
||||
iteration of the algorithm in the worse case. The average case for the
|
||||
grid variant is <i>O(|V| + |E|)</i>. The number of iterations is
|
||||
determined by the cooling schedule.
|
||||
|
||||
<br>
|
||||
<HR>
|
||||
<TABLE>
|
||||
<TR valign=top>
|
||||
<TD nowrap>Copyright © 2004</TD><TD>
|
||||
<A HREF="../../../people/doug_gregor.html">Doug Gregor</A>, Indiana University
|
||||
</TD></TR></TABLE>
|
||||
|
||||
</BODY>
|
||||
</HTML>
|
@ -46,7 +46,9 @@ between each pair of vertices is stored in the distance matrix
|
||||
<TT>D</TT>. This is one of the more time intensive graph algorithms,
|
||||
having a time complexity of <i>O(V E log V)</i>.
|
||||
|
||||
<P>
|
||||
<P>This algorithm should be used to compute shortest paths between
|
||||
every pair of vertices for sparse graphs. For dense graphs, use <a
|
||||
href="floyd_warshall_shortest.html"><code>floyd_warshall_all_pairs_shortest_paths</code></a>.
|
||||
|
||||
<H3>Where Defined</H3>
|
||||
|
||||
|
94
doc/random_layout.html
Normal file
94
doc/random_layout.html
Normal file
@ -0,0 +1,94 @@
|
||||
<HTML>
|
||||
<Head>
|
||||
<Title>Boost Graph Library: Random Graph Layout</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>
|
||||
|
||||
<TT>random_graph_layout</TT>
|
||||
</H1>
|
||||
|
||||
|
||||
<P>
|
||||
<PRE>
|
||||
<i>// non-named parameter version</i>
|
||||
template<typename Graph, typename PositionMap, typename Dimension,
|
||||
typename RandomNumberGenerator>
|
||||
void
|
||||
random_graph_layout(const Graph& g, PositionMap position_map,
|
||||
Dimension minX, Dimension maxX,
|
||||
Dimension minY, Dimension maxY,
|
||||
RandomNumberGenerator& gen);
|
||||
</PRE>
|
||||
|
||||
<P> This algorithm places the points of the graph at random
|
||||
locations. </p>
|
||||
|
||||
<h3>Where Defined</h3>
|
||||
|
||||
<a href="../../../boost/graph/random_layout.hpp"><tt>boost/graph/random_layout.hpp</tt></a>
|
||||
|
||||
<h3>Parameters</h3>
|
||||
|
||||
IN: <tt>const Graph& g</tt>
|
||||
<blockquote>
|
||||
The graph object on which the algorithm will be applied.
|
||||
The type <tt>Graph</tt> must be a model of
|
||||
<a href="./VertexAndEdgeListGraph.html">Vertex And Edge List Graph</a>.
|
||||
</blockquote>
|
||||
|
||||
IN/OUT: <tt>PositionMap position</tt>
|
||||
<blockquote>
|
||||
The property map that stores the position of each vertex. The type
|
||||
<tt>PositionMap</tt> must be a model of <a
|
||||
href="../../property_map/LvaluePropertyMap.html">Lvalue Property
|
||||
Map</a> such that the vertex descriptor type of <tt>Graph</tt> is
|
||||
convertible to its key type. Its value type must be a structure with
|
||||
fields <tt>x</tt> and <tt>y</tt>, representing the coordinates of
|
||||
the vertex.
|
||||
</blockquote>
|
||||
|
||||
IN: <tt>Dimension minX</tt>
|
||||
<blockquote>
|
||||
The minimum <tt>x</tt> coordinate.
|
||||
</blockquote>
|
||||
|
||||
IN: <tt>Dimension maxX</tt>
|
||||
<blockquote>
|
||||
The maximum <tt>x</tt> coordinate.
|
||||
</blockquote>
|
||||
|
||||
IN: <tt>Dimension minY</tt>
|
||||
<blockquote>
|
||||
The minimum <tt>y</tt> coordinate.
|
||||
</blockquote>
|
||||
|
||||
IN: <tt>Dimension maxY</tt>
|
||||
<blockquote>
|
||||
The maximum <tt>y</tt> coordinate.
|
||||
</blockquote>
|
||||
|
||||
IN/UTIL: <tt>RandomNumberGenerator& gen</tt>
|
||||
<blockquote>
|
||||
A random number generator that will be used to place vertices. The
|
||||
type <tt>RandomNumberGenerator</tt> must model the <a
|
||||
href="../../random/random-concepts.html#number_generator">NumberGenerator</a>
|
||||
concept.
|
||||
</blockquote>
|
||||
|
||||
<H3>Complexity</H3>
|
||||
<P> The time complexity is <i>O(|V|)</i>.
|
||||
|
||||
<br>
|
||||
<HR>
|
||||
<TABLE>
|
||||
<TR valign=top>
|
||||
<TD nowrap>Copyright © 2004</TD><TD>
|
||||
<A HREF="../../../people/doug_gregor.html">Doug Gregor</A>, Indiana University
|
||||
</TD></TR></TABLE>
|
||||
|
||||
</BODY>
|
||||
</HTML>
|
@ -73,6 +73,7 @@
|
||||
<LI><a href="./DFSVisitor.html">DFS Visitor</a>
|
||||
<LI><a href="./DijkstraVisitor.html">Dijkstra Visitor</a>
|
||||
<LI><a href="./BellmanFordVisitor.html">Bellman Ford Visitor</a>
|
||||
<LI><a href="AStarVisitor.html">A* Visitor</a></LI>
|
||||
<LI><a href="./EventVisitor.html">Event Visitor</a>
|
||||
</OL>
|
||||
<li>EventVisitorList Adaptors
|
||||
@ -82,6 +83,7 @@
|
||||
<LI><a href="./dfs_visitor.html"><tt>dfs_visitor</tt></a>
|
||||
<LI><a href="./dijkstra_visitor.html"><tt>dijkstra_visitor</tt></a>
|
||||
<LI><a href="./bellman_visitor.html"><tt>bellman_visitor</tt></a>
|
||||
<li><a href="astar_visitor.html"><tt>astar_visitor</tt></a></li>
|
||||
</OL>
|
||||
<li>Event Visitors
|
||||
<OL>
|
||||
@ -142,6 +144,7 @@
|
||||
<LI><A href="./dag_shortest_paths.html"><tt>dag_shortest_paths</tt></A>
|
||||
<LI><A
|
||||
href="./johnson_all_pairs_shortest.html"><tt>johnson_all_pairs_shortest_paths</tt></A>
|
||||
<li><a href="floyd_warshall_shortest.html"><tt>floyd_warshall_all_pairs_shortest_paths</tt></a></li>
|
||||
</OL>
|
||||
<LI>Minimum Spanning Tree Algorithms
|
||||
<OL>
|
||||
@ -184,8 +187,10 @@
|
||||
<LI><A href="betweenness_centrality.html"><tt>brandes_betweenness_centrality</tt></A></LI>
|
||||
<li>Layout algorithms
|
||||
<ol>
|
||||
<li><a href="random_layout.html"><tt>random_graph_layout</tt></a></li>
|
||||
<li><a href="circle_layout.html"><tt>circle_layout</tt></a></li>
|
||||
<li><a href="kamada_kawai_spring_layout.html"><tt>kamada_kawai_spring_layout</tt></a></li>
|
||||
<li><a href="fruchterman_reingold.html"><tt>fruchterman_reingold_force_directed_layout</tt></li>
|
||||
</ol>
|
||||
</li>
|
||||
<li>Clustering algorithms
|
||||
@ -193,6 +198,7 @@
|
||||
<li><a href="bc_clustering.html"><tt>betweenness_centrality_clustering</tt></li>
|
||||
</ol>
|
||||
</li>
|
||||
<li><a href="astar_search.html"><tt>astar_search</tt></li>
|
||||
</OL>
|
||||
</OL>
|
||||
|
||||
|
@ -42,6 +42,7 @@ the following visitor concepts:
|
||||
<li> <a href="./DFSVisitor.html">DFS Visitor</a>
|
||||
<li> <a href="./DijkstraVisitor.html">Dijkstra Visitor</a>
|
||||
<li> <a href="./BellmanFordVisitor.html">Bellman Ford Visitor</a>
|
||||
<li> <a href="./AStarVisitor.html">A* Visitor</a>
|
||||
<li> <a href="./EventVisitor.html">Event Visitor</a>
|
||||
</ul>
|
||||
|
||||
|
224
example/astar-cities.cpp
Normal file
224
example/astar-cities.cpp
Normal file
@ -0,0 +1,224 @@
|
||||
|
||||
|
||||
//
|
||||
//=======================================================================
|
||||
// Copyright (c) 2004 Kristopher Beevers
|
||||
//
|
||||
// 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/astar_search.hpp>
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/graph/random.hpp>
|
||||
#include <boost/random.hpp>
|
||||
#include <boost/graph/graphviz.hpp>
|
||||
#include <sys/time.h>
|
||||
#include <vector>
|
||||
#include <list>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <math.h> // for sqrt
|
||||
|
||||
using namespace boost;
|
||||
using namespace std;
|
||||
|
||||
|
||||
// auxiliary types
|
||||
struct location
|
||||
{
|
||||
float y, x; // lat, long
|
||||
};
|
||||
typedef float cost;
|
||||
|
||||
template <class Name, class LocMap>
|
||||
class city_writer {
|
||||
public:
|
||||
city_writer(Name n, LocMap l, float _minx, float _maxx,
|
||||
float _miny, float _maxy,
|
||||
unsigned int _ptx, unsigned int _pty)
|
||||
: name(n), loc(l), minx(_minx), maxx(_maxx), miny(_miny),
|
||||
maxy(_maxy), ptx(_ptx), pty(_pty) {}
|
||||
template <class Vertex>
|
||||
void operator()(ostream& out, const Vertex& v) const {
|
||||
float px = 1 - (loc[v].x - minx) / (maxx - minx);
|
||||
float py = (loc[v].y - miny) / (maxy - miny);
|
||||
out << "[label=\"" << name[v] << "\", pos=\""
|
||||
<< static_cast<unsigned int>(ptx * px) << ","
|
||||
<< static_cast<unsigned int>(pty * py)
|
||||
<< "\", fontsize=\"11\"]";
|
||||
}
|
||||
private:
|
||||
Name name;
|
||||
LocMap loc;
|
||||
float minx, maxx, miny, maxy;
|
||||
unsigned int ptx, pty;
|
||||
};
|
||||
|
||||
template <class WeightMap>
|
||||
class time_writer {
|
||||
public:
|
||||
time_writer(WeightMap w) : wm(w) {}
|
||||
template <class Edge>
|
||||
void operator()(ostream &out, const Edge& e) const {
|
||||
out << "[label=\"" << wm[e] << "\", fontsize=\"11\"]";
|
||||
}
|
||||
private:
|
||||
WeightMap wm;
|
||||
};
|
||||
|
||||
|
||||
// euclidean distance heuristic
|
||||
template <class Graph, class CostType, class LocMap>
|
||||
class distance_heuristic : public astar_heuristic<Graph, CostType>
|
||||
{
|
||||
public:
|
||||
typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
|
||||
distance_heuristic(LocMap l, Vertex goal)
|
||||
: m_location(l), m_goal(goal) {}
|
||||
CostType operator()(Vertex u)
|
||||
{
|
||||
CostType dx = m_location[m_goal].x - m_location[u].x;
|
||||
CostType dy = m_location[m_goal].y - m_location[u].y;
|
||||
return ::sqrt(dx * dx + dy * dy);
|
||||
}
|
||||
private:
|
||||
LocMap m_location;
|
||||
Vertex m_goal;
|
||||
};
|
||||
|
||||
|
||||
struct found_goal {}; // exception for termination
|
||||
|
||||
// visitor that terminates when we find the goal
|
||||
template <class Vertex>
|
||||
class astar_goal_visitor : public boost::default_astar_visitor
|
||||
{
|
||||
public:
|
||||
astar_goal_visitor(Vertex goal) : m_goal(goal) {}
|
||||
template <class Graph>
|
||||
void examine_vertex(Vertex u, Graph& g) {
|
||||
if(u == m_goal)
|
||||
throw found_goal();
|
||||
}
|
||||
private:
|
||||
Vertex m_goal;
|
||||
};
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
|
||||
// specify some types
|
||||
typedef adjacency_list<listS, vecS, undirectedS, no_property,
|
||||
property<edge_weight_t, cost> > mygraph_t;
|
||||
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
|
||||
enum nodes {
|
||||
Troy, LakePlacid, Plattsburgh, Massena, Watertown, Utica,
|
||||
Syracuse, Rochester, Buffalo, Ithaca, Binghamton, Woodstock,
|
||||
NewYork, N
|
||||
};
|
||||
const char *name[] = {
|
||||
"Troy", "Lake Placid", "Plattsburgh", "Massena",
|
||||
"Watertown", "Utica", "Syracuse", "Rochester", "Buffalo",
|
||||
"Ithaca", "Binghamton", "Woodstock", "New York"
|
||||
};
|
||||
location locations[] = { // lat/long
|
||||
{42.73, 73.68}, {44.28, 73.99}, {44.70, 73.46},
|
||||
{44.93, 74.89}, {43.97, 75.91}, {43.10, 75.23},
|
||||
{43.04, 76.14}, {43.17, 77.61}, {42.89, 78.86},
|
||||
{42.44, 76.50}, {42.10, 75.91}, {42.04, 74.11},
|
||||
{40.67, 73.94}
|
||||
};
|
||||
edge edge_array[] = {
|
||||
edge(Troy,Utica), edge(Troy,LakePlacid),
|
||||
edge(Troy,Plattsburgh), edge(LakePlacid,Plattsburgh),
|
||||
edge(Plattsburgh,Massena), edge(LakePlacid,Massena),
|
||||
edge(Massena,Watertown), edge(Watertown,Utica),
|
||||
edge(Watertown,Syracuse), edge(Utica,Syracuse),
|
||||
edge(Syracuse,Rochester), edge(Rochester,Buffalo),
|
||||
edge(Syracuse,Ithaca), edge(Ithaca,Binghamton),
|
||||
edge(Ithaca,Rochester), edge(Binghamton,Troy),
|
||||
edge(Binghamton,Woodstock), edge(Binghamton,NewYork),
|
||||
edge(Syracuse,Binghamton), edge(Woodstock,Troy),
|
||||
edge(Woodstock,NewYork)
|
||||
};
|
||||
unsigned int num_edges = sizeof(edge_array) / sizeof(edge);
|
||||
cost weights[] = { // estimated travel time (mins)
|
||||
96, 134, 143, 65, 115, 133, 117, 116, 74, 56,
|
||||
84, 73, 69, 70, 116, 147, 173, 183, 74, 71, 124
|
||||
};
|
||||
|
||||
|
||||
// create graph
|
||||
mygraph_t g(N);
|
||||
WeightMap weightmap = get(edge_weight, g);
|
||||
for(std::size_t j = 0; j < num_edges; ++j) {
|
||||
edge_descriptor e; bool inserted;
|
||||
tie(e, inserted) = add_edge(edge_array[j].first,
|
||||
edge_array[j].second, g);
|
||||
weightmap[e] = weights[j];
|
||||
}
|
||||
|
||||
|
||||
// pick random start/goal
|
||||
mt19937 gen(time(0));
|
||||
vertex start = random_vertex(g, gen);
|
||||
vertex goal = random_vertex(g, gen);
|
||||
|
||||
|
||||
cout << "Start vertex: " << name[start] << endl;
|
||||
cout << "Goal vertex: " << name[goal] << endl;
|
||||
|
||||
ofstream dotfile;
|
||||
dotfile.open("test-astar-cities.dot");
|
||||
write_graphviz(dotfile, g,
|
||||
city_writer<const char **, location*>
|
||||
(name, locations, 73.46, 78.86, 40.67, 44.93,
|
||||
480, 400),
|
||||
time_writer<WeightMap>(weightmap));
|
||||
|
||||
|
||||
vector<mygraph_t::vertex_descriptor> p(num_vertices(g));
|
||||
vector<cost> d(num_vertices(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]).
|
||||
visitor(astar_goal_visitor<vertex>(goal)));
|
||||
|
||||
|
||||
} catch(found_goal fg) { // found a path to the goal
|
||||
list<vertex> shortest_path;
|
||||
for(vertex v = goal;; v = p[v]) {
|
||||
shortest_path.push_front(v);
|
||||
if(p[v] == v)
|
||||
break;
|
||||
}
|
||||
cout << "Shortest path from " << name[start] << " to "
|
||||
<< name[goal] << ": ";
|
||||
list<vertex>::iterator spi = shortest_path.begin();
|
||||
cout << name[start];
|
||||
for(++spi; spi != shortest_path.end(); ++spi)
|
||||
cout << " -> " << name[*spi];
|
||||
cout << endl << "Total travel time: " << d[goal] << endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
cout << "Didn't find a path from " << name[start] << "to"
|
||||
<< name[goal] << "!" << endl;
|
||||
return 0;
|
||||
|
||||
}
|
36
example/test-astar-cities.dot
Normal file
36
example/test-astar-cities.dot
Normal file
@ -0,0 +1,36 @@
|
||||
graph G {
|
||||
0[label="Troy", pos="460,193", fontsize="11"];
|
||||
1[label="Lake Placid", pos="432,338", fontsize="11"];
|
||||
2[label="Plattsburgh", pos="480,378", fontsize="11"];
|
||||
3[label="Massena", pos="352,400", fontsize="11"];
|
||||
4[label="Watertown", pos="262,309", fontsize="11"];
|
||||
5[label="Utica", pos="322,228", fontsize="11"];
|
||||
6[label="Syracuse", pos="241,222", fontsize="11"];
|
||||
7[label="Rochester", pos="111,234", fontsize="11"];
|
||||
8[label="Buffalo", pos="0,208", fontsize="11"];
|
||||
9[label="Ithaca", pos="209,166", fontsize="11"];
|
||||
10[label="Binghamton", pos="262,134", fontsize="11"];
|
||||
11[label="Woodstock", pos="422,128", fontsize="11"];
|
||||
12[label="New York", pos="437,0", fontsize="11"];
|
||||
0--5 [label="96", fontsize="11"];
|
||||
0--1 [label="134", fontsize="11"];
|
||||
0--2 [label="143", fontsize="11"];
|
||||
1--2 [label="65", fontsize="11"];
|
||||
2--3 [label="115", fontsize="11"];
|
||||
1--3 [label="133", fontsize="11"];
|
||||
3--4 [label="117", fontsize="11"];
|
||||
4--5 [label="116", fontsize="11"];
|
||||
4--6 [label="74", fontsize="11"];
|
||||
5--6 [label="56", fontsize="11"];
|
||||
6--7 [label="84", fontsize="11"];
|
||||
7--8 [label="73", fontsize="11"];
|
||||
6--9 [label="69", fontsize="11"];
|
||||
9--10 [label="70", fontsize="11"];
|
||||
9--7 [label="116", fontsize="11"];
|
||||
10--0 [label="147", fontsize="11"];
|
||||
10--11 [label="173", fontsize="11"];
|
||||
10--12 [label="183", fontsize="11"];
|
||||
6--10 [label="74", fontsize="11"];
|
||||
11--0 [label="71", fontsize="11"];
|
||||
11--12 [label="124", fontsize="11"];
|
||||
}
|
390
include/boost/graph/astar_search.hpp
Normal file
390
include/boost/graph/astar_search.hpp
Normal file
@ -0,0 +1,390 @@
|
||||
|
||||
|
||||
//
|
||||
//=======================================================================
|
||||
// Copyright (c) 2004 Kristopher Beevers
|
||||
//
|
||||
// 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_ASTAR_SEARCH_HPP
|
||||
#define BOOST_GRAPH_ASTAR_SEARCH_HPP
|
||||
|
||||
|
||||
#include <functional>
|
||||
#include <boost/limits.hpp>
|
||||
#include <boost/graph/named_function_params.hpp>
|
||||
#include <boost/pending/mutable_queue.hpp>
|
||||
#include <boost/graph/relax.hpp>
|
||||
#include <boost/pending/indirect_cmp.hpp>
|
||||
#include <boost/graph/exception.hpp>
|
||||
#include <boost/graph/breadth_first_search.hpp>
|
||||
|
||||
|
||||
namespace boost {
|
||||
|
||||
|
||||
template <class Heuristic, class Graph>
|
||||
struct AStarHeuristicConcept {
|
||||
void constraints()
|
||||
{
|
||||
function_requires< CopyConstructibleConcept<Heuristic> >();
|
||||
h(u);
|
||||
}
|
||||
Heuristic h;
|
||||
typename graph_traits<Graph>::vertex_descriptor u;
|
||||
};
|
||||
|
||||
|
||||
template <class Graph, class CostType>
|
||||
class astar_heuristic : public std::unary_function<
|
||||
typename graph_traits<Graph>::vertex_descriptor, CostType>
|
||||
{
|
||||
public:
|
||||
typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
|
||||
astar_heuristic() {}
|
||||
CostType operator()(Vertex u) { return static_cast<CostType>(0); }
|
||||
};
|
||||
|
||||
|
||||
|
||||
template <class Visitor, class Graph>
|
||||
struct AStarVisitorConcept {
|
||||
void constraints()
|
||||
{
|
||||
function_requires< CopyConstructibleConcept<Visitor> >();
|
||||
vis.initialize_vertex(u, g);
|
||||
vis.discover_vertex(u, g);
|
||||
vis.examine_vertex(u, g);
|
||||
vis.examine_edge(e, g);
|
||||
vis.edge_relaxed(e, g);
|
||||
vis.edge_not_relaxed(e, g);
|
||||
vis.black_target(e, g);
|
||||
vis.finish_vertex(u, g);
|
||||
}
|
||||
Visitor vis;
|
||||
Graph g;
|
||||
typename graph_traits<Graph>::vertex_descriptor u;
|
||||
typename graph_traits<Graph>::edge_descriptor e;
|
||||
};
|
||||
|
||||
|
||||
template <class Visitors = null_visitor>
|
||||
class astar_visitor : public bfs_visitor<Visitors> {
|
||||
public:
|
||||
astar_visitor() {}
|
||||
astar_visitor(Visitors vis)
|
||||
: bfs_visitor<Visitors>(vis) {}
|
||||
|
||||
template <class Edge, class Graph>
|
||||
void edge_relaxed(Edge e, Graph& g) {
|
||||
invoke_visitors(this->m_vis, e, g, on_edge_relaxed());
|
||||
}
|
||||
template <class Edge, class Graph>
|
||||
void edge_not_relaxed(Edge e, Graph& g) {
|
||||
invoke_visitors(this->m_vis, e, g, on_edge_not_relaxed());
|
||||
}
|
||||
private:
|
||||
template <class Edge, class Graph>
|
||||
void tree_edge(Edge e, Graph& g) {}
|
||||
template <class Edge, class Graph>
|
||||
void non_tree_edge(Edge e, Graph& g) {}
|
||||
};
|
||||
template <class Visitors>
|
||||
astar_visitor<Visitors>
|
||||
make_astar_visitor(Visitors vis) {
|
||||
return astar_visitor<Visitors>(vis);
|
||||
}
|
||||
typedef astar_visitor<> default_astar_visitor;
|
||||
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <class AStarHeuristic, class UniformCostVisitor,
|
||||
class UpdatableQueue, class PredecessorMap,
|
||||
class CostMap, class DistanceMap, class WeightMap,
|
||||
class ColorMap, class BinaryFunction,
|
||||
class BinaryPredicate>
|
||||
struct astar_bfs_visitor
|
||||
{
|
||||
|
||||
typedef typename property_traits<CostMap>::value_type C;
|
||||
typedef typename property_traits<ColorMap>::value_type ColorValue;
|
||||
typedef color_traits<ColorValue> Color;
|
||||
|
||||
|
||||
astar_bfs_visitor(AStarHeuristic h, UniformCostVisitor vis,
|
||||
UpdatableQueue& Q, PredecessorMap p,
|
||||
CostMap c, DistanceMap d, WeightMap w,
|
||||
ColorMap col, BinaryFunction combine,
|
||||
BinaryPredicate compare, C zero)
|
||||
: m_h(h), m_vis(vis), m_Q(Q), m_predecessor(p), m_cost(c),
|
||||
m_distance(d), m_weight(w), m_color(col),
|
||||
m_combine(combine), m_compare(compare), m_zero(zero) {}
|
||||
|
||||
|
||||
template <class Vertex, class Graph>
|
||||
void initialize_vertex(Vertex u, Graph& g) {
|
||||
m_vis.initialize_vertex(u, g);
|
||||
}
|
||||
template <class Vertex, class Graph>
|
||||
void discover_vertex(Vertex u, Graph& g) {
|
||||
m_vis.discover_vertex(u, g);
|
||||
}
|
||||
template <class Vertex, class Graph>
|
||||
void examine_vertex(Vertex u, Graph& g) {
|
||||
m_vis.examine_vertex(u, g);
|
||||
}
|
||||
template <class Vertex, class Graph>
|
||||
void finish_vertex(Vertex u, Graph& g) {
|
||||
m_vis.finish_vertex(u, g);
|
||||
}
|
||||
template <class Edge, class Graph>
|
||||
void examine_edge(Edge e, Graph& g) {
|
||||
if (m_compare(get(m_weight, e), m_zero))
|
||||
throw negative_edge();
|
||||
m_vis.examine_edge(e, g);
|
||||
}
|
||||
template <class Edge, class Graph>
|
||||
void non_tree_edge(Edge, Graph&) {}
|
||||
|
||||
|
||||
|
||||
template <class Edge, class Graph>
|
||||
void tree_edge(Edge e, Graph& g) {
|
||||
m_decreased = relax(e, g, m_weight, m_predecessor, m_distance,
|
||||
m_combine, m_compare);
|
||||
if(m_decreased) {
|
||||
m_vis.edge_relaxed(e, g);
|
||||
put(m_cost, target(e, g),
|
||||
m_combine(get(m_distance, target(e, g)),
|
||||
m_h(target(e, g))));
|
||||
} else
|
||||
m_vis.edge_not_relaxed(e, g);
|
||||
}
|
||||
|
||||
|
||||
template <class Edge, class Graph>
|
||||
void gray_target(Edge e, Graph& g) {
|
||||
m_decreased = relax(e, g, m_weight, m_predecessor, m_distance,
|
||||
m_combine, m_compare);
|
||||
if(m_decreased) {
|
||||
put(m_cost, target(e, g),
|
||||
m_combine(get(m_distance, target(e, g)),
|
||||
m_h(target(e, g))));
|
||||
m_Q.update(target(e, g));
|
||||
m_vis.edge_relaxed(e, g);
|
||||
} else
|
||||
m_vis.edge_not_relaxed(e, g);
|
||||
}
|
||||
|
||||
|
||||
template <class Edge, class Graph>
|
||||
void black_target(Edge e, Graph& g) {
|
||||
m_decreased = relax(e, g, m_weight, m_predecessor, m_distance,
|
||||
m_combine, m_compare);
|
||||
if(m_decreased) {
|
||||
m_vis.edge_relaxed(e, g);
|
||||
put(m_cost, target(e, g),
|
||||
m_combine(get(m_distance, target(e, g)),
|
||||
m_h(target(e, g))));
|
||||
m_Q.push(target(e, g));
|
||||
put(m_color, target(e, g), Color::gray());
|
||||
m_vis.black_target(e, g);
|
||||
} else
|
||||
m_vis.edge_not_relaxed(e, g);
|
||||
}
|
||||
|
||||
|
||||
|
||||
AStarHeuristic m_h;
|
||||
UniformCostVisitor m_vis;
|
||||
UpdatableQueue& m_Q;
|
||||
PredecessorMap m_predecessor;
|
||||
CostMap m_cost;
|
||||
DistanceMap m_distance;
|
||||
WeightMap m_weight;
|
||||
ColorMap m_color;
|
||||
BinaryFunction m_combine;
|
||||
BinaryPredicate m_compare;
|
||||
bool m_decreased;
|
||||
C m_zero;
|
||||
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
|
||||
|
||||
template <typename VertexListGraph, typename AStarHeuristic,
|
||||
typename AStarVisitor, typename PredecessorMap,
|
||||
typename CostMap, typename DistanceMap,
|
||||
typename WeightMap, typename ColorMap,
|
||||
typename VertexIndexMap,
|
||||
typename CompareFunction, typename CombineFunction,
|
||||
typename CostInf, typename CostZero>
|
||||
inline void
|
||||
astar_search_no_init
|
||||
(VertexListGraph &g,
|
||||
typename graph_traits<VertexListGraph>::vertex_descriptor s,
|
||||
AStarHeuristic h, AStarVisitor vis,
|
||||
PredecessorMap predecessor, CostMap cost,
|
||||
DistanceMap distance, WeightMap weight,
|
||||
ColorMap color, VertexIndexMap index_map,
|
||||
CompareFunction compare, CombineFunction combine,
|
||||
CostInf inf, CostZero zero)
|
||||
{
|
||||
typedef indirect_cmp<CostMap, CompareFunction> IndirectCmp;
|
||||
IndirectCmp icmp(cost, compare);
|
||||
|
||||
typedef typename graph_traits<VertexListGraph>::vertex_descriptor
|
||||
Vertex;
|
||||
typedef mutable_queue<Vertex, std::vector<Vertex>,
|
||||
IndirectCmp, VertexIndexMap>
|
||||
MutableQueue;
|
||||
MutableQueue Q(num_vertices(g), icmp, index_map);
|
||||
|
||||
detail::astar_bfs_visitor<AStarHeuristic, AStarVisitor,
|
||||
MutableQueue, PredecessorMap, CostMap, DistanceMap,
|
||||
WeightMap, ColorMap, CombineFunction, CompareFunction>
|
||||
bfs_vis(h, vis, Q, predecessor, cost, distance, weight,
|
||||
color, combine, compare, zero);
|
||||
|
||||
breadth_first_visit(g, s, Q, bfs_vis, color);
|
||||
}
|
||||
|
||||
|
||||
// Non-named parameter interface
|
||||
template <typename VertexListGraph, typename AStarHeuristic,
|
||||
typename AStarVisitor, typename PredecessorMap,
|
||||
typename CostMap, typename DistanceMap,
|
||||
typename WeightMap, typename VertexIndexMap,
|
||||
typename ColorMap,
|
||||
typename CompareFunction, typename CombineFunction,
|
||||
typename CostInf, typename CostZero>
|
||||
inline void
|
||||
astar_search
|
||||
(VertexListGraph &g,
|
||||
typename graph_traits<VertexListGraph>::vertex_descriptor s,
|
||||
AStarHeuristic h, AStarVisitor vis,
|
||||
PredecessorMap predecessor, CostMap cost,
|
||||
DistanceMap distance, WeightMap weight,
|
||||
VertexIndexMap index_map, ColorMap color,
|
||||
CompareFunction compare, CombineFunction combine,
|
||||
CostInf inf, CostZero zero)
|
||||
{
|
||||
|
||||
typedef typename property_traits<ColorMap>::value_type ColorValue;
|
||||
typedef color_traits<ColorValue> Color;
|
||||
typename graph_traits<VertexListGraph>::vertex_iterator ui, ui_end;
|
||||
for (tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui) {
|
||||
put(color, *ui, Color::white());
|
||||
put(distance, *ui, inf);
|
||||
put(cost, *ui, inf);
|
||||
put(predecessor, *ui, *ui);
|
||||
}
|
||||
put(distance, s, zero);
|
||||
put(cost, s, h(s));
|
||||
|
||||
astar_search_no_init
|
||||
(g, s, h, vis, predecessor, cost, distance, weight,
|
||||
color, index_map, compare, combine, inf, zero);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
namespace detail {
|
||||
template <class VertexListGraph, class AStarHeuristic,
|
||||
class CostMap, class DistanceMap, class WeightMap,
|
||||
class IndexMap, class ColorMap, class Params>
|
||||
inline void
|
||||
astar_dispatch2
|
||||
(VertexListGraph& g,
|
||||
typename graph_traits<VertexListGraph>::vertex_descriptor s,
|
||||
AStarHeuristic h, CostMap cost, DistanceMap distance,
|
||||
WeightMap weight, IndexMap index_map, ColorMap color,
|
||||
const Params& params)
|
||||
{
|
||||
dummy_property_map p_map;
|
||||
typedef typename property_traits<CostMap>::value_type C;
|
||||
astar_search
|
||||
(g, s, h,
|
||||
choose_param(get_param(params, graph_visitor),
|
||||
make_astar_visitor(null_visitor())),
|
||||
choose_param(get_param(params, vertex_predecessor), p_map),
|
||||
cost, distance, weight, index_map, color,
|
||||
choose_param(get_param(params, distance_compare_t()),
|
||||
std::less<C>()),
|
||||
choose_param(get_param(params, distance_combine_t()),
|
||||
closed_plus<C>()),
|
||||
choose_param(get_param(params, distance_inf_t()),
|
||||
std::numeric_limits<C>::max()),
|
||||
choose_param(get_param(params, distance_zero_t()),
|
||||
C()));
|
||||
}
|
||||
|
||||
template <class VertexListGraph, class AStarHeuristic,
|
||||
class CostMap, class DistanceMap, class WeightMap,
|
||||
class IndexMap, class ColorMap, class Params>
|
||||
inline void
|
||||
astar_dispatch1
|
||||
(VertexListGraph& g,
|
||||
typename graph_traits<VertexListGraph>::vertex_descriptor s,
|
||||
AStarHeuristic h, CostMap cost, DistanceMap distance,
|
||||
WeightMap weight, IndexMap index_map, ColorMap color,
|
||||
const Params& params)
|
||||
{
|
||||
typedef typename property_traits<WeightMap>::value_type D;
|
||||
typename std::vector<D>::size_type
|
||||
n = is_default_param(distance) ? num_vertices(g) : 1;
|
||||
std::vector<D> distance_map(n);
|
||||
n = is_default_param(cost) ? num_vertices(g) : 1;
|
||||
std::vector<D> cost_map(n);
|
||||
std::vector<default_color_type> color_map(num_vertices(g));
|
||||
default_color_type c = white_color;
|
||||
|
||||
detail::astar_dispatch2
|
||||
(g, s, h,
|
||||
choose_param(cost, make_iterator_property_map
|
||||
(cost_map.begin(), index_map,
|
||||
cost_map[0])),
|
||||
choose_param(distance, make_iterator_property_map
|
||||
(distance_map.begin(), index_map,
|
||||
distance_map[0])),
|
||||
weight, index_map,
|
||||
choose_param(color, make_iterator_property_map
|
||||
(color_map.begin(), index_map, c)),
|
||||
params);
|
||||
}
|
||||
} // namespace detail
|
||||
|
||||
|
||||
// Named parameter interface
|
||||
template <typename VertexListGraph,
|
||||
typename AStarHeuristic,
|
||||
typename P, typename T, typename R>
|
||||
void
|
||||
astar_search
|
||||
(VertexListGraph &g,
|
||||
typename graph_traits<VertexListGraph>::vertex_descriptor s,
|
||||
AStarHeuristic h, const bgl_named_params<P, T, R>& params)
|
||||
{
|
||||
|
||||
detail::astar_dispatch1
|
||||
(g, s, h,
|
||||
get_param(params, vertex_rank),
|
||||
get_param(params, vertex_distance),
|
||||
choose_const_pmap(get_param(params, edge_weight), g, edge_weight),
|
||||
choose_const_pmap(get_param(params, vertex_index), g, vertex_index),
|
||||
get_param(params, vertex_color),
|
||||
params);
|
||||
|
||||
}
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_GRAPH_ASTAR_SEARCH_HPP
|
@ -120,6 +120,8 @@ namespace boost {
|
||||
typedef typename property_traits<DistanceMap>::value_type D_value;
|
||||
typedef typename property_traits<WeightMap>::value_type W_value;
|
||||
|
||||
D_value inf = (std::numeric_limits<D_value>::max)();
|
||||
|
||||
typename GTraits::edge_iterator i, end;
|
||||
|
||||
for (Size k = 0; k < N; ++k) {
|
||||
@ -137,8 +139,8 @@ namespace boost {
|
||||
}
|
||||
|
||||
for (tie(i, end) = edges(g); i != end; ++i)
|
||||
if (compare(combine(get(distance, source(*i, g)),
|
||||
get(weight, *i)),
|
||||
if (compare(inf_combine(get(distance, source(*i, g)),
|
||||
get(weight, *i), inf, combine, compare),
|
||||
get(distance, target(*i,g))))
|
||||
{
|
||||
v.edge_not_minimized(*i, g);
|
||||
|
240
include/boost/graph/floyd_warshall_shortest.hpp
Normal file
240
include/boost/graph/floyd_warshall_shortest.hpp
Normal file
@ -0,0 +1,240 @@
|
||||
// Copyright 2002 Rensselaer Polytechnic Institute
|
||||
|
||||
// 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)
|
||||
|
||||
// Authors: Lauren Foutz
|
||||
// Scott Hill
|
||||
|
||||
/*
|
||||
This file implements the functions
|
||||
|
||||
template <class VertexListGraph, class DistanceMatrix,
|
||||
class P, class T, class R>
|
||||
bool floyd_warshall_initialized_all_pairs_shortest_paths(
|
||||
const VertexListGraph& g, DistanceMatrix& d,
|
||||
const bgl_named_params<P, T, R>& params)
|
||||
|
||||
AND
|
||||
|
||||
template <class VertexAndEdgeListGraph, class DistanceMatrix,
|
||||
class P, class T, class R>
|
||||
bool floyd_warshall_all_pairs_shortest_paths(
|
||||
const VertexAndEdgeListGraph& g, DistanceMatrix& d,
|
||||
const bgl_named_params<P, T, R>& params)
|
||||
*/
|
||||
|
||||
|
||||
#ifndef BOOST_GRAPH_FLOYD_WARSHALL_HPP
|
||||
#define BOOST_GRAPH_FLOYD_WARSHALL_HPP
|
||||
|
||||
#include <boost/property_map.hpp>
|
||||
#include <boost/graph/graph_traits.hpp>
|
||||
#include <boost/graph/named_function_params.hpp>
|
||||
#include <boost/graph/graph_concepts.hpp>
|
||||
#include <boost/graph/relax.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
template <typename VertexListGraph, typename DistanceMatrix,
|
||||
typename BinaryPredicate, typename BinaryFunction,
|
||||
typename Infinity, typename Zero>
|
||||
bool floyd_warshall_initialized_all_pairs_shortest_paths(
|
||||
const VertexListGraph& g, DistanceMatrix& d,
|
||||
const BinaryPredicate& compare,
|
||||
const BinaryFunction& combine, const Infinity& inf,
|
||||
const Zero& zero)
|
||||
{
|
||||
function_requires<VertexListGraphConcept<VertexListGraph> >();
|
||||
|
||||
return detail::floyd_warshall_dispatch(g, d, compare, combine,
|
||||
inf, zero);
|
||||
}
|
||||
|
||||
|
||||
|
||||
template <typename VertexAndEdgeListGraph, typename DistanceMatrix,
|
||||
typename WeightMap, typename BinaryPredicate,
|
||||
typename BinaryFunction, typename Infinity, typename Zero>
|
||||
bool floyd_warshall_all_pairs_shortest_paths(
|
||||
const VertexAndEdgeListGraph& g,
|
||||
DistanceMatrix& d, const WeightMap& w,
|
||||
const BinaryPredicate& compare, const BinaryFunction& combine,
|
||||
const Infinity& inf, const Zero& zero)
|
||||
{
|
||||
function_requires<VertexListGraphConcept<VertexAndEdgeListGraph> >();
|
||||
function_requires<EdgeListGraphConcept<VertexAndEdgeListGraph> >();
|
||||
function_requires<IncidenceGraphConcept<VertexAndEdgeListGraph> >();
|
||||
|
||||
typename graph_traits<VertexAndEdgeListGraph>::vertex_iterator
|
||||
firstv, lastv, firstv2, lastv2;
|
||||
typename graph_traits<VertexAndEdgeListGraph>::edge_iterator first, last;
|
||||
|
||||
|
||||
for(tie(firstv, lastv) = vertices(g); firstv != lastv; firstv++)
|
||||
for(tie(firstv2, lastv2) = vertices(g); firstv2 != lastv2; firstv2++)
|
||||
d[*firstv][*firstv2] = inf;
|
||||
|
||||
|
||||
for(tie(firstv, lastv) = vertices(g); firstv != lastv; firstv++)
|
||||
d[*firstv][*firstv] = 0;
|
||||
|
||||
|
||||
for(tie(first, last) = edges(g); first != last; first++)
|
||||
{
|
||||
if (d[source(*first, g)][target(*first, g)] != inf)
|
||||
d[source(*first, g)][target(*first, g)] =
|
||||
std::min(get(w, *first),
|
||||
d[source(*first, g)][target(*first, g)]);
|
||||
else
|
||||
d[source(*first, g)][target(*first, g)] = get(w, *first);
|
||||
}
|
||||
|
||||
bool is_undirected = is_same<typename
|
||||
graph_traits<VertexAndEdgeListGraph>::directed_category,
|
||||
undirected_tag>::value;
|
||||
if (is_undirected)
|
||||
{
|
||||
for(tie(first, last) = edges(g); first != last; first++)
|
||||
{
|
||||
if (d[target(*first, g)][source(*first, g)] != inf)
|
||||
d[target(*first, g)][source(*first, g)] =
|
||||
std::min(get(w, *first),
|
||||
d[target(*first, g)][source(*first, g)]);
|
||||
else
|
||||
d[target(*first, g)][source(*first, g)] = get(w, *first);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return detail::floyd_warshall_dispatch(g, d, compare, combine,
|
||||
inf, zero);
|
||||
}
|
||||
|
||||
|
||||
namespace detail {
|
||||
template<typename VertexListGraph, typename DistanceMatrix,
|
||||
typename BinaryPredicate, typename BinaryFunction,
|
||||
typename Infinity, typename Zero>
|
||||
bool floyd_warshall_dispatch(const VertexListGraph& g,
|
||||
DistanceMatrix& d, const BinaryPredicate &compare,
|
||||
const BinaryFunction &combine, const Infinity& inf,
|
||||
const Zero& zero)
|
||||
{
|
||||
typename graph_traits<VertexListGraph>::vertex_iterator
|
||||
i, lasti, j, lastj, k, lastk;
|
||||
|
||||
|
||||
for (tie(k, lastk) = vertices(g); k != lastk; k++)
|
||||
for (tie(i, lasti) = vertices(g); i != lasti; i++)
|
||||
for (tie(j, lastj) = vertices(g); j != lastj; j++)
|
||||
{
|
||||
d[*i][*j] = std::min(d[*i][*j],
|
||||
inf_combine(d[*i][*k], d[*k][*j], inf, combine,
|
||||
compare), compare);
|
||||
}
|
||||
|
||||
|
||||
for (tie(i, lasti) = vertices(g); i != lasti; i++)
|
||||
if (compare(d[*i][*i], zero))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
template <class VertexListGraph, class DistanceMatrix,
|
||||
class WeightMap, class P, class T, class R>
|
||||
bool floyd_warshall_init_dispatch(const VertexListGraph& g,
|
||||
DistanceMatrix& d, WeightMap w,
|
||||
const bgl_named_params<P, T, R>& params)
|
||||
{
|
||||
typedef typename property_traits<WeightMap>::value_type WM;
|
||||
|
||||
return floyd_warshall_initialized_all_pairs_shortest_paths(g, d,
|
||||
choose_param(get_param(params, distance_compare_t()),
|
||||
std::less<WM>()),
|
||||
choose_param(get_param(params, distance_combine_t()),
|
||||
std::plus<WM>()),
|
||||
choose_param(get_param(params, distance_inf_t()),
|
||||
std::numeric_limits<WM>::max()),
|
||||
choose_param(get_param(params, distance_zero_t()),
|
||||
WM()));
|
||||
}
|
||||
|
||||
|
||||
|
||||
template <class VertexAndEdgeListGraph, class DistanceMatrix,
|
||||
class WeightMap, class P, class T, class R>
|
||||
bool floyd_warshall_noninit_dispatch(const VertexAndEdgeListGraph& g,
|
||||
DistanceMatrix& d, WeightMap w,
|
||||
const bgl_named_params<P, T, R>& params)
|
||||
{
|
||||
typedef typename property_traits<WeightMap>::value_type WM;
|
||||
|
||||
return floyd_warshall_all_pairs_shortest_paths(g, d, w,
|
||||
choose_param(get_param(params, distance_compare_t()),
|
||||
std::less<WM>()),
|
||||
choose_param(get_param(params, distance_combine_t()),
|
||||
std::plus<WM>()),
|
||||
choose_param(get_param(params, distance_inf_t()),
|
||||
std::numeric_limits<WM>::max()),
|
||||
choose_param(get_param(params, distance_zero_t()),
|
||||
WM()));
|
||||
}
|
||||
|
||||
|
||||
} // namespace detail
|
||||
|
||||
|
||||
|
||||
template <class VertexListGraph, class DistanceMatrix, class P,
|
||||
class T, class R>
|
||||
bool floyd_warshall_initialized_all_pairs_shortest_paths(
|
||||
const VertexListGraph& g, DistanceMatrix& d,
|
||||
const bgl_named_params<P, T, R>& params)
|
||||
{
|
||||
return detail::floyd_warshall_init_dispatch(g, d,
|
||||
choose_const_pmap(get_param(params, edge_weight), g, edge_weight),
|
||||
params);
|
||||
}
|
||||
|
||||
template <class VertexListGraph, class DistanceMatrix>
|
||||
bool floyd_warshall_initialized_all_pairs_shortest_paths(
|
||||
const VertexListGraph& g, DistanceMatrix& d)
|
||||
{
|
||||
bgl_named_params<int,int> params(0);
|
||||
return detail::floyd_warshall_init_dispatch(g, d,
|
||||
get(edge_weight, g), params);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
template <class VertexAndEdgeListGraph, class DistanceMatrix,
|
||||
class P, class T, class R>
|
||||
bool floyd_warshall_all_pairs_shortest_paths(
|
||||
const VertexAndEdgeListGraph& g, DistanceMatrix& d,
|
||||
const bgl_named_params<P, T, R>& params)
|
||||
{
|
||||
return detail::floyd_warshall_noninit_dispatch(g, d,
|
||||
choose_const_pmap(get_param(params, edge_weight), g, edge_weight),
|
||||
params);
|
||||
}
|
||||
|
||||
template <class VertexAndEdgeListGraph, class DistanceMatrix>
|
||||
bool floyd_warshall_all_pairs_shortest_paths(
|
||||
const VertexAndEdgeListGraph& g, DistanceMatrix& d)
|
||||
{
|
||||
bgl_named_params<int,int> params(0);
|
||||
return detail::floyd_warshall_noninit_dispatch(g, d,
|
||||
get(edge_weight, g), params);
|
||||
}
|
||||
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
|
378
include/boost/graph/fruchterman_reingold.hpp
Normal file
378
include/boost/graph/fruchterman_reingold.hpp
Normal file
@ -0,0 +1,378 @@
|
||||
// Copyright 2004 The Trustees of Indiana University.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software
|
||||
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// Authors: Douglas Gregor
|
||||
// Andrew Lumsdaine
|
||||
#ifndef BOOST_GRAPH_FRUCHTERMAN_REINGOLD_FORCE_DIRECTED_LAYOUT_HPP
|
||||
#define BOOST_GRAPH_FRUCHTERMAN_REINGOLD_FORCE_DIRECTED_LAYOUT_HPP
|
||||
|
||||
#include <cmath>
|
||||
#include <boost/graph/graph_traits.hpp>
|
||||
#include <boost/graph/named_function_params.hpp>
|
||||
#include <boost/graph/simple_point.hpp>
|
||||
#include <vector>
|
||||
#include <list>
|
||||
|
||||
namespace boost {
|
||||
|
||||
struct square_distance_attractive_force {
|
||||
template<typename Graph, typename T>
|
||||
T
|
||||
operator()(typename graph_traits<Graph>::edge_descriptor,
|
||||
T k,
|
||||
T d,
|
||||
const Graph&) const
|
||||
{
|
||||
return d * d / k;
|
||||
}
|
||||
};
|
||||
|
||||
struct square_distance_repulsive_force {
|
||||
template<typename Graph, typename T>
|
||||
T
|
||||
operator()(typename graph_traits<Graph>::vertex_descriptor,
|
||||
typename graph_traits<Graph>::vertex_descriptor,
|
||||
T k,
|
||||
T d,
|
||||
const Graph&) const
|
||||
{
|
||||
return k * k / d;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct linear_cooling {
|
||||
typedef T result_type;
|
||||
|
||||
linear_cooling(std::size_t iterations)
|
||||
: temp(T(iterations) / T(10)), step(0.1) { }
|
||||
|
||||
linear_cooling(std::size_t iterations, T temp)
|
||||
: temp(temp), step(temp / T(iterations)) { }
|
||||
|
||||
T operator()()
|
||||
{
|
||||
T old_temp = temp;
|
||||
temp -= step;
|
||||
if (temp < T(0)) temp = T(0);
|
||||
return old_temp;
|
||||
}
|
||||
|
||||
private:
|
||||
T temp;
|
||||
T step;
|
||||
};
|
||||
|
||||
struct all_force_pairs
|
||||
{
|
||||
template<typename Graph, typename ApplyForce >
|
||||
void operator()(const Graph& g, ApplyForce apply_force)
|
||||
{
|
||||
typedef typename graph_traits<Graph>::vertex_iterator vertex_iterator;
|
||||
vertex_iterator v, end;
|
||||
for (tie(v, end) = vertices(g); v != end; ++v) {
|
||||
vertex_iterator u = v;
|
||||
for (++u; u != end; ++u) {
|
||||
apply_force(*u, *v);
|
||||
apply_force(*v, *u);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Dim, typename PositionMap>
|
||||
struct grid_force_pairs
|
||||
{
|
||||
explicit grid_force_pairs(Dim width, Dim height, PositionMap position)
|
||||
: width(width), height(height), position(position)
|
||||
{
|
||||
using std::sqrt;
|
||||
two_k = Dim(2) * sqrt(width*height);
|
||||
}
|
||||
|
||||
template<typename Graph, typename ApplyForce >
|
||||
void operator()(const Graph& g, ApplyForce apply_force)
|
||||
{
|
||||
typedef typename graph_traits<Graph>::vertex_iterator vertex_iterator;
|
||||
typedef typename graph_traits<Graph>::vertex_descriptor vertex_descriptor;
|
||||
typedef std::list<vertex_descriptor> bucket_t;
|
||||
typedef std::vector<bucket_t> buckets_t;
|
||||
|
||||
std::size_t columns = std::size_t(width / two_k);
|
||||
buckets_t buckets(num_vertices(g) / 4);
|
||||
vertex_iterator v, v_end;
|
||||
for (tie(v, v_end) = vertices(g); v != v_end; ++v) {
|
||||
std::size_t column = std::size_t((position[*v].x - width / 2) / two_k);
|
||||
std::size_t row = std::size_t((position[*v].y - height / 2) / two_k);
|
||||
buckets.at(row * columns + column).push_back(*v);
|
||||
}
|
||||
|
||||
typedef typename buckets_t::iterator buckets_iterator;
|
||||
for (buckets_iterator i = buckets.begin(); i != buckets.end(); ++i) {
|
||||
typedef typename bucket_t::iterator bucket_iterator;
|
||||
for (bucket_iterator u = i->begin(); u != i->end(); ++u) {
|
||||
for (bucket_iterator v = i->begin(); v != i->end(); ++v) {
|
||||
if (*u != *v) apply_force(*u, *v);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
Dim width;
|
||||
Dim height;
|
||||
PositionMap position;
|
||||
Dim two_k;
|
||||
};
|
||||
|
||||
template<typename Dim, typename PositionMap>
|
||||
inline grid_force_pairs<Dim, PositionMap>
|
||||
make_grid_force_pairs(Dim width, Dim height, const PositionMap& position)
|
||||
{ return grid_force_pairs<Dim, PositionMap>(width, height, position); }
|
||||
|
||||
template<typename Graph, typename PositionMap, typename Dim>
|
||||
void
|
||||
scale_graph(const Graph& g, PositionMap position,
|
||||
Dim left, Dim top, Dim right, Dim bottom)
|
||||
{
|
||||
if (num_vertices(g) == 0) return;
|
||||
|
||||
if (bottom > top) {
|
||||
using std::swap;
|
||||
swap(bottom, top);
|
||||
}
|
||||
|
||||
typedef typename graph_traits<Graph>::vertex_iterator vertex_iterator;
|
||||
|
||||
// Find min/max ranges
|
||||
Dim minX = position[*vertices(g).first].x, maxX = minX;
|
||||
Dim minY = position[*vertices(g).first].y, maxY = minY;
|
||||
vertex_iterator vi, vi_end;
|
||||
for (tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) {
|
||||
using std::min; // TBD: eric's tricks
|
||||
using std::max;
|
||||
minX = min(minX, position[*vi].x);
|
||||
maxX = max(maxX, position[*vi].x);
|
||||
minY = min(minY, position[*vi].y);
|
||||
maxY = max(maxY, position[*vi].y);
|
||||
}
|
||||
|
||||
// Scale to bounding box provided
|
||||
for (tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) {
|
||||
position[*vi].x = ((position[*vi].x - minX) / (maxX - minX))
|
||||
* (right - left) + left;
|
||||
position[*vi].y = ((position[*vi].y - minY) / (maxY - minY))
|
||||
* (top - bottom) + bottom;
|
||||
}
|
||||
}
|
||||
|
||||
namespace detail {
|
||||
template<typename PositionMap, typename DisplacementMap,
|
||||
typename RepulsiveForce, typename Dim, typename Graph>
|
||||
struct fr_apply_force
|
||||
{
|
||||
typedef typename graph_traits<Graph>::vertex_descriptor vertex_descriptor;
|
||||
|
||||
fr_apply_force(const PositionMap& position,
|
||||
const DisplacementMap& displacement,
|
||||
RepulsiveForce repulsive_force, Dim k, const Graph& g)
|
||||
: position(position), displacement(displacement),
|
||||
repulsive_force(repulsive_force), k(k), g(g)
|
||||
{ }
|
||||
|
||||
void operator()(vertex_descriptor u, vertex_descriptor v)
|
||||
{
|
||||
if (u != v) {
|
||||
using std::sqrt;
|
||||
|
||||
Dim delta_x = position[v].x - position[u].x;
|
||||
Dim delta_y = position[v].y - position[u].y;
|
||||
Dim dist = sqrt(delta_x * delta_x + delta_y * delta_y);
|
||||
Dim fr = repulsive_force(u, v, k, dist, g);
|
||||
displacement[v].x += delta_x / dist * fr;
|
||||
displacement[v].y += delta_y / dist * fr;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
PositionMap position;
|
||||
DisplacementMap displacement;
|
||||
RepulsiveForce repulsive_force;
|
||||
Dim k;
|
||||
const Graph& g;
|
||||
};
|
||||
|
||||
} // end namespace detail
|
||||
|
||||
template<typename Graph, typename PositionMap, typename Dim,
|
||||
typename AttractiveForce, typename RepulsiveForce,
|
||||
typename ForcePairs, typename Cooling, typename DisplacementMap>
|
||||
void
|
||||
fruchterman_reingold_force_directed_layout
|
||||
(const Graph& g,
|
||||
PositionMap position,
|
||||
Dim width,
|
||||
Dim height,
|
||||
AttractiveForce attractive_force,
|
||||
RepulsiveForce repulsive_force,
|
||||
ForcePairs force_pairs,
|
||||
Cooling cool,
|
||||
DisplacementMap displacement)
|
||||
{
|
||||
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;
|
||||
|
||||
using std::sqrt;
|
||||
|
||||
Dim area = width * height;
|
||||
// assume positions are initialized randomly
|
||||
Dim k = sqrt(area / num_vertices(g));
|
||||
|
||||
detail::fr_apply_force<PositionMap, DisplacementMap,
|
||||
RepulsiveForce, Dim, Graph>
|
||||
apply_force(position, displacement, repulsive_force, k, g);
|
||||
|
||||
while (Dim temp = cool()) {
|
||||
// Calculate repulsive forces
|
||||
vertex_iterator v, v_end;
|
||||
for (tie(v, v_end) = vertices(g); v != v_end; ++v) {
|
||||
displacement[*v].x = 0;
|
||||
displacement[*v].y = 0;
|
||||
}
|
||||
force_pairs(g, apply_force);
|
||||
|
||||
// Calculate attractive forces
|
||||
edge_iterator e, e_end;
|
||||
for (tie(e, e_end) = edges(g); e != e_end; ++e) {
|
||||
vertex_descriptor v = source(*e, g);
|
||||
vertex_descriptor u = target(*e, g);
|
||||
Dim delta_x = position[v].x - position[u].x;
|
||||
Dim delta_y = position[v].y - position[u].y;
|
||||
Dim dist = sqrt(delta_x * delta_x + delta_y * delta_y);
|
||||
Dim fa = attractive_force(*e, k, dist, g);
|
||||
|
||||
displacement[v].x -= delta_x / dist * fa;
|
||||
displacement[v].y -= delta_y / dist * fa;
|
||||
displacement[u].x += delta_x / dist * fa;
|
||||
displacement[u].y += delta_y / dist * fa;
|
||||
}
|
||||
|
||||
// Update positions
|
||||
for (tie(v, v_end) = vertices(g); v != v_end; ++v) {
|
||||
using std::min; // TBD: use Eric's crazy hacks here
|
||||
using std::max; // TBD: use Eric's crazy hacks here
|
||||
Dim disp_size = sqrt(displacement[*v].x * displacement[*v].x
|
||||
+ displacement[*v].y * displacement[*v].y);
|
||||
position[*v].x += displacement[*v].x / disp_size * min(disp_size, temp);
|
||||
position[*v].y += displacement[*v].y / disp_size * min(disp_size, temp);
|
||||
position[*v].x = min(width / 2, max(-width / 2, position[*v].x));
|
||||
position[*v].y = min(height / 2, max(-height / 2, position[*v].y));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace detail {
|
||||
template<typename DisplacementMap>
|
||||
struct fr_force_directed_layout
|
||||
{
|
||||
template<typename Graph, typename PositionMap, typename Dim,
|
||||
typename AttractiveForce, typename RepulsiveForce,
|
||||
typename ForcePairs, typename Cooling,
|
||||
typename Param, typename Tag, typename Rest>
|
||||
static void
|
||||
run(const Graph& g,
|
||||
PositionMap position,
|
||||
Dim width,
|
||||
Dim height,
|
||||
AttractiveForce attractive_force,
|
||||
RepulsiveForce repulsive_force,
|
||||
ForcePairs force_pairs,
|
||||
Cooling cool,
|
||||
DisplacementMap displacement,
|
||||
const bgl_named_params<Param, Tag, Rest>&)
|
||||
{
|
||||
fruchterman_reingold_force_directed_layout
|
||||
(g, position, width, height, attractive_force, repulsive_force,
|
||||
force_pairs, cool, displacement);
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct fr_force_directed_layout<error_property_not_found>
|
||||
{
|
||||
template<typename Graph, typename PositionMap, typename Dim,
|
||||
typename AttractiveForce, typename RepulsiveForce,
|
||||
typename ForcePairs, typename Cooling,
|
||||
typename Param, typename Tag, typename Rest>
|
||||
static void
|
||||
run(const Graph& g,
|
||||
PositionMap position,
|
||||
Dim width,
|
||||
Dim height,
|
||||
AttractiveForce attractive_force,
|
||||
RepulsiveForce repulsive_force,
|
||||
ForcePairs force_pairs,
|
||||
Cooling cool,
|
||||
error_property_not_found,
|
||||
const bgl_named_params<Param, Tag, Rest>& params)
|
||||
{
|
||||
std::vector<simple_point<double> > displacements(num_vertices(g));
|
||||
fruchterman_reingold_force_directed_layout
|
||||
(g, position, width, height, attractive_force, repulsive_force,
|
||||
force_pairs, cool,
|
||||
make_iterator_property_map
|
||||
(displacements.begin(),
|
||||
choose_const_pmap(get_param(params, vertex_index), g,
|
||||
vertex_index)));
|
||||
}
|
||||
};
|
||||
|
||||
} // end namespace detail
|
||||
|
||||
template<typename Graph, typename PositionMap, typename Dim, typename Param,
|
||||
typename Tag, typename Rest>
|
||||
void
|
||||
fruchterman_reingold_force_directed_layout
|
||||
(const Graph& g,
|
||||
PositionMap position,
|
||||
Dim width,
|
||||
Dim height,
|
||||
const bgl_named_params<Param, Tag, Rest>& params)
|
||||
{
|
||||
typedef typename property_value<bgl_named_params<Param,Tag,Rest>,
|
||||
vertex_displacement_t>::type D;
|
||||
|
||||
detail::fr_force_directed_layout<D>::run
|
||||
(g, position, width, height,
|
||||
choose_param(get_param(params, attractive_force_t()),
|
||||
square_distance_attractive_force()),
|
||||
choose_param(get_param(params, repulsive_force_t()),
|
||||
square_distance_repulsive_force()),
|
||||
choose_param(get_param(params, force_pairs_t()),
|
||||
make_grid_force_pairs(width, height, position)),
|
||||
choose_param(get_param(params, cooling_t()),
|
||||
linear_cooling<double>(100)),
|
||||
get_param(params, vertex_displacement_t()),
|
||||
params);
|
||||
}
|
||||
|
||||
template<typename Graph, typename PositionMap, typename Dim, typename Param,
|
||||
typename Tag, typename Rest>
|
||||
void
|
||||
fruchterman_reingold_force_directed_layout(const Graph& g,
|
||||
PositionMap position,
|
||||
Dim width,
|
||||
Dim height)
|
||||
{
|
||||
fruchterman_reingold_force_directed_layout
|
||||
(g, position, width, height,
|
||||
attractive_force(square_distance_attractive_force()));
|
||||
}
|
||||
|
||||
} // end namespace boost
|
||||
|
||||
#endif // BOOST_GRAPH_FRUCHTERMAN_REINGOLD_FORCE_DIRECTED_LAYOUT_HPP
|
@ -45,6 +45,11 @@ namespace boost {
|
||||
struct vertex_max_invariant_t { };
|
||||
struct orig_to_copy_t { };
|
||||
struct root_vertex_t { };
|
||||
struct attractive_force_t { };
|
||||
struct repulsive_force_t { };
|
||||
struct force_pairs_t { };
|
||||
struct cooling_t { };
|
||||
struct vertex_displacement_t { };
|
||||
|
||||
namespace detail {
|
||||
template <class T>
|
||||
@ -284,6 +289,42 @@ namespace boost {
|
||||
return Params(c, *this);
|
||||
}
|
||||
|
||||
template <typename VertexDisplacement>
|
||||
bgl_named_params<VertexDisplacement, vertex_displacement_t, self>
|
||||
displacement_map(const VertexDisplacement& c) const {
|
||||
typedef bgl_named_params<VertexDisplacement, vertex_displacement_t, self> Params;
|
||||
return Params(c, *this);
|
||||
}
|
||||
|
||||
template <typename AttractiveForce>
|
||||
bgl_named_params<AttractiveForce, attractive_force_t, self>
|
||||
attractive_force(const AttractiveForce& c) {
|
||||
typedef bgl_named_params<AttractiveForce, attractive_force_t, self> Params;
|
||||
return Params(c, *this);
|
||||
}
|
||||
|
||||
template <typename RepulsiveForce>
|
||||
bgl_named_params<RepulsiveForce, repulsive_force_t, self>
|
||||
repulsive_force(const RepulsiveForce& c) {
|
||||
typedef bgl_named_params<RepulsiveForce, repulsive_force_t, self> Params;
|
||||
return Params(c, *this);
|
||||
}
|
||||
|
||||
template <typename ForcePairs>
|
||||
bgl_named_params<ForcePairs, force_pairs_t, self>
|
||||
force_pairs(const ForcePairs& c) {
|
||||
typedef bgl_named_params<ForcePairs, force_pairs_t, self> Params;
|
||||
return Params(c, *this);
|
||||
}
|
||||
|
||||
template <typename Cooling>
|
||||
bgl_named_params<Cooling, cooling_t, self>
|
||||
cooling(const Cooling& c) {
|
||||
typedef bgl_named_params<Cooling, cooling_t, self> Params;
|
||||
return Params(c, *this);
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
template <typename WeightMap>
|
||||
@ -484,6 +525,41 @@ namespace boost {
|
||||
return Params(c);
|
||||
}
|
||||
|
||||
template <typename VertexDisplacement>
|
||||
bgl_named_params<VertexDisplacement, vertex_displacement_t>
|
||||
displacement_map(const VertexDisplacement& c) {
|
||||
typedef bgl_named_params<VertexDisplacement, vertex_displacement_t> Params;
|
||||
return Params(c);
|
||||
}
|
||||
|
||||
template <typename AttractiveForce>
|
||||
bgl_named_params<AttractiveForce, attractive_force_t>
|
||||
attractive_force(const AttractiveForce& c) {
|
||||
typedef bgl_named_params<AttractiveForce, attractive_force_t> Params;
|
||||
return Params(c);
|
||||
}
|
||||
|
||||
template <typename RepulsiveForce>
|
||||
bgl_named_params<RepulsiveForce, repulsive_force_t>
|
||||
repulsive_force(const RepulsiveForce& c) {
|
||||
typedef bgl_named_params<RepulsiveForce, repulsive_force_t> Params;
|
||||
return Params(c);
|
||||
}
|
||||
|
||||
template <typename ForcePairs>
|
||||
bgl_named_params<ForcePairs, force_pairs_t>
|
||||
force_pairs(const ForcePairs& c) {
|
||||
typedef bgl_named_params<ForcePairs, force_pairs_t> Params;
|
||||
return Params(c);
|
||||
}
|
||||
|
||||
template <typename Cooling>
|
||||
bgl_named_params<Cooling, cooling_t>
|
||||
cooling(const Cooling& c) {
|
||||
typedef bgl_named_params<Cooling, cooling_t> Params;
|
||||
return Params(c);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
// Functions for extracting parameters from bgl_named_params
|
||||
|
||||
|
49
include/boost/graph/random_layout.hpp
Normal file
49
include/boost/graph/random_layout.hpp
Normal file
@ -0,0 +1,49 @@
|
||||
// Copyright 2004 The Trustees of Indiana University.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software
|
||||
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// Authors: Douglas Gregor
|
||||
// Andrew Lumsdaine
|
||||
#ifndef BOOST_GRAPH_RANDOM_LAYOUT_HPP
|
||||
#define BOOST_GRAPH_RANDOM_LAYOUT_HPP
|
||||
|
||||
#include <boost/graph/graph_traits.hpp>
|
||||
#include <boost/random/uniform_int.hpp>
|
||||
#include <boost/random/uniform_01.hpp>
|
||||
#include <boost/random/uniform_real.hpp>
|
||||
#include <boost/type_traits/is_integral.hpp>
|
||||
#include <boost/mpl/if.hpp>
|
||||
|
||||
namespace boost {
|
||||
|
||||
template<typename Graph, typename PositionMap, typename Dimension,
|
||||
typename RandomNumberGenerator>
|
||||
void
|
||||
random_graph_layout(const Graph& g, PositionMap position_map,
|
||||
Dimension minX, Dimension maxX,
|
||||
Dimension minY, Dimension maxY,
|
||||
RandomNumberGenerator& gen)
|
||||
{
|
||||
typedef typename mpl::if_<is_integral<Dimension>,
|
||||
uniform_int<Dimension>,
|
||||
uniform_real<Dimension> >::type distrib_t;
|
||||
typedef typename mpl::if_<is_integral<Dimension>,
|
||||
RandomNumberGenerator&,
|
||||
uniform_01<RandomNumberGenerator, Dimension> >
|
||||
::type gen_t;
|
||||
|
||||
gen_t my_gen(gen);
|
||||
distrib_t x(minX, maxX);
|
||||
distrib_t y(minY, maxY);
|
||||
typename graph_traits<Graph>::vertex_iterator vi, vi_end;
|
||||
for(tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) {
|
||||
position_map[*vi].x = x(my_gen);
|
||||
position_map[*vi].y = y(my_gen);
|
||||
}
|
||||
}
|
||||
|
||||
} // end namespace boost
|
||||
|
||||
#endif // BOOST_GRAPH_RANDOM_LAYOUT_HPP
|
@ -1,6 +1,8 @@
|
||||
//
|
||||
//=======================================================================
|
||||
// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
|
||||
// Copyright 2002 Rensselaer Polytechnic Institute
|
||||
//
|
||||
// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
|
||||
//
|
||||
// This file is part of the Boost Graph Library
|
||||
@ -25,6 +27,15 @@
|
||||
//=======================================================================
|
||||
//
|
||||
|
||||
// Copyright 2002 Rensselaer Polytechnic Institute
|
||||
|
||||
// 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)
|
||||
|
||||
// Authors: Lauren Foutz
|
||||
// Scott Hill
|
||||
|
||||
#ifndef BOOST_GRAPH_RELAX_HPP
|
||||
#define BOOST_GRAPH_RELAX_HPP
|
||||
|
||||
@ -35,6 +46,18 @@
|
||||
|
||||
namespace boost {
|
||||
|
||||
template<typename MatrixValue, typename BinaryFunction,
|
||||
typename BinaryPredicate>
|
||||
inline MatrixValue inf_combine(MatrixValue a, MatrixValue b,
|
||||
MatrixValue inf, BinaryFunction combine,
|
||||
BinaryPredicate compare)
|
||||
{
|
||||
if(compare(a, inf) && compare(b, inf))
|
||||
return combine(a, b);
|
||||
else
|
||||
return inf;
|
||||
}
|
||||
|
||||
// The following version of the plus functor prevents
|
||||
// problems due to overflow at positive infinity.
|
||||
|
||||
@ -70,13 +93,15 @@ namespace boost {
|
||||
typedef typename property_traits<WeightMap>::value_type W;
|
||||
D d_u = get(d, u), d_v = get(d, v);
|
||||
W w_e = get(w, e);
|
||||
|
||||
if ( compare(combine(d_u, w_e), d_v) ) {
|
||||
put(d, v, combine(d_u, w_e));
|
||||
D inf = (std::numeric_limits<D>::max)();
|
||||
|
||||
if ( compare(inf_combine(d_u, w_e, inf, combine, compare), d_v) ) {
|
||||
put(d, v, inf_combine(d_u, w_e, inf, combine, compare));
|
||||
put(p, v, u);
|
||||
return true;
|
||||
} else if (is_undirected && compare(combine(d_v, w_e), d_u)) {
|
||||
put(d, u, combine(d_v, w_e));
|
||||
} else if (is_undirected
|
||||
&& compare(inf_combine(d_v, w_e, inf, combine, compare), d_u)) {
|
||||
put(d, u, inf_combine(d_v, w_e, inf, combine, compare));
|
||||
put(p, u, v);
|
||||
return true;
|
||||
} else
|
||||
|
15
include/boost/graph/simple_point.hpp
Normal file
15
include/boost/graph/simple_point.hpp
Normal file
@ -0,0 +1,15 @@
|
||||
#ifndef BOOST_GRAPH_SIMPLE_POINT_HPP
|
||||
#define BOOST_GRAPH_SIMPLE_POINT_HPP
|
||||
|
||||
namespace boost {
|
||||
|
||||
template<typename T>
|
||||
struct simple_point
|
||||
{
|
||||
T x;
|
||||
T y;
|
||||
};
|
||||
|
||||
} // end namespace boost
|
||||
|
||||
#endif // BOOST_GRAPH_SIMPLE_POINT_HPP
|
@ -58,6 +58,9 @@ test-suite graph :
|
||||
|
||||
[ run bundled_properties.cpp ]
|
||||
|
||||
[ run floyd_warshall_test.cpp ]
|
||||
|
||||
[ run astar_search_test.cpp ]
|
||||
;
|
||||
|
||||
# Run SDB tests only when -sSDB= is set.
|
||||
|
213
test/astar_search_test.cpp
Normal file
213
test/astar_search_test.cpp
Normal file
@ -0,0 +1,213 @@
|
||||
|
||||
|
||||
//
|
||||
//=======================================================================
|
||||
// Copyright (c) 2004 Kristopher Beevers
|
||||
//
|
||||
// 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/astar_search.hpp>
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/graph/random.hpp>
|
||||
#include <boost/random.hpp>
|
||||
#include <sys/time.h>
|
||||
#include <vector>
|
||||
#include <list>
|
||||
#include <iostream>
|
||||
#include <math.h> // for sqrt
|
||||
|
||||
using namespace boost;
|
||||
using namespace std;
|
||||
|
||||
|
||||
// auxiliary types
|
||||
struct location
|
||||
{
|
||||
float y, x; // lat, long
|
||||
};
|
||||
typedef float cost;
|
||||
|
||||
template <class Name, class LocMap>
|
||||
class city_writer {
|
||||
public:
|
||||
city_writer(Name n, LocMap l, float _minx, float _maxx,
|
||||
float _miny, float _maxy,
|
||||
unsigned int _ptx, unsigned int _pty)
|
||||
: name(n), loc(l), minx(_minx), maxx(_maxx), miny(_miny),
|
||||
maxy(_maxy), ptx(_ptx), pty(_pty) {}
|
||||
template <class Vertex>
|
||||
void operator()(ostream& out, const Vertex& v) const {
|
||||
float px = 1 - (loc[v].x - minx) / (maxx - minx);
|
||||
float py = (loc[v].y - miny) / (maxy - miny);
|
||||
out << "[label=\"" << name[v] << "\", pos=\""
|
||||
<< static_cast<unsigned int>(ptx * px) << ","
|
||||
<< static_cast<unsigned int>(pty * py)
|
||||
<< "\", fontsize=\"11\"]";
|
||||
}
|
||||
private:
|
||||
Name name;
|
||||
LocMap loc;
|
||||
float minx, maxx, miny, maxy;
|
||||
unsigned int ptx, pty;
|
||||
};
|
||||
|
||||
template <class WeightMap>
|
||||
class time_writer {
|
||||
public:
|
||||
time_writer(WeightMap w) : wm(w) {}
|
||||
template <class Edge>
|
||||
void operator()(ostream &out, const Edge& e) const {
|
||||
out << "[label=\"" << wm[e] << "\", fontsize=\"11\"]";
|
||||
}
|
||||
private:
|
||||
WeightMap wm;
|
||||
};
|
||||
|
||||
|
||||
// euclidean distance heuristic
|
||||
template <class Graph, class CostType, class LocMap>
|
||||
class distance_heuristic : public astar_heuristic<Graph, CostType>
|
||||
{
|
||||
public:
|
||||
typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
|
||||
distance_heuristic(LocMap l, Vertex goal)
|
||||
: m_location(l), m_goal(goal) {}
|
||||
CostType operator()(Vertex u)
|
||||
{
|
||||
CostType dx = m_location[m_goal].x - m_location[u].x;
|
||||
CostType dy = m_location[m_goal].y - m_location[u].y;
|
||||
return ::sqrt(dx * dx + dy * dy);
|
||||
}
|
||||
private:
|
||||
LocMap m_location;
|
||||
Vertex m_goal;
|
||||
};
|
||||
|
||||
|
||||
struct found_goal {}; // exception for termination
|
||||
|
||||
// visitor that terminates when we find the goal
|
||||
template <class Vertex>
|
||||
class astar_goal_visitor : public boost::default_astar_visitor
|
||||
{
|
||||
public:
|
||||
astar_goal_visitor(Vertex goal) : m_goal(goal) {}
|
||||
template <class Graph>
|
||||
void examine_vertex(Vertex u, Graph& g) {
|
||||
if(u == m_goal)
|
||||
throw found_goal();
|
||||
}
|
||||
private:
|
||||
Vertex m_goal;
|
||||
};
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
|
||||
// specify some types
|
||||
typedef adjacency_list<listS, vecS, undirectedS, no_property,
|
||||
property<edge_weight_t, cost> > mygraph_t;
|
||||
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
|
||||
enum nodes {
|
||||
Troy, LakePlacid, Plattsburgh, Massena, Watertown, Utica,
|
||||
Syracuse, Rochester, Buffalo, Ithaca, Binghamton, Woodstock,
|
||||
NewYork, N
|
||||
};
|
||||
const char *name[] = {
|
||||
"Troy", "Lake Placid", "Plattsburgh", "Massena",
|
||||
"Watertown", "Utica", "Syracuse", "Rochester", "Buffalo",
|
||||
"Ithaca", "Binghamton", "Woodstock", "New York"
|
||||
};
|
||||
location locations[] = { // lat/long
|
||||
{42.73, 73.68}, {44.28, 73.99}, {44.70, 73.46},
|
||||
{44.93, 74.89}, {43.97, 75.91}, {43.10, 75.23},
|
||||
{43.04, 76.14}, {43.17, 77.61}, {42.89, 78.86},
|
||||
{42.44, 76.50}, {42.10, 75.91}, {42.04, 74.11},
|
||||
{40.67, 73.94}
|
||||
};
|
||||
edge edge_array[] = {
|
||||
edge(Troy,Utica), edge(Troy,LakePlacid),
|
||||
edge(Troy,Plattsburgh), edge(LakePlacid,Plattsburgh),
|
||||
edge(Plattsburgh,Massena), edge(LakePlacid,Massena),
|
||||
edge(Massena,Watertown), edge(Watertown,Utica),
|
||||
edge(Watertown,Syracuse), edge(Utica,Syracuse),
|
||||
edge(Syracuse,Rochester), edge(Rochester,Buffalo),
|
||||
edge(Syracuse,Ithaca), edge(Ithaca,Binghamton),
|
||||
edge(Ithaca,Rochester), edge(Binghamton,Troy),
|
||||
edge(Binghamton,Woodstock), edge(Binghamton,NewYork),
|
||||
edge(Syracuse,Binghamton), edge(Woodstock,Troy),
|
||||
edge(Woodstock,NewYork)
|
||||
};
|
||||
unsigned int num_edges = sizeof(edge_array) / sizeof(edge);
|
||||
cost weights[] = { // estimated travel time (mins)
|
||||
96, 134, 143, 65, 115, 133, 117, 116, 74, 56,
|
||||
84, 73, 69, 70, 116, 147, 173, 183, 74, 71, 124
|
||||
};
|
||||
|
||||
|
||||
// create graph
|
||||
mygraph_t g(N);
|
||||
WeightMap weightmap = get(edge_weight, g);
|
||||
for(std::size_t j = 0; j < num_edges; ++j) {
|
||||
edge_descriptor e; bool inserted;
|
||||
tie(e, inserted) = add_edge(edge_array[j].first,
|
||||
edge_array[j].second, g);
|
||||
weightmap[e] = weights[j];
|
||||
}
|
||||
|
||||
|
||||
// pick random start/goal
|
||||
mt19937 gen(time(0));
|
||||
vertex start = random_vertex(g, gen);
|
||||
vertex goal = random_vertex(g, gen);
|
||||
|
||||
|
||||
cout << "Start vertex: " << name[start] << endl;
|
||||
cout << "Goal vertex: " << name[goal] << endl;
|
||||
|
||||
vector<mygraph_t::vertex_descriptor> p(num_vertices(g));
|
||||
vector<cost> d(num_vertices(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]).
|
||||
visitor(astar_goal_visitor<vertex>(goal)));
|
||||
|
||||
|
||||
} catch(found_goal fg) { // found a path to the goal
|
||||
list<vertex> shortest_path;
|
||||
for(vertex v = goal;; v = p[v]) {
|
||||
shortest_path.push_front(v);
|
||||
if(p[v] == v)
|
||||
break;
|
||||
}
|
||||
cout << "Shortest path from " << name[start] << " to "
|
||||
<< name[goal] << ": ";
|
||||
list<vertex>::iterator spi = shortest_path.begin();
|
||||
cout << name[start];
|
||||
for(++spi; spi != shortest_path.end(); ++spi)
|
||||
cout << " -> " << name[*spi];
|
||||
cout << endl << "Total travel time: " << d[goal] << endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
cout << "Didn't find a path from " << name[start] << "to"
|
||||
<< name[goal] << "!" << endl;
|
||||
return 0;
|
||||
|
||||
}
|
394
test/floyd_warshall_test.cpp
Normal file
394
test/floyd_warshall_test.cpp
Normal file
@ -0,0 +1,394 @@
|
||||
#include <boost/graph/floyd_warshall_shortest.hpp>
|
||||
#include <map>
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <boost/random/linear_congruential.hpp>
|
||||
#include <boost/graph/graph_utility.hpp>
|
||||
#include <boost/graph/properties.hpp>
|
||||
#include <boost/graph/bellman_ford_shortest_paths.hpp>
|
||||
#include <boost/graph/random.hpp>
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/graph/adjacency_matrix.hpp>
|
||||
#include <boost/test/minimal.hpp>
|
||||
|
||||
template <typename T>
|
||||
struct inf_plus{
|
||||
T operator()(const T& a, const T& b) const {
|
||||
T inf = std::numeric_limits<T>::max();
|
||||
if (a == inf || b == inf){
|
||||
return inf;
|
||||
}
|
||||
return a + b;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<typename Graph>
|
||||
bool acceptance_test(Graph& g, int vec, int e)
|
||||
{
|
||||
boost::minstd_rand ran(vec);
|
||||
|
||||
{
|
||||
typename boost::property_map<Graph, boost::vertex_name_t>::type index =
|
||||
boost::get(boost::vertex_name, g);
|
||||
typename boost::graph_traits<Graph>::vertex_iterator firstv, lastv,
|
||||
firstv2, lastv2;
|
||||
int x = 0;
|
||||
for(boost::tie(firstv, lastv) = boost::vertices(g); firstv != lastv;
|
||||
firstv++){
|
||||
boost::put(index, *firstv, x);
|
||||
x++;
|
||||
}
|
||||
|
||||
|
||||
for(int i = 0; i < e; i++){
|
||||
boost::add_edge(index[ran() % vec], index[ran() % vec], g);
|
||||
}
|
||||
|
||||
|
||||
typename boost::graph_traits<Graph>::edge_iterator first, last;
|
||||
typename boost::property_map<Graph, boost::edge_weight_t>::type
|
||||
local_edge_map = boost::get(boost::edge_weight, g);
|
||||
for(boost::tie(first, last) = boost::edges(g); first != last; first++){
|
||||
if (ran() % vec != 0){
|
||||
boost::put(local_edge_map, *first, ran() % 100);
|
||||
} else {
|
||||
boost::put(local_edge_map, *first, 0 - (ran() % 100));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
typedef typename boost::graph_traits<Graph>::vertex_descriptor vertex_des;
|
||||
std::map<vertex_des,int> matrixRow;
|
||||
std::map<vertex_des, std::map<vertex_des ,int> > matrix;
|
||||
typedef typename boost::property_map<Graph, boost::vertex_distance_t>::type
|
||||
distance_type;
|
||||
distance_type distance_row = boost::get(boost::vertex_distance, g);
|
||||
for(boost::tie(firstv, lastv) = boost::vertices(g); firstv != lastv;
|
||||
firstv++){
|
||||
boost::put(distance_row, *firstv, std::numeric_limits<int>::max());
|
||||
matrixRow[*firstv] = std::numeric_limits<int>::max();
|
||||
}
|
||||
for(boost::tie(firstv, lastv) = boost::vertices(g); firstv != lastv;
|
||||
firstv++){
|
||||
matrix[*firstv] = matrixRow;
|
||||
}
|
||||
for(boost::tie(firstv, lastv) = boost::vertices(g); firstv != lastv;
|
||||
firstv++){
|
||||
matrix[*firstv][*firstv] = 0;
|
||||
}
|
||||
std::map<vertex_des, std::map<vertex_des, int> > matrix3(matrix);
|
||||
std::map<vertex_des, std::map<vertex_des, int> > matrix4(matrix);
|
||||
for(boost::tie(first, last) = boost::edges(g); first != last; first++){
|
||||
if (matrix[boost::source(*first, g)][boost::target(*first, g)]
|
||||
!= std::numeric_limits<int>::max()){
|
||||
matrix[boost::source(*first, g)][boost::target(*first, g)] =
|
||||
std::min(boost::get(local_edge_map, *first),
|
||||
matrix[boost::source(*first, g)][boost::target(*first, g)]);
|
||||
} else {
|
||||
matrix[boost::source(*first, g)][boost::target(*first, g)] =
|
||||
boost::get(local_edge_map, *first);
|
||||
}
|
||||
}
|
||||
bool is_undirected =
|
||||
boost::is_same<typename boost::graph_traits<Graph>::directed_category,
|
||||
boost::undirected_tag>::value;
|
||||
if (is_undirected){
|
||||
for(boost::tie(first, last) = boost::edges(g); first != last; first++){
|
||||
if (matrix[boost::target(*first, g)][boost::source(*first, g)]
|
||||
!= std::numeric_limits<int>::max()){
|
||||
matrix[boost::target(*first, g)][boost::source(*first, g)] =
|
||||
std::min(boost::get(local_edge_map, *first),
|
||||
matrix[boost::target(*first, g)][boost::source(*first, g)]);
|
||||
} else {
|
||||
matrix[boost::target(*first, g)][boost::source(*first, g)] =
|
||||
boost::get(local_edge_map, *first);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool bellman, floyd1, floyd2, floyd3;
|
||||
std::less<int> compare;
|
||||
inf_plus<int> combine;
|
||||
floyd1 =
|
||||
boost::floyd_warshall_initialized_all_pairs_shortest_paths
|
||||
(g,
|
||||
matrix, weight_map(boost::get(boost::edge_weight, g)).
|
||||
distance_compare(compare). distance_combine(combine).
|
||||
distance_inf(std::numeric_limits<int>::max()). distance_zero(0));
|
||||
|
||||
floyd2 =
|
||||
boost::floyd_warshall_all_pairs_shortest_paths
|
||||
(g, matrix3,
|
||||
weight_map(local_edge_map). distance_compare(compare).
|
||||
distance_combine(combine).
|
||||
distance_inf(std::numeric_limits<int>::max()). distance_zero(0));
|
||||
|
||||
floyd3 = boost::floyd_warshall_all_pairs_shortest_paths(g, matrix4);
|
||||
|
||||
|
||||
boost::dummy_property_map dummy_map;
|
||||
std::map<vertex_des, std::map<vertex_des, int> > matrix2;
|
||||
for(boost::tie(firstv, lastv) = vertices(g); firstv != lastv; firstv++){
|
||||
boost::put(distance_row, *firstv, 0);
|
||||
bellman =
|
||||
boost::bellman_ford_shortest_paths
|
||||
(g, vec,
|
||||
weight_map(boost::get(boost::edge_weight, g)).
|
||||
distance_map(boost::get(boost::vertex_distance, g)).
|
||||
predecessor_map(dummy_map).distance_compare(compare).
|
||||
distance_combine(combine));
|
||||
distance_row = boost::get(boost::vertex_distance, g);
|
||||
for(boost::tie(firstv2, lastv2) = vertices(g); firstv2 != lastv2;
|
||||
firstv2++){
|
||||
matrix2[*firstv][*firstv2] = boost::get(distance_row, *firstv2);
|
||||
boost::put(distance_row, *firstv2, std::numeric_limits<int>::max());
|
||||
}
|
||||
if(bellman == false){
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (bellman != floyd1 || bellman != floyd2 || bellman != floyd3){
|
||||
std::cout <<
|
||||
"A negative cycle was detected in one algorithm but not the others. "
|
||||
<< std::endl;
|
||||
return false;
|
||||
}
|
||||
else if (bellman == false && floyd1 == false && floyd2 == false &&
|
||||
floyd3 == false){
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
typename boost::graph_traits<Graph>::vertex_iterator first1, first2,
|
||||
last1, last2;
|
||||
for (boost::tie(first1, last1) = boost::vertices(g); first1 != last1;
|
||||
first1++){
|
||||
for (boost::tie(first2, last2) = boost::vertices(g); first2 != last2;
|
||||
first2++){
|
||||
if (matrix2[*first1][*first2] != matrix[*first1][*first2]){
|
||||
std::cout << "Algorithms do not match at matrix point "
|
||||
<< index[*first1] << " " << index[*first2]
|
||||
<< " Bellman results: " << matrix2[*first1][*first2]
|
||||
<< " floyd 1 results " << matrix[*first1][*first2]
|
||||
<< std::endl;
|
||||
return false;
|
||||
}
|
||||
if (matrix2[*first1][*first2] != matrix3[*first1][*first2]){
|
||||
std::cout << "Algorithms do not match at matrix point "
|
||||
<< index[*first1] << " " << index[*first2]
|
||||
<< " Bellman results: " << matrix2[*first1][*first2]
|
||||
<< " floyd 2 results " << matrix3[*first1][*first2]
|
||||
<< std::endl;
|
||||
return false;
|
||||
}
|
||||
if (matrix2[*first1][*first2] != matrix4[*first1][*first2]){
|
||||
std::cout << "Algorithms do not match at matrix point "
|
||||
<< index[*first1] << " " << index[*first2]
|
||||
<< " Bellman results: " << matrix2[*first1][*first2]
|
||||
<< " floyd 3 results " << matrix4[*first1][*first2]
|
||||
<< std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename Graph>
|
||||
bool acceptance_test2(Graph& g, int vec, int e)
|
||||
{
|
||||
boost::minstd_rand ran(vec);
|
||||
|
||||
{
|
||||
|
||||
typename boost::property_map<Graph, boost::vertex_name_t>::type index =
|
||||
boost::get(boost::vertex_name, g);
|
||||
typename boost::graph_traits<Graph>::vertex_iterator firstv, lastv,
|
||||
firstv2, lastv2;
|
||||
int x = 0;
|
||||
for(boost::tie(firstv, lastv) = boost::vertices(g); firstv != lastv;
|
||||
firstv++){
|
||||
boost::put(index, *firstv, x);
|
||||
x++;
|
||||
}
|
||||
|
||||
boost::generate_random_graph(g, vec, e, ran, true);
|
||||
|
||||
typename boost::graph_traits<Graph>::edge_iterator first, last;
|
||||
typename boost::property_map<Graph, boost::edge_weight_t>::type
|
||||
local_edge_map = boost::get(boost::edge_weight, g);
|
||||
for(boost::tie(first, last) = boost::edges(g); first != last; first++){
|
||||
if (ran() % vec != 0){
|
||||
boost::put(local_edge_map, *first, ran() % 100);
|
||||
} else {
|
||||
boost::put(local_edge_map, *first, 0 - (ran() % 100));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
typedef typename boost::graph_traits<Graph>::vertex_descriptor vertex_des;
|
||||
std::map<vertex_des,int> matrixRow;
|
||||
std::map<vertex_des, std::map<vertex_des ,int> > matrix;
|
||||
typedef typename boost::property_map<Graph, boost::vertex_distance_t>::type
|
||||
distance_type;
|
||||
distance_type distance_row = boost::get(boost::vertex_distance, g);
|
||||
for(boost::tie(firstv, lastv) = boost::vertices(g); firstv != lastv;
|
||||
firstv++){
|
||||
boost::put(distance_row, *firstv, std::numeric_limits<int>::max());
|
||||
matrixRow[*firstv] = std::numeric_limits<int>::max();
|
||||
}
|
||||
for(boost::tie(firstv, lastv) = boost::vertices(g); firstv != lastv;
|
||||
firstv++){
|
||||
matrix[*firstv] = matrixRow;
|
||||
}
|
||||
for(boost::tie(firstv, lastv) = boost::vertices(g); firstv != lastv;
|
||||
firstv++){
|
||||
matrix[*firstv][*firstv] = 0;
|
||||
}
|
||||
std::map<vertex_des, std::map<vertex_des, int> > matrix3(matrix);
|
||||
std::map<vertex_des, std::map<vertex_des, int> > matrix4(matrix);
|
||||
for(boost::tie(first, last) = boost::edges(g); first != last; first++){
|
||||
if (matrix[boost::source(*first, g)][boost::target(*first, g)]
|
||||
!= std::numeric_limits<int>::max()){
|
||||
matrix[boost::source(*first, g)][boost::target(*first, g)] =
|
||||
std::min(boost::get(local_edge_map, *first),
|
||||
matrix[boost::source(*first, g)][boost::target(*first, g)]);
|
||||
} else {
|
||||
matrix[boost::source(*first, g)][boost::target(*first, g)] =
|
||||
boost::get(local_edge_map, *first);
|
||||
}
|
||||
}
|
||||
bool is_undirected =
|
||||
boost::is_same<typename boost::graph_traits<Graph>::directed_category,
|
||||
boost::undirected_tag>::value;
|
||||
if (is_undirected){
|
||||
for(boost::tie(first, last) = boost::edges(g); first != last; first++){
|
||||
if (matrix[boost::target(*first, g)][boost::source(*first, g)]
|
||||
!= std::numeric_limits<int>::max()){
|
||||
matrix[boost::target(*first, g)][boost::source(*first, g)] =
|
||||
std::min(boost::get(local_edge_map, *first),
|
||||
matrix[boost::target(*first, g)][boost::source(*first, g)]);
|
||||
} else {
|
||||
matrix[boost::target(*first, g)][boost::source(*first, g)] =
|
||||
boost::get(local_edge_map, *first);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool bellman, floyd1, floyd2, floyd3;
|
||||
std::less<int> compare;
|
||||
inf_plus<int> combine;
|
||||
floyd1 =
|
||||
boost::floyd_warshall_initialized_all_pairs_shortest_paths
|
||||
(g,
|
||||
matrix, weight_map(boost::get(boost::edge_weight, g)).
|
||||
distance_compare(compare). distance_combine(combine).
|
||||
distance_inf(std::numeric_limits<int>::max()). distance_zero(0));
|
||||
|
||||
floyd2 =
|
||||
boost::floyd_warshall_all_pairs_shortest_paths
|
||||
(g, matrix3,
|
||||
weight_map(local_edge_map). distance_compare(compare).
|
||||
distance_combine(combine).
|
||||
distance_inf(std::numeric_limits<int>::max()). distance_zero(0));
|
||||
|
||||
floyd3 = boost::floyd_warshall_all_pairs_shortest_paths(g, matrix4);
|
||||
|
||||
|
||||
boost::dummy_property_map dummy_map;
|
||||
std::map<vertex_des, std::map<vertex_des, int> > matrix2;
|
||||
for(boost::tie(firstv, lastv) = vertices(g); firstv != lastv; firstv++){
|
||||
boost::put(distance_row, *firstv, 0);
|
||||
bellman =
|
||||
boost::bellman_ford_shortest_paths
|
||||
(g, vec,
|
||||
weight_map(boost::get(boost::edge_weight, g)).
|
||||
distance_map(boost::get(boost::vertex_distance, g)).
|
||||
predecessor_map(dummy_map).distance_compare(compare).
|
||||
distance_combine(combine));
|
||||
distance_row = boost::get(boost::vertex_distance, g);
|
||||
for(boost::tie(firstv2, lastv2) = vertices(g); firstv2 != lastv2;
|
||||
firstv2++){
|
||||
matrix2[*firstv][*firstv2] = boost::get(distance_row, *firstv2);
|
||||
boost::put(distance_row, *firstv2, std::numeric_limits<int>::max());
|
||||
}
|
||||
if(bellman == false){
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (bellman != floyd1 || bellman != floyd2 || bellman != floyd3){
|
||||
std::cout <<
|
||||
"A negative cycle was detected in one algorithm but not the others. "
|
||||
<< std::endl;
|
||||
return false;
|
||||
}
|
||||
else if (bellman == false && floyd1 == false && floyd2 == false &&
|
||||
floyd3 == false){
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
typename boost::graph_traits<Graph>::vertex_iterator first1, first2,
|
||||
last1, last2;
|
||||
for (boost::tie(first1, last1) = boost::vertices(g); first1 != last1;
|
||||
first1++){
|
||||
for (boost::tie(first2, last2) = boost::vertices(g); first2 != last2;
|
||||
first2++){
|
||||
if (matrix2[*first1][*first2] != matrix[*first1][*first2]){
|
||||
std::cout << "Algorithms do not match at matrix point "
|
||||
<< index[*first1] << " " << index[*first2]
|
||||
<< " Bellman results: " << matrix2[*first1][*first2]
|
||||
<< " floyd 1 results " << matrix[*first1][*first2]
|
||||
<< std::endl;
|
||||
return false;
|
||||
}
|
||||
if (matrix2[*first1][*first2] != matrix3[*first1][*first2]){
|
||||
std::cout << "Algorithms do not match at matrix point "
|
||||
<< index[*first1] << " " << index[*first2]
|
||||
<< " Bellman results: " << matrix2[*first1][*first2]
|
||||
<< " floyd 2 results " << matrix3[*first1][*first2]
|
||||
<< std::endl;
|
||||
return false;
|
||||
}
|
||||
if (matrix2[*first1][*first2] != matrix4[*first1][*first2]){
|
||||
std::cout << "Algorithms do not match at matrix point "
|
||||
<< index[*first1] << " " << index[*first2]
|
||||
<< " Bellman results: " << matrix2[*first1][*first2]
|
||||
<< " floyd 3 results " << matrix4[*first1][*first2]
|
||||
<< std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
int test_main(int, char*[])
|
||||
{
|
||||
typedef boost::adjacency_list<boost::listS, boost::listS, boost::directedS,
|
||||
boost::property<boost::vertex_distance_t, int,
|
||||
boost::property<boost::vertex_name_t, int> > ,
|
||||
boost::property<boost::edge_weight_t, int> > Digraph;
|
||||
Digraph adjlist_digraph;
|
||||
BOOST_TEST(acceptance_test2(adjlist_digraph, 100, 2000));
|
||||
|
||||
typedef boost::adjacency_matrix<boost::undirectedS,
|
||||
boost::property<boost::vertex_distance_t, int,
|
||||
boost::property<boost::vertex_name_t, int> > ,
|
||||
boost::property<boost::edge_weight_t, int> > Graph;
|
||||
Graph matrix_graph(100);
|
||||
BOOST_TEST(acceptance_test(matrix_graph, 100, 2000));
|
||||
|
||||
return 0;
|
||||
}
|
@ -6,9 +6,12 @@
|
||||
|
||||
// Authors: Douglas Gregor
|
||||
// Andrew Lumsdaine
|
||||
#include <boost/graph/fruchterman_reingold.hpp>
|
||||
#include <boost/graph/random_layout.hpp>
|
||||
#include <boost/graph/kamada_kawai_spring_layout.hpp>
|
||||
#include <boost/graph/circle_layout.hpp>
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/random/linear_congruential.hpp>
|
||||
#include <boost/test/minimal.hpp>
|
||||
#include <iostream>
|
||||
#include <boost/limits.hpp>
|
||||
@ -149,7 +152,7 @@ test_triangle(Graph*)
|
||||
side_length(50.0));
|
||||
BOOST_TEST(ok);
|
||||
|
||||
std::cout << "Triangle layout.\n";
|
||||
std::cout << "Triangle layout (Kamada-Kawai).\n";
|
||||
print_graph_layout(g, get(vertex_position, g));
|
||||
}
|
||||
|
||||
@ -191,10 +194,32 @@ test_cube(Graph*)
|
||||
kamada_kawai_done());
|
||||
BOOST_TEST(ok);
|
||||
|
||||
std::cout << "Cube layout.\n";
|
||||
std::cout << "Cube layout (Kamada-Kawai).\n";
|
||||
print_graph_layout(g, get(vertex_position, g));
|
||||
|
||||
dump_graph_layout("cube", g, get(vertex_position, g));
|
||||
|
||||
minstd_rand gen;
|
||||
random_graph_layout(g, get(vertex_position, g), -25.0, 25.0, -25.0, 25.0,
|
||||
gen);
|
||||
|
||||
std::vector<point> displacements(num_vertices(g));
|
||||
fruchterman_reingold_force_directed_layout
|
||||
(g,
|
||||
get(vertex_position, g),
|
||||
50.0,
|
||||
50.0,
|
||||
square_distance_attractive_force(),
|
||||
square_distance_repulsive_force(),
|
||||
all_force_pairs(),
|
||||
linear_cooling<double>(100),
|
||||
make_iterator_property_map(displacements.begin(),
|
||||
get(vertex_index, g)));
|
||||
|
||||
std::cout << "Cube layout (Fruchterman-Reingold).\n";
|
||||
print_graph_layout(g, get(vertex_position, g));
|
||||
|
||||
dump_graph_layout("cube-fr", g, get(vertex_position, g));
|
||||
}
|
||||
|
||||
template<typename Graph>
|
||||
@ -235,10 +260,88 @@ test_triangular(Graph*)
|
||||
kamada_kawai_done());
|
||||
BOOST_TEST(ok);
|
||||
|
||||
std::cout << "Triangular layout.\n";
|
||||
std::cout << "Triangular layout (Kamada-Kawai).\n";
|
||||
print_graph_layout(g, get(vertex_position, g));
|
||||
|
||||
dump_graph_layout("triangular", g, get(vertex_position, g));
|
||||
dump_graph_layout("triangular-kk", g, get(vertex_position, g));
|
||||
|
||||
minstd_rand gen;
|
||||
random_graph_layout(g, get(vertex_position, g), -25.0, 25.0, -25.0, 25.0,
|
||||
gen);
|
||||
|
||||
dump_graph_layout("random", g, get(vertex_position, g));
|
||||
|
||||
std::vector<point> displacements(num_vertices(g));
|
||||
fruchterman_reingold_force_directed_layout
|
||||
(g,
|
||||
get(vertex_position, g),
|
||||
50.0,
|
||||
50.0,
|
||||
attractive_force(square_distance_attractive_force()).
|
||||
cooling(linear_cooling<double>(100)));
|
||||
|
||||
std::cout << "Triangular layout (Fruchterman-Reingold).\n";
|
||||
print_graph_layout(g, get(vertex_position, g));
|
||||
|
||||
dump_graph_layout("triangular-fr", g, get(vertex_position, g));
|
||||
}
|
||||
|
||||
template<typename Graph>
|
||||
void
|
||||
test_disconnected(Graph*)
|
||||
{
|
||||
enum {A, B, C, D, E, F, G, H};
|
||||
simple_edge triangular_edges[13] = {
|
||||
{A, B}, {B, C}, {C, A},
|
||||
{D, E}, {E, F}, {F, G}, {G, H}, {H, D},
|
||||
{D, F}, {F, H}, {H, E}, {E, G}, {G, D}
|
||||
};
|
||||
|
||||
Graph g(&triangular_edges[0], &triangular_edges[13], 8);
|
||||
|
||||
typedef typename graph_traits<Graph>::edge_iterator edge_iterator;
|
||||
typedef typename graph_traits<Graph>::vertex_iterator vertex_iterator;
|
||||
|
||||
vertex_iterator vi, vi_end;
|
||||
int i = 0;
|
||||
for (tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
|
||||
put(vertex_index, g, *vi, i++);
|
||||
|
||||
edge_iterator ei, ei_end;
|
||||
for (tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) {
|
||||
put(edge_weight, g, *ei, 1.0);
|
||||
std::cerr << "(" << (char)(get(vertex_index, g, source(*ei, g)) + 'A')
|
||||
<< ", " << (char)(get(vertex_index, g, target(*ei, g)) + 'A')
|
||||
<< ") ";
|
||||
}
|
||||
std::cerr << std::endl;
|
||||
|
||||
circle_graph_layout(g, get(vertex_position, g), 25.0);
|
||||
|
||||
bool ok = kamada_kawai_spring_layout(g,
|
||||
get(vertex_position, g),
|
||||
get(edge_weight, g),
|
||||
side_length(50.0),
|
||||
kamada_kawai_done());
|
||||
BOOST_TEST(!ok);
|
||||
|
||||
minstd_rand gen;
|
||||
random_graph_layout(g, get(vertex_position, g), -25.0, 25.0, -25.0, 25.0,
|
||||
gen);
|
||||
|
||||
std::vector<point> displacements(num_vertices(g));
|
||||
fruchterman_reingold_force_directed_layout
|
||||
(g,
|
||||
get(vertex_position, g),
|
||||
50.0,
|
||||
50.0,
|
||||
attractive_force(square_distance_attractive_force()).
|
||||
cooling(linear_cooling<double>(50)));
|
||||
|
||||
std::cout << "Disconnected layout (Fruchterman-Reingold).\n";
|
||||
print_graph_layout(g, get(vertex_position, g));
|
||||
|
||||
dump_graph_layout("disconnected-fr", g, get(vertex_position, g));
|
||||
}
|
||||
|
||||
int test_main(int, char*[])
|
||||
@ -253,6 +356,6 @@ int test_main(int, char*[])
|
||||
test_circle_layout((Graph*)0, 5);
|
||||
test_cube((Graph*)0);
|
||||
test_triangular((Graph*)0);
|
||||
|
||||
test_disconnected((Graph*)0);
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user