|
39 | 39 | from pygraph.classes.exceptions import NodeUnreachable |
40 | 40 | from pygraph.classes.exceptions import NegativeWeightCycleError |
41 | 41 | from pygraph.classes.digraph import digraph |
42 | | -import bisect |
| 42 | +import heapq |
43 | 43 |
|
44 | 44 | # Minimal spanning tree |
45 | 45 |
|
@@ -157,33 +157,28 @@ def shortest_path(graph, source): |
157 | 157 | dist = {source: 0} |
158 | 158 | previous = {source: None} |
159 | 159 |
|
160 | | - # This is a sorted queue of (dist, node) 2-tuples. The first item in the |
| 160 | + # This is a priority queue of (dist, node) 2-tuples. The first item in the |
161 | 161 | # queue is always either a finalized node that we can ignore or the node |
162 | 162 | # with the smallest estimated distance from the source. Note that we will |
163 | 163 | # not remove nodes from this list as they are finalized; we just ignore them |
164 | 164 | # when they come up. |
165 | 165 | q = [(0, source)] |
166 | 166 |
|
167 | | - # The set of nodes for which we have final distances. |
168 | | - finished = set() |
169 | | - |
170 | | - # Algorithm loop |
171 | 167 | while len(q) > 0: |
172 | | - du, u = q.pop(0) |
173 | | - |
174 | | - # Process reachable, remaining nodes from u |
175 | | - if u not in finished: |
176 | | - finished.add(u) |
177 | | - for v in graph[u]: |
178 | | - if v not in finished: |
179 | | - alt = du + graph.edge_weight((u, v)) |
180 | | - if (v not in dist) or (alt < dist[v]): |
181 | | - dist[v] = alt |
182 | | - previous[v] = u |
183 | | - bisect.insort(q, (alt, v)) |
| 168 | + du, u = heapq.heappop(q) |
184 | 169 |
|
185 | | - return previous, dist |
| 170 | + # Skip finished node |
| 171 | + if dist[u] < du: |
| 172 | + continue |
| 173 | + |
| 174 | + for v in graph[u]: |
| 175 | + alt = du + graph.edge_weight((u, v)) |
| 176 | + if (v not in dist) or (alt < dist[v]): |
| 177 | + dist[v] = alt |
| 178 | + previous[v] = u |
| 179 | + heapq.heappush(q, (alt, v)) |
186 | 180 |
|
| 181 | + return previous, dist |
187 | 182 |
|
188 | 183 |
|
189 | 184 | def shortest_path_bellman_ford(graph, source): |
|
0 commit comments