1010// License for the specific language governing permissions and limitations
1111// under the License.
1212
13- use crate :: petgraph:: algo:: { Measure } ;
13+ use crate :: petgraph:: algo:: Measure ;
1414use crate :: petgraph:: graph:: { Graph , Node , NodeIndex } ;
15- use crate :: petgraph:: visit:: { EdgeRef , IntoEdges , VisitMap , Visitable , IntoEdgeReferences } ;
15+ use crate :: petgraph:: visit:: { EdgeRef , IntoEdgeReferences , IntoEdges , VisitMap , Visitable } ;
1616use crate :: petgraph:: EdgeType ;
1717
1818use std:: collections:: hash_map:: Entry :: { Occupied , Vacant } ;
1919use std:: collections:: { BinaryHeap , HashMap , HashSet } ;
2020use std:: fmt:: Debug ;
2121use std:: hash:: Hash ;
2222
23+ use crate :: min_scored:: MinScored ;
2324use petgraph:: data:: DataMap ;
2425use petgraph:: graph:: { Edge , EdgeIndex , EdgeReference , GraphIndex } ;
2526use petgraph:: visit:: { GraphBase , GraphRef } ;
2627use rand:: Rng ;
27- use crate :: min_scored:: MinScored ;
28-
29-
3028
3129#[ derive( Debug ) ]
32- struct NodeData < N , K >
33- {
34- pub node_id : N , // node identifier
35- pub parent_id : Option < N > , // parent identifier
36- pub cost : K , // cost of minimum path from source
30+ struct NodeData < N , K > {
31+ pub node_id : N , // node identifier
32+ pub parent_id : Option < N > , // parent identifier
33+ pub cost : K , // cost of minimum path from source
3734}
3835
39-
40-
4136pub fn dijkstra_shortest_path_with_excluded_prefix < G , F , K > (
4237 graph : G ,
4338 start : G :: NodeId ,
4439 target : G :: NodeId ,
45- mut edge_cost : F ,
40+ mut edge_cost : F ,
4641 excluded_prefix : & HashSet < G :: NodeId > ,
4742) -> ( Vec < G :: NodeId > , K )
4843where
4944 G : Visitable + IntoEdges ,
5045 G :: NodeId : Eq + Hash ,
5146 F : FnMut ( G :: EdgeRef ) -> K ,
5247 K : Measure + Copy ,
53- G :: NodeId : Debug , <G as IntoEdgeReferences >:: EdgeRef : PartialEq
48+ G :: NodeId : Debug ,
49+ <G as IntoEdgeReferences >:: EdgeRef : PartialEq ,
5450{
5551 let mut visit_map = graph. visit_map ( ) ;
5652 let mut scores: HashMap < G :: NodeId , K > = HashMap :: new ( ) ;
57- let mut pathnodes: HashMap < G :: NodeId , NodeData < G :: NodeId , K > > = HashMap :: new ( ) ;
58- let mut visit_next: BinaryHeap < MinScored < K , G :: NodeId > > = BinaryHeap :: new ( ) ;
53+ let mut pathnodes: HashMap < G :: NodeId , NodeData < G :: NodeId , K > > = HashMap :: new ( ) ;
54+ let mut visit_next: BinaryHeap < MinScored < K , G :: NodeId > > = BinaryHeap :: new ( ) ;
5955 visit_next. push ( MinScored ( K :: default ( ) , start) ) ;
6056 scores. insert ( start, K :: default ( ) ) ;
61- pathnodes. insert ( start, NodeData {
62- node_id : start,
63- parent_id : None ,
64- cost : K :: default ( )
65- } ) ;
57+ pathnodes. insert (
58+ start,
59+ NodeData {
60+ node_id : start,
61+ parent_id : None ,
62+ cost : K :: default ( ) ,
63+ } ,
64+ ) ;
6665
6766 // In the loop below, all the nodes which have been assigned the shortest path from source
6867 // are marked as visited. The visisted nodes are not present in the heap, and hence we do not
7574 let v = edge. target ( ) ;
7675
7776 // don't traverse the nodes marked for exclusion, or which have been visited.
78- if visit_map. is_visited ( & v) || excluded_prefix. contains ( & v) {
77+ if visit_map. is_visited ( & v) || excluded_prefix. contains ( & v) {
7978 continue ;
8079 }
8180
9594 cost : node_score + edge_weight,
9695 } ;
9796 pathnodes. insert ( v_pnode. node_id , new_node) ;
98-
9997 } else {
100- assert_eq ! ( true , false , "Invariant not satisfied, Node {:?} not present in pathnodes" , v) ;
98+ assert_eq ! (
99+ true , false ,
100+ "Invariant not satisfied, Node {:?} not present in pathnodes" ,
101+ v
102+ ) ;
101103 }
102104 }
103105 }
@@ -107,11 +109,14 @@ where
107109 // Create the entry in the priority queue and an entry in the pathnodes map.
108110 scores. insert ( v, node_score + edge_weight) ;
109111 visit_next. push ( MinScored ( node_score + edge_weight, v) ) ;
110- pathnodes. insert ( v, NodeData {
111- node_id : v,
112- parent_id : Some ( node) ,
113- cost : node_score + edge_weight
114- } ) ;
112+ pathnodes. insert (
113+ v,
114+ NodeData {
115+ node_id : v,
116+ parent_id : Some ( node) ,
117+ cost : node_score + edge_weight,
118+ } ,
119+ ) ;
115120 }
116121 }
117122 }
@@ -136,8 +141,6 @@ where
136141 }
137142}
138143
139-
140-
141144/// Implementation of Yen's Algorithm to find k shortest paths.
142145pub fn get_smallest_k_paths_yen < N , K , T > (
143146 graph : & mut Graph < N , K , T > ,
@@ -149,14 +152,14 @@ where
149152 K : Measure + Copy ,
150153 T : EdgeType ,
151154{
152- let mut listA: Vec < Vec < NodeIndex > > = Vec :: new ( ) ; // list to contain shortest paths
155+ let mut listA: Vec < Vec < NodeIndex > > = Vec :: new ( ) ; // list to contain shortest paths
153156 let ( shortest_path, min_cost) = dijkstra_shortest_path_with_excluded_prefix (
154157 & * graph,
155158 start,
156159 target,
157- |e| { * e. weight ( ) } ,
158- & HashSet :: new ( ) ) ;
159-
160+ |e| * e. weight ( ) ,
161+ & HashSet :: new ( ) ,
162+ ) ;
160163
161164 println ! ( "Inserting path of cost {:?} in listA" , min_cost) ;
162165 listA. push ( shortest_path) ;
@@ -180,38 +183,40 @@ where
180183 // A diverging path at x[j] is formed as union of current path till node x[j], and the shortest path
181184 // from x[j] to target after removing prohibited edges (see above).
182185
183- let mut current_path = listA[ i- 1 ] . to_owned ( ) ; // current path is the last added path in listA
184- let mut excluded_edges_map: HashMap < ( NodeIndex , NodeIndex ) , K > = HashMap :: new ( ) ; // map to keep track of removed edges, which are added back later
185- let mut root_cost = K :: default ( ) ; // keep track of the cost of current path till diversion point.
186+ let mut current_path = listA[ i - 1 ] . to_owned ( ) ; // current path is the last added path in listA
187+ let mut excluded_edges_map: HashMap < ( NodeIndex , NodeIndex ) , K > = HashMap :: new ( ) ; // map to keep track of removed edges, which are added back later
188+ let mut root_cost = K :: default ( ) ; // keep track of the cost of current path till diversion point.
186189
187190 for j in 0usize ..current_path. len ( ) - 1 {
188191 // we are looking for diversion at current_path[j]
189192 let root_node = current_path[ j] ;
190- let next_edge = graph. find_edge ( root_node, current_path[ j+ 1 ] ) . unwrap ( ) ;
193+ let next_edge = graph. find_edge ( root_node, current_path[ j + 1 ] ) . unwrap ( ) ;
191194 let next_edge_cost = * graph. edge_weight ( next_edge) . unwrap ( ) ;
192195
193196 for path in listA. iter ( ) {
194197 // for each path that agrees with current path till node j,
195198 // remove the neighbor of j^{th} node on that path.
196- if path. len ( ) < j+ 1 {
199+ if path. len ( ) < j + 1 {
197200 continue ;
198201 }
199202
200203 if path[ 0 ..=j] == current_path[ 0 ..=j] {
201- if let Some ( edge) = graph. find_edge ( root_node, path[ j+1 ] ) {
202- excluded_edges_map. insert ( ( root_node, path[ j + 1 ] ) , * graph. edge_weight ( edge) . unwrap ( ) ) ;
204+ if let Some ( edge) = graph. find_edge ( root_node, path[ j + 1 ] ) {
205+ excluded_edges_map
206+ . insert ( ( root_node, path[ j + 1 ] ) , * graph. edge_weight ( edge) . unwrap ( ) ) ;
203207 graph. remove_edge ( edge) ;
204208 }
205209 }
206210 }
207211 // find the shortest path form root_node to target in the graph after removing prohibited edges.
208- let ( shortest_root_target_path, path_cost) = dijkstra_shortest_path_with_excluded_prefix (
209- & * graph,
210- root_node,
211- target,
212- |e| { * e. weight ( ) } ,
213- & HashSet :: from_iter ( current_path[ 0 ..=j] . to_vec ( ) . into_iter ( ) ) ,
214- ) ;
212+ let ( shortest_root_target_path, path_cost) =
213+ dijkstra_shortest_path_with_excluded_prefix (
214+ & * graph,
215+ root_node,
216+ target,
217+ |e| * e. weight ( ) ,
218+ & HashSet :: from_iter ( current_path[ 0 ..=j] . to_vec ( ) . into_iter ( ) ) ,
219+ ) ;
215220
216221 if shortest_root_target_path. len ( ) > 0 {
217222 // create new_path by appending current_path till divergence point and the shortest path after that.
@@ -228,7 +233,7 @@ where
228233
229234 // add current edge cost to the root cost
230235 root_cost = root_cost + next_edge_cost;
231- } ;
236+ }
232237
233238 // finally restore the edges we removed to reset the graph for next iteration
234239 for ( edge, wt) in & excluded_edges_map {
@@ -249,45 +254,12 @@ where
249254}
250255
251256
252-
253- /// To return next possible target for the path.
254- /// if all possible nodes are traced, then it picks the shortest endpoint and pick the nodes of next nodes.
255-
256- fn get_smallest_k_element < P > ( scores : & HashMap < NodeIndex , P > , visited : & mut Vec < NodeIndex > ) ->
257- Option < NodeIndex > where P : Copy + std:: cmp:: PartialOrd + std:: default:: Default + std:: ops:: Add < Output = P > + std:: fmt:: Debug {
258- if scores. len ( ) == 1 {
259- for ( node, _score) in scores {
260- return Some ( node. clone ( ) ) ;
261- }
262- }
263- else {
264- let mut score_vec: Vec < _ > = scores. iter ( ) . collect ( ) ;
265- score_vec. sort_by ( |& ( _, & score1) , & ( _, & score2) | {
266- score1. partial_cmp ( & score2) . unwrap_or ( std:: cmp:: Ordering :: Equal )
267- } ) ;
268- let mut count = 0 ;
269- for ( node, _score) in & score_vec {
270- if ! visited. contains ( node) {
271- visited. push ( * * node) ;
272- return Some ( * * node) ;
273- }
274- count = count + 1 ;
275- if count == score_vec. len ( ) {
276- return Some ( * score_vec[ 0 ] . 0 ) ;
277- }
278- }
279-
280- }
281- return None ;
282- }
283-
284-
285257#[ cfg( test) ]
286258mod tests {
287- use petgraph :: { Graph , Undirected } ;
259+ use crate :: shortest_path :: simple_shortest_paths :: get_smallest_k_paths_yen ;
288260 use petgraph:: graph:: NodeIndex ;
261+ use petgraph:: { Graph , Undirected } ;
289262 use rand:: Rng ;
290- use crate :: shortest_path:: simple_shortest_paths:: { get_smallest_k_paths_yen} ;
291263
292264 // The function below generates a graph consisting of n hexagons between two terminal vertices.
293265 // All edges have weights 1. The illustration below shows the graph for n=2.
@@ -300,19 +272,26 @@ mod tests {
300272 //
301273 fn generate_n_cycle_example ( n : usize ) -> ( Graph < usize , u32 , Undirected > , Vec < NodeIndex > ) {
302274 let mut g: Graph < usize , u32 , Undirected > = Graph :: new_undirected ( ) ;
303- let num_nodes = 6 * n + 2 ;
275+ let num_nodes = 6 * n + 2 ;
304276 let mut node_names: Vec < usize > = Vec :: new ( ) ;
305- for i in 0 .. num_nodes {
277+ for i in 0 ..num_nodes {
306278 node_names. push ( i) ;
307279 }
308- let mut nodes = ( 0 ..num_nodes) . into_iter ( ) . map ( |i| g. add_node ( node_names[ i] ) ) . collect :: < Vec < _ > > ( ) ;
280+ let mut nodes = ( 0 ..num_nodes)
281+ . into_iter ( )
282+ . map ( |i| g. add_node ( node_names[ i] ) )
283+ . collect :: < Vec < _ > > ( ) ;
309284 // build cycles
310- for i in 0 .. n {
285+ for i in 0 ..n {
311286 let base = 6 * i + 1 ;
312287 for j in 0 ..6 {
313- g. add_edge ( nodes[ base + ( j % 6 ) ] , nodes[ base + ( ( j + 1 ) % 6 ) ] , ( j+1 ) as u32 ) ;
288+ g. add_edge (
289+ nodes[ base + ( j % 6 ) ] ,
290+ nodes[ base + ( ( j + 1 ) % 6 ) ] ,
291+ ( j + 1 ) as u32 ,
292+ ) ;
314293 }
315- g. add_edge ( nodes[ base + 3 ] , nodes[ base+ 6 ] , 1 ) ;
294+ g. add_edge ( nodes[ base + 3 ] , nodes[ base + 6 ] , 1 ) ;
316295 }
317296
318297 g. add_edge ( nodes[ 0 ] , nodes[ 1 ] , 1 ) ;
@@ -325,45 +304,48 @@ mod tests {
325304 let mut g: Graph < usize , u32 , Undirected > = Graph :: new_undirected ( ) ;
326305 let num_nodes = n;
327306 let mut node_names: Vec < usize > = Vec :: new ( ) ;
328- for i in 0 .. num_nodes {
307+ for i in 0 ..num_nodes {
329308 node_names. push ( i) ;
330309 }
331- let mut nodes = ( 0 ..num_nodes) . into_iter ( ) . map ( |i| g. add_node ( node_names[ i] ) ) . collect :: < Vec < _ > > ( ) ;
310+ let mut nodes = ( 0 ..num_nodes)
311+ . into_iter ( )
312+ . map ( |i| g. add_node ( node_names[ i] ) )
313+ . collect :: < Vec < _ > > ( ) ;
332314 // build cycles
333- for i in 0 .. n {
334- g. add_edge ( nodes[ i] , nodes[ ( i+ 1 ) % n] , 1 ) ;
315+ for i in 0 ..n {
316+ g. add_edge ( nodes[ i] , nodes[ ( i + 1 ) % n] , 1 ) ;
335317 }
336318 ( g, nodes)
337319 }
338320
339321 // This function generates an undirected n-gon as in previous example, with additional chords.
340322 // The argument step specifies the clockwise distance between vertices connected by the chords.
341- fn generate_n_gon_with_chords_example ( n : usize , step : usize ) -> ( Graph < usize , u32 , Undirected > , Vec < NodeIndex > ) {
323+ fn generate_n_gon_with_chords_example (
324+ n : usize ,
325+ step : usize ,
326+ ) -> ( Graph < usize , u32 , Undirected > , Vec < NodeIndex > ) {
342327 let mut g: Graph < usize , u32 , Undirected > = Graph :: new_undirected ( ) ;
343328 let num_nodes = n;
344329 let mut node_names: Vec < usize > = Vec :: new ( ) ;
345- for i in 0 .. num_nodes {
330+ for i in 0 ..num_nodes {
346331 node_names. push ( i) ;
347332 }
348- let mut nodes = ( 0 ..num_nodes) . into_iter ( ) . map ( |i| g. add_node ( node_names[ i] ) ) . collect :: < Vec < _ > > ( ) ;
333+ let mut nodes = ( 0 ..num_nodes)
334+ . into_iter ( )
335+ . map ( |i| g. add_node ( node_names[ i] ) )
336+ . collect :: < Vec < _ > > ( ) ;
349337 // build cycles
350- for i in 0 .. n {
351- g. add_edge ( nodes[ i] , nodes[ ( i+ 1 ) % n] , 1 ) ;
352- g. add_edge ( nodes[ i] , nodes[ ( i+ step) % n] , 1 ) ;
338+ for i in 0 ..n {
339+ g. add_edge ( nodes[ i] , nodes[ ( i + 1 ) % n] , 1 ) ;
340+ g. add_edge ( nodes[ i] , nodes[ ( i + step) % n] , 1 ) ;
353341 }
354342 ( g, nodes)
355343 }
356344
357-
358345 #[ test]
359346 fn test_k_shortest_paths ( ) {
360347 let ( mut graph, nodes) = generate_n_gon_with_chords_example ( 6 , 2 ) ;
361- let paths = get_smallest_k_paths_yen (
362- & mut graph,
363- nodes[ 0 ] ,
364- nodes[ 1 ] ,
365- 10
366- ) ;
348+ let paths = get_smallest_k_paths_yen ( & mut graph, nodes[ 0 ] , nodes[ 1 ] , 10 ) ;
367349 for path in paths {
368350 println ! ( "{:#?}" , path) ;
369351 }
@@ -374,23 +356,23 @@ mod tests {
374356 let mut g = Graph :: new_undirected ( ) ;
375357 let nodes: Vec < NodeIndex > = ( 0 ..5000 ) . map ( |_| g. add_node ( ( ) ) ) . collect ( ) ;
376358 let mut rng: rand:: prelude:: ThreadRng = rand:: thread_rng ( ) ;
377- for _ in 0 ..62291 { // Adjust the number of edges as desired
359+ for _ in 0 ..62291 {
360+ // Adjust the number of edges as desired
378361 let a = rng. gen_range ( 0 ..nodes. len ( ) ) ;
379362 let b = rng. gen_range ( 0 ..nodes. len ( ) ) ;
380363 let weight = rng. gen_range ( 1 ..100 ) ; // Random weight between 1 and 100
381- if a != b { // Prevent self-loops
382- g. add_edge ( nodes[ a] , nodes[ b] , weight as f32 ) ; }
364+ if a != b {
365+ // Prevent self-loops
366+ g. add_edge ( nodes[ a] , nodes[ b] , weight as f32 ) ;
367+ }
383368 }
384369 println ! ( "Graph created" ) ;
385370 let source = nodes[ 1 ] ;
386371 let target = nodes[ 4000 ] ;
387- let shortest_path_get : usize = 5 ;
372+ let shortest_path_get: usize = 5 ;
388373 //println!(“{:?}“, g);
389- for p in get_smallest_k_paths_yen ( & mut g, source, target, 10 ) {
390- println ! ( "Path: {:#?} " , p) ;
374+ for p in get_smallest_k_paths_yen ( & mut g, source, target, 10 ) {
375+ println ! ( "Path: {:#?} " , p) ;
391376 }
392-
393377 }
394378}
395-
396-
0 commit comments