Add fibonacci_heap implementation
This commit is contained in:
parent
6cbb389ee7
commit
d2c1e6d422
6 changed files with 303 additions and 187 deletions
40
examples/priority_queue_test.rs
Normal file
40
examples/priority_queue_test.rs
Normal file
|
|
@ -0,0 +1,40 @@
|
||||||
|
use factorio_blueprint::priority_queue::{fibonacci_heap::FibonacciHeap, PriorityQueue};
|
||||||
|
use std::fmt::Debug;
|
||||||
|
|
||||||
|
fn test_loop<P>()
|
||||||
|
where
|
||||||
|
P: PriorityQueue<u16> + Debug,
|
||||||
|
{
|
||||||
|
let mut input = String::new();
|
||||||
|
|
||||||
|
let mut p = P::new();
|
||||||
|
|
||||||
|
let mut handles = Vec::new();
|
||||||
|
|
||||||
|
loop {
|
||||||
|
input.clear();
|
||||||
|
std::io::stdin().read_line(&mut input);
|
||||||
|
|
||||||
|
let (cmd, arg) = input.trim().split_once(' ').unwrap_or((input.trim(), ""));
|
||||||
|
// dbg!(cmd, arg);
|
||||||
|
|
||||||
|
match cmd {
|
||||||
|
"i" => handles.push(p.insert(arg.parse::<u16>().unwrap())),
|
||||||
|
"m" => println!("{:?}", p.pop_min()),
|
||||||
|
"d" => {
|
||||||
|
let (a, b) = arg.split_once(' ').unwrap();
|
||||||
|
let h = &handles[a.parse::<usize>().unwrap()];
|
||||||
|
let n = b.parse::<u16>().unwrap();
|
||||||
|
p.decrease_key(h, |f| *f = n);
|
||||||
|
}
|
||||||
|
"p" => {
|
||||||
|
dbg!(&p);
|
||||||
|
}
|
||||||
|
_ => println!("Unknown command."),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
test_loop::<FibonacciHeap<u16>>()
|
||||||
|
}
|
||||||
|
|
@ -1,32 +0,0 @@
|
||||||
use factorio_blueprint::belt_finding::{common::Position, Problem};
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
let mut p = Problem::new(33, 13);
|
|
||||||
|
|
||||||
p.set_blocked_range(1, 3, 2, 5, true);
|
|
||||||
p.set_blocked_range(1, 7, 2, 9, true);
|
|
||||||
|
|
||||||
p.set_blocked(0, 3, true);
|
|
||||||
p.set_blocked(0, 8, true);
|
|
||||||
|
|
||||||
p.set_blocked_range(10, 0, 21, 2, true);
|
|
||||||
p.set_blocked_range(10, 5, 21, 7, true);
|
|
||||||
p.set_blocked_range(10, 10, 21, 12, true);
|
|
||||||
|
|
||||||
p.set_blocked_range(30, 3, 31, 5, true);
|
|
||||||
p.set_blocked_range(30, 7, 31, 9, true);
|
|
||||||
p.set_blocked(32, 3, true);
|
|
||||||
p.set_blocked(32, 9, true);
|
|
||||||
|
|
||||||
p.add_connection(Position::new(3, 3), Position::new(29, 7));
|
|
||||||
p.add_connection(Position::new(3, 4), Position::new(29, 9));
|
|
||||||
p.add_connection(Position::new(3, 5), Position::new(29, 8));
|
|
||||||
|
|
||||||
p.add_connection(Position::new(3, 7), Position::new(29, 3));
|
|
||||||
p.add_connection(Position::new(3, 8), Position::new(29, 5));
|
|
||||||
p.add_connection(Position::new(3, 9), Position::new(29, 4));
|
|
||||||
|
|
||||||
println!("{p}");
|
|
||||||
p.find_path();
|
|
||||||
println!("{p}");
|
|
||||||
}
|
|
||||||
|
|
@ -1,7 +1,9 @@
|
||||||
use crate::graph::wheighted_graph::shortest_path::dijkstra;
|
|
||||||
use crate::graph::wheighted_graph::WheightedGraph;
|
use crate::graph::wheighted_graph::WheightedGraph;
|
||||||
use crate::misc::Map;
|
use crate::misc::Map;
|
||||||
use crate::priority_queue::BinaryHeap;
|
use crate::priority_queue::BinaryHeap;
|
||||||
|
use crate::{
|
||||||
|
graph::wheighted_graph::shortest_path::dijkstra, priority_queue::fibonacci_heap::FibonacciHeap,
|
||||||
|
};
|
||||||
use std::ops::Index;
|
use std::ops::Index;
|
||||||
use termcolor::{Color, ColorSpec};
|
use termcolor::{Color, ColorSpec};
|
||||||
|
|
||||||
|
|
@ -208,7 +210,7 @@ impl Problem {
|
||||||
for i in 0..self.start.len() {
|
for i in 0..self.start.len() {
|
||||||
self.calculate_wheights(i);
|
self.calculate_wheights(i);
|
||||||
let m = MapInternal { map: &self.map };
|
let m = MapInternal { map: &self.map };
|
||||||
let p = dijkstra::<MapInternal, BinaryHeap<_>>(&m, self.start[i], self.end[i]);
|
let p = dijkstra::<MapInternal, FibonacciHeap<_>>(&m, self.start[i], self.end[i]);
|
||||||
|
|
||||||
if let Some(p) = p {
|
if let Some(p) = p {
|
||||||
self.path[i] = p;
|
self.path[i] = p;
|
||||||
|
|
|
||||||
|
|
@ -119,7 +119,7 @@ mod test {
|
||||||
graph::wheighted_graph::{
|
graph::wheighted_graph::{
|
||||||
adjacency_list::WheightedAdjacencyList, shortest_path::dijkstra, WheightedGraph,
|
adjacency_list::WheightedAdjacencyList, shortest_path::dijkstra, WheightedGraph,
|
||||||
},
|
},
|
||||||
priority_queue::BinaryHeap,
|
priority_queue::{fibonacci_heap::FibonacciHeap, BinaryHeap},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
@ -162,6 +162,14 @@ mod test {
|
||||||
dijkstra::<WheightedAdjacencyList, BinaryHeap<_>>(&a, 0, 6),
|
dijkstra::<WheightedAdjacencyList, BinaryHeap<_>>(&a, 0, 6),
|
||||||
None
|
None
|
||||||
);
|
);
|
||||||
|
assert_eq!(
|
||||||
|
dijkstra::<WheightedAdjacencyList, FibonacciHeap<_>>(&a, 0, 4),
|
||||||
|
Some(vec![0, 1, 2, 5, 4])
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
dijkstra::<WheightedAdjacencyList, FibonacciHeap<_>>(&a, 0, 6),
|
||||||
|
None
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Grid {
|
struct Grid {
|
||||||
|
|
|
||||||
|
|
@ -1,186 +1,280 @@
|
||||||
|
use std::fmt::Debug;
|
||||||
|
|
||||||
use crate::misc::{Arena, ArenaKey};
|
use crate::misc::{Arena, ArenaKey};
|
||||||
|
|
||||||
use super::PriorityQueue;
|
use super::PriorityQueue;
|
||||||
|
|
||||||
#[derive(Debug)]
|
type Index = u32;
|
||||||
struct FibonacciHeapObject<T> {
|
|
||||||
left: ArenaKey,
|
pub struct FibonacciHeap<I> {
|
||||||
right: ArenaKey,
|
min: Option<Index>,
|
||||||
parent: Option<ArenaKey>,
|
data: Vec<Option<Node<I>>>,
|
||||||
child: Option<ArenaKey>,
|
free: Vec<Index>,
|
||||||
rank: usize,
|
temp: [Option<Index>; 64],
|
||||||
marked: bool,
|
}
|
||||||
data: T,
|
|
||||||
|
impl<I: std::fmt::Debug> std::fmt::Debug for FibonacciHeap<I> {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
struct PrintData<'a, I>(&'a Vec<Option<Node<I>>>);
|
||||||
|
impl<'a, I: Debug> Debug for PrintData<'a, I> {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
f.debug_map()
|
||||||
|
.entries(self.0.iter().enumerate().filter_map(|d| {
|
||||||
|
if let (i, Some(c)) = d {
|
||||||
|
Some((i, c))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
.finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
f.debug_struct("FibonacciHeap")
|
||||||
|
.field("min", &self.min)
|
||||||
|
.field("data", &PrintData(&self.data))
|
||||||
|
.field("free", &self.free)
|
||||||
|
.finish()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct FibonacciHeap<T> {
|
pub struct FibonacciHeapHandle(Index);
|
||||||
arena: Arena<FibonacciHeapObject<T>>,
|
|
||||||
min: Option<ArenaKey>,
|
#[derive(Debug)]
|
||||||
update_rank: Vec<Option<ArenaKey>>,
|
struct Node<I> {
|
||||||
|
item: I,
|
||||||
|
parent: Index,
|
||||||
|
left: Index,
|
||||||
|
right: Index,
|
||||||
|
child: Index,
|
||||||
|
mark: bool,
|
||||||
|
rank: u16,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct FibonacciHeapHandle(ArenaKey);
|
impl<I> Node<I> {
|
||||||
|
fn new(item: I) -> Self {
|
||||||
|
Self {
|
||||||
|
item,
|
||||||
|
parent: 0,
|
||||||
|
left: 0,
|
||||||
|
right: 0,
|
||||||
|
child: 0,
|
||||||
|
mark: false,
|
||||||
|
rank: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<T> PriorityQueue<T> for FibonacciHeap<T>
|
impl<I> FibonacciHeap<I>
|
||||||
where
|
where
|
||||||
T: std::cmp::Ord,
|
I: PartialOrd,
|
||||||
|
{
|
||||||
|
fn add_to_list(&mut self, list: Index, i: Index) {
|
||||||
|
let right = self.get(list).right;
|
||||||
|
let n = self.get_mut(i);
|
||||||
|
n.right = right;
|
||||||
|
n.left = list;
|
||||||
|
self.get_mut(right).left = i;
|
||||||
|
self.get_mut(list).right = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn remove_from_list(&mut self, i: Index) -> Option<Index> {
|
||||||
|
let left = self.get(i).left;
|
||||||
|
if left == i {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
let right = self.get(i).right;
|
||||||
|
|
||||||
|
self.get_mut(left).right = right;
|
||||||
|
self.get_mut(right).left = left;
|
||||||
|
|
||||||
|
Some(right)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn insert_tree(&mut self, i: Index) {
|
||||||
|
if let Some(min) = self.min {
|
||||||
|
self.add_to_list(min, i);
|
||||||
|
|
||||||
|
self.get_mut(i).parent = i;
|
||||||
|
|
||||||
|
if self.get(i).item < self.get(min).item {
|
||||||
|
self.min = Some(i);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let m = self.get_mut(i);
|
||||||
|
m.parent = i;
|
||||||
|
m.left = i;
|
||||||
|
m.right = i;
|
||||||
|
self.min = Some(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn union(&mut self, a: Index, b: Index) -> Index {
|
||||||
|
let min;
|
||||||
|
let max;
|
||||||
|
|
||||||
|
if self.get(a).item < self.get(b).item {
|
||||||
|
min = a;
|
||||||
|
max = b;
|
||||||
|
} else {
|
||||||
|
min = b;
|
||||||
|
max = a;
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.get(min).rank == 0 {
|
||||||
|
self.get_mut(min).child = max;
|
||||||
|
self.get_mut(min).rank = 1;
|
||||||
|
let m = self.get_mut(max);
|
||||||
|
m.parent = min;
|
||||||
|
m.left = max;
|
||||||
|
m.right = max;
|
||||||
|
} else {
|
||||||
|
self.get_mut(max).parent = min;
|
||||||
|
self.add_to_list(self.get(min).child, max);
|
||||||
|
self.get_mut(min).rank += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
min
|
||||||
|
}
|
||||||
|
fn insert_temp(&mut self, i: Index) {
|
||||||
|
let rank = self.get(i).rank;
|
||||||
|
if let Some(t) = self.temp[rank as usize].take() {
|
||||||
|
let m = self.union(t, i);
|
||||||
|
|
||||||
|
self.insert_temp(m);
|
||||||
|
} else {
|
||||||
|
self.temp[rank as usize] = Some(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn insert_data(&mut self, data: I) -> Index {
|
||||||
|
if let Some(i) = self.free.pop() {
|
||||||
|
self.data[i as usize] = Some(Node::new(data));
|
||||||
|
i
|
||||||
|
} else {
|
||||||
|
let i = self.data.len() as Index;
|
||||||
|
self.data.push(Some(Node::new(data)));
|
||||||
|
i
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get(&self, i: Index) -> &Node<I> {
|
||||||
|
self.data.get(i as usize).unwrap().as_ref().unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_mut(&mut self, i: Index) -> &mut Node<I> {
|
||||||
|
self.data.get_mut(i as usize).unwrap().as_mut().unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn remove_data(&mut self, i: Index) -> I {
|
||||||
|
let n = self.data[i as usize].take().unwrap();
|
||||||
|
|
||||||
|
self.free.push(i);
|
||||||
|
|
||||||
|
n.item
|
||||||
|
}
|
||||||
|
|
||||||
|
fn cut(&mut self, i: Index) {
|
||||||
|
if self.get(i).item < self.get(self.min.unwrap()).item {
|
||||||
|
self.min = Some(i);
|
||||||
|
}
|
||||||
|
let parent = self.get(i).parent;
|
||||||
|
if parent == i {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let c = self.remove_from_list(i);
|
||||||
|
if self.get(parent).rank > 1 {
|
||||||
|
self.get_mut(parent).child = c.unwrap();
|
||||||
|
}
|
||||||
|
self.get_mut(parent).rank -= 1;
|
||||||
|
|
||||||
|
self.add_to_list(self.min.unwrap(), i);
|
||||||
|
self.get_mut(i).mark = false;
|
||||||
|
self.get_mut(i).parent = i;
|
||||||
|
|
||||||
|
if self.get(parent).mark {
|
||||||
|
self.cut(parent);
|
||||||
|
} else {
|
||||||
|
self.get_mut(parent).mark = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<I> PriorityQueue<I> for FibonacciHeap<I>
|
||||||
|
where
|
||||||
|
I: PartialOrd,
|
||||||
{
|
{
|
||||||
type Handle = FibonacciHeapHandle;
|
type Handle = FibonacciHeapHandle;
|
||||||
|
|
||||||
fn new() -> Self {
|
fn new() -> Self {
|
||||||
todo!()
|
FibonacciHeap {
|
||||||
|
min: None,
|
||||||
|
data: Vec::new(),
|
||||||
|
free: Vec::new(),
|
||||||
|
temp: [None; 64],
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn insert(&mut self, item: T) -> Self::Handle {
|
fn insert(&mut self, item: I) -> Self::Handle {
|
||||||
let h = self.arena.insert(FibonacciHeapObject {
|
let i = self.insert_data(item);
|
||||||
left: ArenaKey::default(),
|
|
||||||
right: ArenaKey::default(),
|
|
||||||
parent: None,
|
|
||||||
child: None,
|
|
||||||
rank: 0,
|
|
||||||
marked: false,
|
|
||||||
data: item,
|
|
||||||
});
|
|
||||||
|
|
||||||
self.insert_tree(h);
|
self.insert_tree(i);
|
||||||
|
|
||||||
FibonacciHeapHandle(h)
|
FibonacciHeapHandle(i)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pop_min(&mut self) -> Option<T> {
|
fn pop_min(&mut self) -> Option<I> {
|
||||||
if let Some(k) = self.min.take() {
|
if let Some(min) = self.min.take() {
|
||||||
let o = self.arena.remove(k);
|
if self.get(min).rank != 0 {
|
||||||
|
let mut c = self.get(min).child;
|
||||||
if let Some(child) = o.child {
|
|
||||||
let mut p = child;
|
|
||||||
loop {
|
loop {
|
||||||
self.arena.get_mut(&p).parent = None;
|
let t = c;
|
||||||
self.arena.get_mut(&p).marked = false;
|
c = self.get(c).right;
|
||||||
let t = self.arena.get(&p).right;
|
self.add_to_list(min, t);
|
||||||
|
self.get_mut(t).parent = t;
|
||||||
self.insert_tree(p);
|
self.get_mut(t).mark = false;
|
||||||
|
if c == self.get(min).child {
|
||||||
p = t;
|
|
||||||
|
|
||||||
if p == child {
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if let Some(m) = self.remove_from_list(min) {
|
||||||
|
let mut c = m;
|
||||||
|
loop {
|
||||||
|
let t = c;
|
||||||
|
c = self.get(c).right;
|
||||||
|
self.insert_temp(t);
|
||||||
|
if c == m {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if o.left != o.right {
|
for i in 0..self.temp.len() {
|
||||||
self.arena.get_mut(&o.left).right = o.right;
|
if let Some(i) = self.temp[i].take() {
|
||||||
self.arena.get_mut(&o.right).left = o.left;
|
if let Some(min) = self.min {
|
||||||
self.update_min(o.left);
|
self.add_to_list(min, i);
|
||||||
|
if self.get(i).item < self.get(min).item {
|
||||||
|
self.min = Some(i);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
self.get_mut(i).left = i;
|
||||||
|
self.get_mut(i).right = i;
|
||||||
|
self.min = Some(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Some(o.data)
|
Some(self.remove_data(min))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn decrease_key(&mut self, _handle: &Self::Handle, _f: impl Fn(&mut T)) {
|
fn decrease_key(&mut self, handle: &Self::Handle, f: impl Fn(&mut I)) {
|
||||||
todo!()
|
let h = self.get_mut(handle.0);
|
||||||
}
|
f(&mut h.item);
|
||||||
}
|
self.cut(handle.0);
|
||||||
|
|
||||||
impl<T> FibonacciHeap<T>
|
|
||||||
where
|
|
||||||
T: std::cmp::Ord,
|
|
||||||
{
|
|
||||||
fn insert_tree(&mut self, h: ArenaKey) {
|
|
||||||
if let Some(h_min) = self.min {
|
|
||||||
let h_last = self.arena.get(&h_min).left;
|
|
||||||
|
|
||||||
self.arena.get_mut(&h_min).left = h;
|
|
||||||
|
|
||||||
self.arena.get_mut(&h).left = h_last;
|
|
||||||
self.arena.get_mut(&h).right = h_min;
|
|
||||||
|
|
||||||
self.arena.get_mut(&h_last).right = h;
|
|
||||||
|
|
||||||
if self.arena.get(&h).data < self.arena.get(&h_min).data {
|
|
||||||
self.min = Some(h)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
self.arena.get_mut(&h).left = h;
|
|
||||||
self.arena.get_mut(&h).right = h;
|
|
||||||
|
|
||||||
self.min = Some(h);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn update_min(&mut self, mut h: ArenaKey) {
|
|
||||||
let h_start = h;
|
|
||||||
|
|
||||||
loop {
|
|
||||||
let next_h = self.arena.get(&h).right;
|
|
||||||
|
|
||||||
self.add_to_update_rank(h);
|
|
||||||
|
|
||||||
h = next_h;
|
|
||||||
if h == h_start {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut prev = None;
|
|
||||||
// let mut start = None;
|
|
||||||
|
|
||||||
for h in &mut self.update_rank {
|
|
||||||
if let Some(h) = h.take() {
|
|
||||||
if let Some(p) = prev {
|
|
||||||
self.arena.get_mut(&h).left = p;
|
|
||||||
self.arena.get_mut(&p).right = h;
|
|
||||||
} else {
|
|
||||||
prev = Some(h);
|
|
||||||
// start = Some(h);
|
|
||||||
}
|
|
||||||
if let Some(m) = self.min {
|
|
||||||
if self.arena.get(&h).data < self.arena.get(&m).data {
|
|
||||||
self.min = Some(h);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
self.min = Some(h);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn add_to_update_rank(&mut self, h: ArenaKey) {
|
|
||||||
let rank = self.arena.get(&h).rank;
|
|
||||||
|
|
||||||
while self.update_rank.len() + 1 < rank {
|
|
||||||
self.update_rank.push(None)
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(o) = self.update_rank.get_mut(rank).unwrap().take() {
|
|
||||||
if let Some(child) = self.arena.get(&h).child {
|
|
||||||
let last = self.arena.get(&child).left;
|
|
||||||
|
|
||||||
self.arena.get_mut(&child).left = h;
|
|
||||||
self.arena.get_mut(&last).right = h;
|
|
||||||
|
|
||||||
self.arena.get_mut(&o).parent = Some(h);
|
|
||||||
self.arena.get_mut(&o).marked = false;
|
|
||||||
self.arena.get_mut(&o).left = last;
|
|
||||||
self.arena.get_mut(&o).right = child;
|
|
||||||
} else {
|
|
||||||
self.arena.get_mut(&h).child = Some(o);
|
|
||||||
|
|
||||||
self.arena.get_mut(&o).parent = Some(h);
|
|
||||||
self.arena.get_mut(&o).marked = false;
|
|
||||||
self.arena.get_mut(&o).left = o;
|
|
||||||
self.arena.get_mut(&o).right = o;
|
|
||||||
}
|
|
||||||
|
|
||||||
self.arena.get_mut(&h).rank += 1;
|
|
||||||
|
|
||||||
self.add_to_update_rank(h);
|
|
||||||
} else {
|
|
||||||
*self.update_rank.get_mut(rank).unwrap() = Some(h);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -100,6 +100,8 @@ where
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
use super::fibonacci_heap::FibonacciHeap;
|
||||||
|
use super::BinaryHeap;
|
||||||
use super::PriorityQueue;
|
use super::PriorityQueue;
|
||||||
|
|
||||||
macro_rules! test_generics {
|
macro_rules! test_generics {
|
||||||
|
|
@ -124,12 +126,14 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn $fun() {
|
fn $fun() {
|
||||||
super::$fun::<super::super::$gen<usize>>();
|
super::super::$fun::<super::super::$gen<usize>>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
test_generics!(basic_generic decrease_key_generic; BinaryHeap);
|
mod test_macro {
|
||||||
|
test_generics!(basic_generic decrease_key_generic; BinaryHeap FibonacciHeap);
|
||||||
|
}
|
||||||
|
|
||||||
fn basic_generic<T: PriorityQueue<usize>>() {
|
fn basic_generic<T: PriorityQueue<usize>>() {
|
||||||
let mut q = T::new();
|
let mut q = T::new();
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue