use crate::transit_network::Link;
pub(crate) struct PqEntry<'a> {
pub(crate) link: &'a Link,
pub(crate) priority: f64,
pub(crate) index: i64,
}
pub(crate) struct PriorityQueue<'a> {
entries: Vec<PqEntry<'a>>,
heap: Vec<usize>,
}
impl<'a> PriorityQueue<'a> {
pub(crate) fn with_capacity(capacity: usize) -> Self {
PriorityQueue {
entries: Vec::with_capacity(capacity),
heap: Vec::with_capacity(capacity),
}
}
pub(crate) fn push(&mut self, link: &'a Link, priority: f64) -> usize {
let id = self.entries.len();
self.entries.push(PqEntry {
link,
priority,
index: 0,
});
self.heap.push(id);
id
}
pub(crate) fn len(&self) -> usize {
self.heap.len()
}
pub(crate) fn link(&self, id: usize) -> &'a Link {
self.entries[id].link
}
pub(crate) fn priority(&self, id: usize) -> f64 {
self.entries[id].priority
}
fn less(&self, i: usize, j: usize) -> bool {
self.entries[self.heap[i]].priority <= self.entries[self.heap[j]].priority
}
fn swap(&mut self, i: usize, j: usize) {
self.heap.swap(i, j);
self.entries[self.heap[i]].index = i as i64;
self.entries[self.heap[j]].index = j as i64;
}
pub(crate) fn pop(&mut self) -> Option<usize> {
let n = self.heap.len();
if n == 0 {
return None;
}
let first = self.heap[0];
let last = self.heap[n - 1];
self.heap[0] = last;
self.entries[last].index = 0;
self.heap.truncate(n - 1);
self.sift_down(0);
self.entries[first].index = -1;
Some(first)
}
pub(crate) fn init(&mut self) {
for i in 0..self.heap.len() {
self.entries[self.heap[i]].index = i as i64;
}
let mut i = self.heap.len() as i64 / 2 - 1;
while i >= 0 {
self.sift_down(i as usize);
i -= 1;
}
}
pub(crate) fn update(&mut self, id: usize, priority: f64) {
if self.entries[id].index < 0 {
return;
}
let old_priority = self.entries[id].priority;
self.entries[id].priority = priority;
let index = self.entries[id].index;
if priority <= old_priority {
self.sift_up(index);
} else {
self.sift_down(index as usize);
}
}
fn sift_up(&mut self, mut i: i64) {
while i > 0 {
let parent = (i - 1) / 2;
if self.less(i as usize, parent as usize) {
self.swap(i as usize, parent as usize);
i = parent;
} else {
break;
}
}
}
fn sift_down(&mut self, i: usize) {
let n = self.heap.len();
let mut i = i;
loop {
let mut smallest = i;
let left = 2 * i + 1;
let right = 2 * i + 2;
if left < n && self.less(left, smallest) {
smallest = left;
}
if right < n && self.less(right, smallest) {
smallest = right;
}
if smallest != i {
self.swap(i, smallest);
i = smallest;
} else {
break;
}
}
}
pub(crate) fn print(&self) {
if self.len() == 0 {
println!("Priority Queue: <empty>");
return;
}
let arr: Vec<String> = self
.heap
.iter()
.map(|&id| {
let entry = &self.entries[id];
format!(
"({},{}) == {:.2}",
entry.link.from_node, entry.link.to_node, entry.priority
)
})
.collect();
println!("Priority Queue: [{}]\\\\ ", arr.join(", "));
}
}