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