1extern crate petgraph;
9
10mod scored;
11
12#[cfg(test)]
13mod tests;
14
15use petgraph::{Direction, Graph};
16use petgraph::graph::{EdgeIndex, NodeIndex};
17use petgraph::algo::Measure;
18use petgraph::visit::{EdgeRef, IntoEdgesDirected, IntoNodeReferences, NodeRef, Visitable, VisitMap};
19use std::collections::{BinaryHeap, HashMap, VecDeque};
20use std::collections::hash_map::Entry;
21use std::hash::Hash;
22use std::ops::Sub;
23
24use scored::{MinScored, Scored};
25
26#[derive(Debug)]
27pub struct ShortPathsIterator<'a, N: 'a, E: 'a, K>
28 where
29 K: PartialOrd
30{
31 graph: &'a Graph<N, E>,
32 source: NodeIndex,
33 spt: HashMap<NodeIndex, (K, Option<EdgeIndex>)>,
34 path_graph: Graph<PathNode, (PathEdge, K)>,
35 path_graph_root: NodeIndex,
36 generated_paths: Vec<PathData>,
37 visit_queue: BinaryHeap<MinScored<K, PathData>>,
38}
39
40#[derive(Clone, Debug)]
41pub enum PathData {
42 Empty,
43 Augment(usize, EdgeIndex),
44}
45
46fn build_shortest_path_tree<G, F, K>(graph: G, target: G::NodeId, mut edge_cost: F)
53 -> HashMap<G::NodeId, (K, Option<G::EdgeId>)>
54 where
55 G: IntoEdgesDirected + Visitable,
56 G::NodeId: Eq + Hash,
57 F: FnMut(G::EdgeRef) -> K,
58 K: Measure + Copy,
59{
60 let mut visited = graph.visit_map();
61 let mut tree = HashMap::new();
62 let mut visit_next = BinaryHeap::new();
63 let zero_score = K::default();
64
65 tree.insert(target, (zero_score, None));
66 visit_next.push(MinScored(zero_score, target));
67
68 while let Some(MinScored(node_score, node)) = visit_next.pop() {
69 if visited.is_visited(&node) {
70 continue
71 }
72
73 visited.visit(node);
74
75 for e in graph.edges_directed(node, Direction::Incoming) {
76 let next = e.source();
77 if visited.is_visited(&next) {
78 continue
79 }
80
81 visited.visit(node);
82
83 let next_score = node_score + edge_cost(e);
84 match tree.entry(next) {
85 Entry::Occupied(ent) => {
86 let (previous_score, _) = *ent.get();
87 if next_score < previous_score {
88 *ent.into_mut() = (next_score, Some(e.id()));
89 } else {
90 continue
91 }
92 },
93 Entry::Vacant(ent) => {
94 ent.insert((next_score, Some(e.id())));
95 },
96 }
97
98 visit_next.push(MinScored(next_score, next));
99 }
100 }
101
102 tree
103}
104
105fn build_heap_graph<N, E, K, F>(
110 graph: &Graph<N, E>,
111 target: NodeIndex,
112 spt: &HashMap<NodeIndex, (K, Option<EdgeIndex>)>,
113 mut edge_cost: F,
114) -> (Graph<(EdgeIndex, K), ()>, HashMap<NodeIndex, NodeIndex>)
115 where
116 E: Copy,
117 F: FnMut(E) -> K,
118 K: Measure + Sub<Output=K> + Copy,
119{
120 let mut result_graph = Graph::<(EdgeIndex, K), ()>::new();
121 let mut heap_roots = HashMap::new();
122
123 let mut inverse_spt: HashMap<NodeIndex, Vec<NodeIndex>> = HashMap::new();
124 for (&node, &(_, successor)) in spt.iter() {
125 if let Some(successor_edge) = successor {
126 let successor_node = graph.edge_endpoints(successor_edge).unwrap().1;
127 inverse_spt.entry(successor_node).or_insert_with(Vec::new).push(node);
128 }
129 }
130
131 let mut edge_sidetrack_cost = |e: EdgeIndex| -> K {
132 let (edge_source, edge_target) = match graph.edge_endpoints(e) {
133 Some(endpoints) => endpoints,
134 None => return K::default(),
135 };
136 let source_distance = match spt.get(&edge_source) {
137 Some(&(dist, _)) => dist,
138 None => return K::default(),
139 };
140 let target_distance = match spt.get(&edge_target) {
141 Some(&(dist, _)) => dist,
142 None => return K::default(),
143 };
144 edge_cost(graph[e]) + target_distance - source_distance
145 };
146
147 let mut visit_order = VecDeque::new();
148 visit_order.push_back(target);
149
150 while let Some(node) = visit_order.pop_front() {
151 let (_, successor) = spt[&node];
152 match successor {
153 Some(successor_edge_id) => {
154 let successor_target = graph.edge_endpoints(successor_edge_id).unwrap().1;
155
156 match heap_roots.get(&successor_target) {
157 Some(&successor_heap_root) => {
158 let mut outgoing_edges: Vec<EdgeIndex> = Vec::new();
159 for e in graph.edges(node) {
160 let e_id = e.id();
161 if e_id == successor_edge_id {
162 continue
163 }
164 outgoing_edges.push(e_id);
165 }
166
167 let new_root = merge_and_embed(&mut result_graph, outgoing_edges, successor_heap_root, &mut edge_sidetrack_cost);
168 heap_roots.insert(node, new_root);
169 },
170 None => {
171 let mut scored_edges: Vec<Scored<K, EdgeIndex>> = Vec::new();
173 for e in graph.edges(node) {
174 let e_id = e.id();
175 if e_id == successor_edge_id {
176 continue
177 }
178 scored_edges.push(Scored(edge_sidetrack_cost(e_id), e_id));
179 }
180
181 if scored_edges.len() > 0 {
182 min_heapify(&mut scored_edges);
183
184 let mut heap_nodes = Vec::new();
185 for &Scored(e_cost, e_id) in scored_edges.iter() {
186 let new_node = result_graph.add_node((e_id, e_cost));
187 heap_nodes.push(new_node);
188 }
189 for (i, &node) in heap_nodes.iter().enumerate() {
190 if 2*i + 1 < heap_nodes.len() {
191 let child_node = heap_nodes[2*i+1];
192 result_graph.add_edge(node, child_node, ());
193 }
194 if 2*i + 2 < heap_nodes.len() {
195 let child_node = heap_nodes[2*i+2];
196 result_graph.add_edge(node, child_node, ());
197 }
198 }
199 heap_roots.insert(node, heap_nodes[0]);
200 }
201 },
202 }
203 },
204 None => {
205 let mut scored_edges: Vec<Scored<K, EdgeIndex>> = Vec::new();
208 for e in graph.edges(node) {
209 let e_id = e.id();
210 scored_edges.push(Scored(edge_sidetrack_cost(e_id), e_id));
211 }
212 if scored_edges.len() > 0 {
213 min_heapify(&mut scored_edges);
214
215 let mut heap_nodes = Vec::new();
216 for &Scored(e_cost, e_id) in scored_edges.iter() {
217 let new_node = result_graph.add_node((e_id, e_cost));
218 heap_nodes.push(new_node);
219 }
220 for (i, &node) in heap_nodes.iter().enumerate() {
221 if 2*i + 1 < heap_nodes.len() {
222 let child_node = heap_nodes[2*i+1];
223 result_graph.add_edge(node, child_node, ());
224 }
225 if 2*i + 2 < heap_nodes.len() {
226 let child_node = heap_nodes[2*i+2];
227 result_graph.add_edge(node, child_node, ());
228 }
229 }
230 heap_roots.insert(node, heap_nodes[0]);
231 }
232 },
233 }
234 if let Some(predecessors) = inverse_spt.get(&node) {
235 for &pred in predecessors.iter() {
236 visit_order.push_back(pred);
237 }
238 }
239 }
240
241 (result_graph, heap_roots)
242}
243
244#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
245pub enum PathNode {
246 Root,
247 Heap(EdgeIndex),
248}
249
250#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
251pub enum PathEdge {
252 Heap,
253 Cross,
254 Initial,
255}
256
257fn build_path_graph<N, E, K>(
258 graph: &Graph<N, E>,
259 source: NodeIndex,
260 spt: &HashMap<NodeIndex, (K, Option<EdgeIndex>)>,
261 heap_graph: &Graph<(EdgeIndex, K), ()>,
262 heap_roots: &HashMap<NodeIndex, NodeIndex>,
263) -> (Graph<PathNode, (PathEdge, K)>, NodeIndex)
264 where
265 E: Copy,
266 K: Measure + Sub<Output=K> + Copy,
267{
268 let mut result_graph = Graph::<PathNode, (PathEdge, K)>::new();
269 let mut node_map: HashMap<NodeIndex, NodeIndex> = HashMap::new();
271
272 let root_node = result_graph.add_node(PathNode::Root);
273
274 for n in heap_graph.node_references() {
275 let &(e_id, _) = n.weight();
276 let new_node = result_graph.add_node(PathNode::Heap(e_id));
277
278 node_map.insert(n.id(), new_node);
279 }
280
281 for e in heap_graph.edge_references() {
283 let s = e.source();
284 let t = e.target();
285 let &(_, source_edge_sidetrack) = heap_graph.node_weight(s).unwrap();
286 let &(_, target_edge_sidetrack) = heap_graph.node_weight(t).unwrap();
287
288 let s_node = node_map[&s];
289 let t_node = node_map[&t];
290 result_graph.add_edge(s_node, t_node, (PathEdge::Heap, target_edge_sidetrack - source_edge_sidetrack));
291 }
292
293 for n in heap_graph.node_references() {
295 let &(e_id, _) = n.weight();
296 let (e_source, e_target) = graph.edge_endpoints(e_id).unwrap();
297 if let Some(&(_, Some(spt_edge_id))) = spt.get(&e_source) {
298 if e_id == spt_edge_id {
299 continue
300 }
301 }
302 let new_source = node_map[&n.id()];
303 if let Some(&root_node) = heap_roots.get(&e_target) {
304 let &(_, root_edge_sidetrack) = heap_graph.node_weight(root_node).unwrap();
305 let new_target = node_map[&root_node];
306 result_graph.add_edge(new_source, new_target, (PathEdge::Cross, root_edge_sidetrack));
307 }
308 }
309
310 let initial_root = heap_roots[&source];
312 let &(_, initial_root_sidetrack) = heap_graph.node_weight(initial_root).unwrap();
313 let initial_target = node_map[&initial_root];
314 result_graph.add_edge(root_node, initial_target, (PathEdge::Initial, initial_root_sidetrack));
315
316 (result_graph, root_node)
317}
318
319fn merge_and_embed<N, K, F>(graph: &mut Graph<(N, K), ()>, values: Vec<N>, target_root: NodeIndex, mut cost: F) -> NodeIndex
323 where
324 N: Copy,
325 F: FnMut(N) -> K,
326 K: PartialOrd + Copy,
327{
328 if values.len() == 0 {
330 return target_root
331 }
332
333 let mut scored_values = Vec::new();
334 for v in values {
335 scored_values.push(Scored(cost(v), v));
336 }
337 min_heapify(&mut scored_values);
338
339 let new_root = make_root(graph, scored_values[0].1, target_root, cost);
342
343 let mut heap_nodes = Vec::new();
345 heap_nodes.push(new_root);
346
347 for &Scored(v_cost, v) in scored_values.iter().skip(1) {
348 let new_node = graph.add_node((v, v_cost));
349 heap_nodes.push(new_node);
350 }
351
352 for (i, &node) in heap_nodes.iter().enumerate() {
353 if 2*i + 1 < heap_nodes.len() {
354 let child_node = heap_nodes[2*i + 1];
355 graph.add_edge(node, child_node, ());
356 }
357 if 2*i + 2 < heap_nodes.len() {
358 let child_node = heap_nodes[2*i + 2];
359 graph.add_edge(node, child_node, ());
360 }
361 }
362
363 new_root
364}
365
366fn make_root<N, F, K>(graph: &mut Graph<(N, K), ()>, new_value: N, target_root: NodeIndex, mut cost: F) -> NodeIndex
370 where
371 N: Copy,
372 F: FnMut(N) -> K,
373 K: PartialOrd + Copy,
374{
375 let value_cost = cost(new_value);
376 let root_cost = graph[target_root].1;
377 if value_cost <= root_cost {
378 let new_root = graph.add_node((new_value, value_cost));
379 graph.add_edge(new_root, target_root, ());
380 return new_root;
381 }
382 let mut least_child_edge = None;
383 for e in graph.edges(target_root) {
384 match least_child_edge {
385 None => {
386 let child_node = e.target();
387 let child_cost = graph[child_node].1;
388 least_child_edge = Some((child_cost, e.id()));
389 },
390 Some((old_child_cost, _)) => {
391 let child_node = e.target();
392 let child_cost = graph[child_node].1;
393 if child_cost < old_child_cost {
394 least_child_edge = Some((child_cost, e.id()));
395 }
396 },
397 }
398 }
399 match least_child_edge {
400 Some((_, e_id)) => {
401 let least_child_node = graph.edge_endpoints(e_id).unwrap().1;
402 let new_child = make_root(graph, new_value, least_child_node, cost);
405 let mut targets = Vec::new();
407 for e in graph.edges(target_root) {
408 if e.id() == e_id {
409 continue
410 }
411 targets.push(e.target());
412 }
413 for t in targets {
414 graph.add_edge(new_child, t, ());
415 }
416 let target_root_value = graph[target_root];
419 let new_root = graph.add_node(target_root_value);
420 graph.add_edge(new_root, new_child, ());
421
422 new_root
423 },
424 None => {
425 let new_child = graph.add_node((new_value, cost(new_value)));
428 let (target_root_value, target_root_cost) = graph[target_root];
429 let new_root = graph.add_node((target_root_value, target_root_cost));
430 graph.add_edge(new_root, new_child, ());
431
432 new_root
433 },
434 }
435}
436
437fn min_heapify<T: PartialOrd>(vec: &mut [T]) {
438 let mut n = vec.len() / 2;
439 while n > 0 {
440 n -= 1;
441 sift_down(vec, n);
442 }
443}
444
445#[test]
446fn test_heapify() {
447 let mut vec = vec![3,1,4,1,5,9,2,6,5,3,5,8,9,7,9,3,2,3];
448 min_heapify(&mut vec);
449
450 for (i, &v) in vec.iter().enumerate() {
451 if 2*i + 1 < vec.len() {
452 assert!(v <= vec[2*i + 1]);
453 }
454 if 2*i + 2 < vec.len() {
455 assert!(v <= vec[2*i + 2]);
456 }
457 }
458}
459
460fn sift_down<T: PartialOrd>(vec: &mut [T], mut pos: usize) {
461 loop {
462 let mut child = 2 * pos + 1;
463 if child >= vec.len() {
464 return
465 }
466 let right = child + 1;
467 if right < vec.len() && vec[right] < vec[child] {
469 child = right;
470 }
471 if vec[pos] < vec[child] {
473 return
474 }
475 vec.swap(pos, child);
477 pos = child;
478 }
479}
480
481impl<'a, N, E, K> ShortPathsIterator<'a, N, E, K>
482 where
483 N: 'a + Eq + Copy,
484 E: 'a + Copy,
485 K: PartialOrd + Measure + Sub<Output=K> + Copy,
486{
487 pub fn new<F>(graph: &'a Graph<N, E>, source: NodeIndex, target: NodeIndex, mut edge_cost: F) -> Self
488 where
489 F: FnMut(E) -> K,
490 {
491 let spt = build_shortest_path_tree(graph, target, |e_ref| { edge_cost(*e_ref.weight()) });
492 let (heap_graph, heap_roots) = build_heap_graph(graph, target, &spt, edge_cost);
493 let (path_graph, path_graph_root) = build_path_graph(graph, source, &spt, &heap_graph, &heap_roots);
494
495 let generated_paths = Vec::new();
496 let mut visit_queue = BinaryHeap::new();
497 visit_queue.push(MinScored(K::default(), PathData::Empty));
498
499 ShortPathsIterator {
500 graph,
501 source,
502 spt,
503 path_graph,
504 path_graph_root,
505 generated_paths,
506 visit_queue,
507 }
508 }
509
510 fn path_end(&self, path_data: &PathData) -> NodeIndex {
512 match path_data {
513 &PathData::Empty => {
514 self.path_graph_root
515 },
516 &PathData::Augment(_, edge_idx) => {
517 self.path_graph.edge_endpoints(edge_idx).unwrap().1
518 }
519 }
520 }
521
522 fn unwind_path_graph_path(&self, path_data: &PathData) -> Vec<EdgeIndex> {
523 match path_data {
524 &PathData::Empty => {
525 Vec::new()
526 },
527 &PathData::Augment(parent_idx, edge_idx) => {
528 let mut path = self.unwind_path_graph_path(&self.generated_paths[parent_idx]);
529 path.push(edge_idx);
530 path
531 },
532 }
533 }
534
535 fn expand_path(&self, path_graph_path: &[EdgeIndex]) -> Vec<EdgeIndex> {
536 let mut path = Vec::new();
537 let mut current_vertex = self.source;
538 let mut final_node = self.path_graph_root;
539
540 for &e_id in path_graph_path.iter() {
542 let (e_source, e_target) = self.path_graph.edge_endpoints(e_id).unwrap();
543 final_node = e_target;
544 if let Some(&(PathEdge::Cross, _)) = self.path_graph.edge_weight(e_id) {
545 if let Some(&PathNode::Heap(non_spt_edge)) = self.path_graph.node_weight(e_source) {
546 let (non_spt_source, non_spt_target) = self.graph.edge_endpoints(non_spt_edge).unwrap();
547 while current_vertex != non_spt_source {
548 match self.spt.get(¤t_vertex) {
549 Some(&(_, Some(spt_edge))) => {
550 let (_, spt_edge_target) = self.graph.edge_endpoints(spt_edge).unwrap();
551 path.push(spt_edge);
552 current_vertex = spt_edge_target;
553 },
554 _ => {
555 panic!("Reached a vertex with no outgoing shortest path tree edge!")
556 },
557 }
558 }
559 path.push(non_spt_edge);
560 current_vertex = non_spt_target;
561 } else {
562 panic!("Cross edge doesn't correspond to a heap edge?")
563 }
564 }
565 }
566
567 if let Some(&PathNode::Heap(non_spt_edge)) = self.path_graph.node_weight(final_node) {
569 let (non_spt_source, non_spt_target) = self.graph.edge_endpoints(non_spt_edge).unwrap();
570 while current_vertex != non_spt_source {
571 match self.spt.get(¤t_vertex) {
572 Some(&(_, Some(spt_edge))) => {
573 let (_, spt_edge_target) = self.graph.edge_endpoints(spt_edge).unwrap();
574 path.push(spt_edge);
575 current_vertex = spt_edge_target;
576 },
577 _ => panic!("Reached a vertex with no outgoing shortest path tree edge!"),
578 }
579 }
580 path.push(non_spt_edge);
581 current_vertex = non_spt_target;
582 }
583
584 while let Some(&(_, Some(spt_edge))) = self.spt.get(¤t_vertex) {
586 let (_, spt_edge_target) = self.graph.edge_endpoints(spt_edge).unwrap();
587 path.push(spt_edge);
588 current_vertex = spt_edge_target;
589 }
590
591 path
592 }
593}
594
595impl<'a, N, E, K> Iterator for ShortPathsIterator<'a, N, E, K>
596 where
597 N: 'a + Eq + Copy,
598 E: 'a + Copy,
599 K: PartialOrd + Measure + Sub<Output=K> + Copy,
600{
601 type Item=Vec<EdgeIndex>;
602
603 fn next(&mut self) -> Option<Self::Item> {
604 let front = self.visit_queue.pop();
605 match front {
606 Some(MinScored(path_score, path_data)) => {
607 let path_graph_path = self.unwind_path_graph_path(&path_data);
608 let path_to_return = self.expand_path(&path_graph_path);
609
610 let final_node = self.path_end(&path_data);
611
612 let path_index = self.generated_paths.len();
613 self.generated_paths.push(path_data);
614
615 for edge in self.path_graph.edges(final_node) {
616 let &(_, edge_cost) = edge.weight();
617 let new_path_cost = path_score + edge_cost;
618 let new_path_data = PathData::Augment(path_index, edge.id());
619
620 self.visit_queue.push(MinScored(new_path_cost, new_path_data));
621 }
622
623 Some(path_to_return)
624 },
625 None => {
626 None
627 },
628 }
629 }
630}