3
3
* This class provides the same API as the BreadthFirstShortestPaths<T>.
4
4
*/
5
5
6
- using System ;
7
- using System . Diagnostics ;
8
- using System . Collections . Generic ;
9
-
10
6
using Algorithms . Common ;
11
7
using DataStructures . Graphs ;
12
8
using DataStructures . Heaps ;
9
+ using System ;
10
+ using System . Collections . Generic ;
13
11
14
12
namespace Algorithms . Graphs
15
13
{
@@ -33,7 +31,7 @@ public class DijkstraShortestPaths<TGraph, TVertex>
33
31
private Dictionary < int , TVertex > _indicesToNodes ;
34
32
35
33
// A const that represent an infinite distance
36
- private const Int64 Infinity = Int64 . MaxValue ;
34
+ private const long Infinity = long . MaxValue ;
37
35
private const int NilPredecessor = - 1 ;
38
36
39
37
@@ -44,9 +42,14 @@ public class DijkstraShortestPaths<TGraph, TVertex>
44
42
public DijkstraShortestPaths ( TGraph Graph , TVertex Source )
45
43
{
46
44
if ( Graph == null )
45
+ {
47
46
throw new ArgumentNullException ( ) ;
48
- else if ( ! Graph . HasVertex ( Source ) )
47
+ }
48
+
49
+ if ( ! Graph . HasVertex ( Source ) )
50
+ {
49
51
throw new ArgumentException ( "The source vertex doesn't belong to graph." ) ;
52
+ }
50
53
51
54
// Init
52
55
_initializeDataMembers ( Graph ) ;
@@ -55,9 +58,10 @@ public DijkstraShortestPaths(TGraph Graph, TVertex Source)
55
58
_dijkstra ( Graph , Source ) ;
56
59
57
60
// check for the acyclic invariant
58
- //if (!_checkOptimalityConditions(Graph, Source))
59
- // throw new Exception("Graph doesn't match optimality conditions.");
60
- Debug . Assert ( _checkOptimalityConditions ( Graph , Source ) ) ;
61
+ if ( ! _checkOptimalityConditions ( Graph , Source ) )
62
+ {
63
+ throw new InvalidOperationException ( "Graph doesn't match optimality condition." ) ;
64
+ }
61
65
}
62
66
63
67
@@ -71,7 +75,7 @@ private void _dijkstra(TGraph graph, TVertex source)
71
75
{
72
76
var minPQ = new MinPriorityQueue < TVertex , long > ( ( uint ) _verticesCount ) ;
73
77
74
- int srcIndex = _nodesToIndices [ source ] ;
78
+ var srcIndex = _nodesToIndices [ source ] ;
75
79
_distances [ srcIndex ] = 0 ;
76
80
77
81
minPQ . Enqueue ( source , _distances [ srcIndex ] ) ;
@@ -89,8 +93,10 @@ private void _dijkstra(TGraph graph, TVertex source)
89
93
90
94
// calculate a new possible weighted path if the edge weight is less than infinity
91
95
var delta = Infinity ;
92
- if ( edge . Weight < Infinity && ( Infinity - edge . Weight ) > _distances [ currentIndex ] ) // Handles overflow
96
+ if ( edge . Weight < Infinity && Infinity - edge . Weight > _distances [ currentIndex ] ) // Handles overflow
97
+ {
93
98
delta = _distances [ currentIndex ] + edge . Weight ;
99
+ }
94
100
95
101
// Relax the edge
96
102
// if check is true, a shorter path is found from current to adjacent
@@ -102,9 +108,13 @@ private void _dijkstra(TGraph graph, TVertex source)
102
108
103
109
// decrease priority with a new distance if it exists; otherwise enqueque it
104
110
if ( minPQ . Contains ( edge . Destination ) )
111
+ {
105
112
minPQ . UpdatePriority ( edge . Destination , delta ) ;
113
+ }
106
114
else
115
+ {
107
116
minPQ . Enqueue ( edge . Destination , delta ) ;
117
+ }
108
118
}
109
119
} //end-foreach
110
120
} //end-while
@@ -118,19 +128,21 @@ private void _initializeDataMembers(TGraph Graph)
118
128
_edgesCount = Graph . EdgesCount ;
119
129
_verticesCount = Graph . VerticesCount ;
120
130
121
- _distances = new Int64 [ _verticesCount ] ;
131
+ _distances = new long [ _verticesCount ] ;
122
132
_predecessors = new int [ _verticesCount ] ;
123
133
_edgeTo = new WeightedEdge < TVertex > [ _edgesCount ] ;
124
134
125
135
_nodesToIndices = new Dictionary < TVertex , int > ( ) ;
126
136
_indicesToNodes = new Dictionary < int , TVertex > ( ) ;
127
137
128
138
// Reset the information arrays
129
- int i = 0 ;
139
+ var i = 0 ;
130
140
foreach ( var node in Graph . Vertices )
131
141
{
132
142
if ( i >= _verticesCount )
143
+ {
133
144
break ;
145
+ }
134
146
135
147
_edgeTo [ i ] = null ;
136
148
_distances [ i ] = Infinity ;
@@ -151,7 +163,7 @@ private void _initializeDataMembers(TGraph Graph)
151
163
private bool _checkOptimalityConditions ( TGraph graph , TVertex source )
152
164
{
153
165
// Get the source index (to be used with the information arrays).
154
- int s = _nodesToIndices [ source ] ;
166
+ var s = _nodesToIndices [ source ] ;
155
167
156
168
// check that edge weights are nonnegative
157
169
foreach ( var edge in graph . Edges )
@@ -170,10 +182,13 @@ private bool _checkOptimalityConditions(TGraph graph, TVertex source)
170
182
return false ;
171
183
}
172
184
173
- for ( int v = 0 ; v < graph . VerticesCount ; v ++ )
185
+ for ( var v = 0 ; v < graph . VerticesCount ; v ++ )
174
186
{
175
187
if ( v == s )
188
+ {
176
189
continue ;
190
+ }
191
+
177
192
if ( _predecessors [ v ] == NilPredecessor && _distances [ v ] != Infinity )
178
193
{
179
194
Console . WriteLine ( "distanceTo[] and edgeTo[] are inconsistent for at least one vertex." ) ;
@@ -184,11 +199,11 @@ private bool _checkOptimalityConditions(TGraph graph, TVertex source)
184
199
// check that all edges e = v->w satisfy distTo[w] <= distTo[v] + e.weight()
185
200
foreach ( var vertex in graph . Vertices )
186
201
{
187
- int v = _nodesToIndices [ vertex ] ;
202
+ var v = _nodesToIndices [ vertex ] ;
188
203
189
204
foreach ( var edge in graph . NeighboursMap ( vertex ) )
190
205
{
191
- int w = _nodesToIndices [ edge . Key ] ;
206
+ var w = _nodesToIndices [ edge . Key ] ;
192
207
193
208
if ( _distances [ v ] + edge . Value < _distances [ w ] )
194
209
{
@@ -201,18 +216,22 @@ private bool _checkOptimalityConditions(TGraph graph, TVertex source)
201
216
// check that all edges e = v->w on SPT satisfy distTo[w] == distTo[v] + e.weight()
202
217
foreach ( var vertex in graph . Vertices )
203
218
{
204
- int w = _nodesToIndices [ vertex ] ;
219
+ var w = _nodesToIndices [ vertex ] ;
205
220
206
221
if ( _edgeTo [ w ] == null )
222
+ {
207
223
continue ;
224
+ }
208
225
209
226
var edge = _edgeTo [ w ] ;
210
- int v = _nodesToIndices [ edge . Source ] ;
227
+ var v = _nodesToIndices [ edge . Source ] ;
211
228
212
229
if ( ! vertex . IsEqualTo ( edge . Destination ) )
230
+ {
213
231
return false ;
232
+ }
214
233
215
- if ( ( _distances [ v ] + edge . Weight ) != _distances [ w ] )
234
+ if ( _distances [ v ] + edge . Weight != _distances [ w ] )
216
235
{
217
236
Console . WriteLine ( "edge " + edge . Source + "-" + edge . Destination + " on shortest path not tight" ) ;
218
237
return false ;
@@ -232,9 +251,11 @@ private bool _checkOptimalityConditions(TGraph graph, TVertex source)
232
251
public bool HasPathTo ( TVertex destination )
233
252
{
234
253
if ( ! _nodesToIndices . ContainsKey ( destination ) )
254
+ {
235
255
throw new Exception ( "Graph doesn't have the specified vertex." ) ;
256
+ }
236
257
237
- int index = _nodesToIndices [ destination ] ;
258
+ var index = _nodesToIndices [ destination ] ;
238
259
return _distances [ index ] != Infinity ;
239
260
}
240
261
@@ -244,9 +265,11 @@ public bool HasPathTo(TVertex destination)
244
265
public long DistanceTo ( TVertex destination )
245
266
{
246
267
if ( ! _nodesToIndices . ContainsKey ( destination ) )
268
+ {
247
269
throw new Exception ( "Graph doesn't have the specified vertex." ) ;
270
+ }
248
271
249
- int index = _nodesToIndices [ destination ] ;
272
+ var index = _nodesToIndices [ destination ] ;
250
273
return _distances [ index ] ;
251
274
}
252
275
@@ -256,16 +279,22 @@ public long DistanceTo(TVertex destination)
256
279
public IEnumerable < TVertex > ShortestPathTo ( TVertex destination )
257
280
{
258
281
if ( ! _nodesToIndices . ContainsKey ( destination ) )
282
+ {
259
283
throw new Exception ( "Graph doesn't have the specified vertex." ) ;
284
+ }
260
285
else if ( ! HasPathTo ( destination ) )
286
+ {
261
287
return null ;
288
+ }
262
289
263
- int dstIndex = _nodesToIndices [ destination ] ;
290
+ var dstIndex = _nodesToIndices [ destination ] ;
264
291
var stack = new DataStructures . Lists . Stack < TVertex > ( ) ;
265
292
266
293
int index ;
267
294
for ( index = dstIndex ; _distances [ index ] != 0 ; index = _predecessors [ index ] )
295
+ {
268
296
stack . Push ( _indicesToNodes [ index ] ) ;
297
+ }
269
298
270
299
// Push the source vertex
271
300
stack . Push ( _indicesToNodes [ index ] ) ;
0 commit comments