1 // ==========================================================================
2 // SeqAn - The Library for Sequence Analysis
3 // ==========================================================================
4 // Copyright (c) 2006-2015, Knut Reinert, FU Berlin
5 // All rights reserved.
6 //
7 // Redistribution and use in source and binary forms, with or without
8 // modification, are permitted provided that the following conditions are met:
9 //
10 // * Redistributions of source code must retain the above copyright
11 // notice, this list of conditions and the following disclaimer.
12 // * Redistributions in binary form must reproduce the above copyright
13 // notice, this list of conditions and the following disclaimer in the
14 // documentation and/or other materials provided with the distribution.
15 // * Neither the name of Knut Reinert or the FU Berlin nor the names of
16 // its contributors may be used to endorse or promote products derived
17 // from this software without specific prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 // ARE DISCLAIMED. IN NO EVENT SHALL KNUT REINERT OR THE FU BERLIN BE LIABLE
23 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 // OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
29 // DAMAGE.
30 //
31 // ==========================================================================
32 // Author: Tobias Raussch <rausch@embl.de>
33 // ==========================================================================
34 // Implementation of Single-Source-Shortest-Path algorithm.
35 // ==========================================================================
36
37 #ifndef INCLUDE_SEQAN_GRAPH_ALGORITHMS_SINGLE_SOURCE_SHORTEST_PATH_H_
38 #define INCLUDE_SEQAN_GRAPH_ALGORITHMS_SINGLE_SOURCE_SHORTEST_PATH_H_
39
40 namespace seqan {
41
42 // ============================================================================
43 // Forwards
44 // ============================================================================
45
46 // ============================================================================
47 // Tags, Classes, Enums
48 // ============================================================================
49
50 // ============================================================================
51 // Metafunctions
52 // ============================================================================
53
54 // ============================================================================
55 // Functions
56 // ============================================================================
57
58 // ----------------------------------------------------------------------------
59 // Function singleSourceShortestPath()
60 // ----------------------------------------------------------------------------
61
62 template <typename TSpec, typename TPredecessorMap, typename TVertexDescriptor, typename TNameMap>
63 inline void
_printPath(Graph<TSpec> const & g,TPredecessorMap const & predecessor,TVertexDescriptor const source,TVertexDescriptor const v,TNameMap const & nameMap)64 _printPath(Graph<TSpec> const& g,
65 TPredecessorMap const& predecessor,
66 TVertexDescriptor const source,
67 TVertexDescriptor const v,
68 TNameMap const& nameMap)
69 {
70 if (source == v) {
71 std::cout << getProperty(nameMap, source);
72 } else if (getProperty(predecessor, v) == getNil<typename VertexDescriptor<Graph<TSpec> >::Type>()) {
73 std::cout << "No path from " << getProperty(nameMap, source) << " to " << getProperty(nameMap, v) << " exists.";
74 } else {
75 _printPath(g,predecessor, source, getProperty(predecessor, v), nameMap);
76 std::cout << "," << getProperty(nameMap, v);
77 }
78 }
79
80 template <typename TSpec, typename TPredecessorMap, typename TVertexDescriptor1, typename TVertexDescriptor2>
81 inline void
_printPath(Graph<TSpec> const & g,TPredecessorMap const & predecessor,TVertexDescriptor1 const source,TVertexDescriptor2 const v)82 _printPath(Graph<TSpec> const& g,
83 TPredecessorMap const& predecessor,
84 TVertexDescriptor1 const source,
85 TVertexDescriptor2 const v)
86 {
87 if (source == v) {
88 std::cout << source;
89 } else if (getProperty(predecessor, v) == getNil<typename VertexDescriptor<Graph<TSpec> >::Type>()) {
90 std::cout << "No path from " << source << " to " << v << " exists.";
91 } else {
92 _printPath(g,predecessor, source, getProperty(predecessor, v));
93 std::cout << "," << v;
94 }
95 }
96
97 template <typename TSpec, typename TPredecessorMap, typename TVertexDescriptor1, typename TVertexDescriptor2, typename TEdgeSet>
98 inline bool
_collectEdges(Graph<TSpec> const & g,TPredecessorMap const & predecessor,TVertexDescriptor1 const source,TVertexDescriptor2 const v,TEdgeSet & edgeSet)99 _collectEdges(Graph<TSpec> const& g,
100 TPredecessorMap const& predecessor,
101 TVertexDescriptor1 const source,
102 TVertexDescriptor2 const v,
103 TEdgeSet& edgeSet)
104 {
105 if ((TVertexDescriptor1) source == (TVertexDescriptor1) v) {
106 return true;
107 } else if (getProperty(predecessor, v) == getNil<typename VertexDescriptor<Graph<TSpec> >::Type>()) {
108 return false;
109 } else {
110 edgeSet.insert(findEdge(g, getProperty(predecessor, v), v));
111 return _collectEdges(g,predecessor, source, getProperty(predecessor, v), edgeSet);
112 }
113 }
114
115 //////////////////////////////////////////////////////////////////////////////
116
117 template <typename TSpec, typename TPredecessorMap, typename TVertexDescriptor, typename TEdgeSet>
118 inline bool
_collectEdges(Graph<TSpec> const & g,TPredecessorMap const & predecessor,TVertexDescriptor const source,TEdgeSet & edgeSet)119 _collectEdges(Graph<TSpec> const& g,
120 TPredecessorMap const& predecessor,
121 TVertexDescriptor const source,
122 TEdgeSet& edgeSet)
123 {
124 typedef Iterator<Graph<Undirected<> >, VertexIterator>::Type TVertexIterator;
125 TVertexIterator it(g);
126 for(;!atEnd(it); goNext(it)) {
127 if (!_collectEdges(g, predecessor, source, value(it), edgeSet)) {
128 edgeSet.clear();
129 return false;
130 }
131 }
132 return true;
133 }
134
135 template <typename TSpec, typename TVertexDescriptor, typename TWeightMap, typename TPredecessorMap, typename TDistanceMap>
136 inline void
_initializeSingleSource(TPredecessorMap & predecessor,TDistanceMap & distance,Graph<TSpec> const & g,TVertexDescriptor const source,TWeightMap const & weight)137 _initializeSingleSource(TPredecessorMap & predecessor,
138 TDistanceMap & distance,
139 Graph<TSpec> const & g,
140 TVertexDescriptor const source,
141 TWeightMap const & weight)
142 {
143 typedef Graph<TSpec> TGraph;
144 typedef typename Iterator<TGraph, VertexIterator>::Type TVertexIterator;
145 typedef typename Value<TPredecessorMap>::Type TPredVal;
146 typedef typename Value<TWeightMap>::Type TDistVal;
147 TPredVal nilPred = getNil<typename VertexDescriptor<TGraph>::Type>();
148 TDistVal infDist = _getInfinityDistance(weight);
149
150 TVertexIterator it(g);
151 for(;!atEnd(it);goNext(it)) {
152 assignProperty(distance, getValue(it), infDist);
153 assignProperty(predecessor, getValue(it), nilPred);
154 }
155 assignProperty(distance, source, 0);
156 }
157
158 template <typename TSpec, typename TWeightMap, typename TPredecessorMap, typename TDistanceMap, typename TVertexDescriptor, typename TEdgeDescriptor>
159 inline void
_relax(Graph<TSpec> const & g,TWeightMap const & weight,TPredecessorMap & predecessor,TDistanceMap & distance,TVertexDescriptor const u,TEdgeDescriptor const e)160 _relax(Graph<TSpec> const& g,
161 TWeightMap const& weight,
162 TPredecessorMap& predecessor,
163 TDistanceMap& distance,
164 TVertexDescriptor const u,
165 TEdgeDescriptor const e)
166 {
167 TVertexDescriptor v = targetVertex(g,e);
168 if (getProperty(distance, v) > getProperty(distance,u) + getProperty(weight,e)) {
169 assignProperty(distance, v, getProperty(distance,u) + getProperty(weight,e));
170 assignProperty(predecessor, v, u);
171 }
172 }
173
174 // TODO(holtgrew): This looks broken (distance too high below).
175
176 /*!
177 * @fn dagShortestPath
178 * @headerfile <seqan/graph_algorithms.h>
179 * @brief Computes shortest paths from a single source in a directed acyclic graph (DAG).
180 *
181 * @signature void dagShortestPath(predecessor, distance, g, source, weight);
182 *
183 * @param[out] predecessor A property map. A property map that represents predecessor relationships among vertices.
184 * It determines a shortest-paths tree.
185 * @param[out] distance A property map. Indicates for each vertex th distance from the source.
186 * do exist.
187 * @param[in] g A directed acyclic graph. Types: Directed Graph
188 * @param[in] source A source vertex. Types: VertexDescriptor
189 * @param[in] weight A weight map. In a directed acyclic graph edge weights can be negative because no cycles
190 *
191 * @section Example
192 *
193 * @include demos/graph_algorithms/dag_shortest_path.cpp
194 *
195 * @include demos/graph_algorithms/dag_shortest_path.cpp.stdout
196 *
197 * @see bellmanFordAlgorithm
198 * @see dijkstra
199 */
200 template <typename TSpec, typename TVertexDescriptor, typename TWeightMap, typename TPredecessorMap, typename TDistanceMap>
dagShortestPath(TPredecessorMap & predecessor,TDistanceMap & distance,Graph<TSpec> const & g,TVertexDescriptor const source,TWeightMap const & weight)201 void dagShortestPath(TPredecessorMap & predecessor,
202 TDistanceMap & distance,
203 Graph<TSpec> const & g,
204 TVertexDescriptor const source,
205 TWeightMap const & weight)
206 {
207 typedef typename Iterator<Graph<TSpec>, OutEdgeIterator>::Type TOutEdgeIterator;
208 typedef typename Iterator<String<TVertexDescriptor>, Rooted>::Type TStringIterator;
209
210 // Initialization
211 resizeVertexMap(predecessor, g);
212 resizeVertexMap(distance, g);
213
214 // Topological sort
215 String<TVertexDescriptor> order;
216 topologicalSort(order, g);
217
218 _initializeSingleSource(predecessor, distance, g, source, weight);
219
220 //DAG Shortest Paths
221 TStringIterator it = begin(order);
222 while(!atEnd(it)) {
223 TOutEdgeIterator itout(g, getValue(it));
224 for(;!atEnd(itout);++itout) {
225 _relax(g,weight,predecessor, distance, getValue(it), getValue(itout));
226 }
227 goNext(it);
228 }
229 }
230
231 } // namespace seqan
232
233 #endif // #ifndef INCLUDE_SEQAN_GRAPH_ALGORITHMS_SINGLE_SOURCE_SHORTEST_PATH_H_
234