use std::cmp::Ordering;
use crate::{StateRanking, SubProblemRanking, SubProblem};
#[derive(Debug, Clone, Copy)]
pub struct MaxUB<'a, O: StateRanking>(&'a O);
impl <'a, O: StateRanking> MaxUB<'a, O> {
pub fn new(x: &'a O) -> Self {
Self(x)
}
}
impl<O: StateRanking> SubProblemRanking for MaxUB<'_, O> {
type State = O::State;
fn compare(&self, l: &SubProblem<O::State>, r: &SubProblem<O::State>) -> Ordering {
l.ub.cmp(&r.ub)
.then_with(|| l.value.cmp(&r.value))
.then_with(|| self.0.compare(&l.state, &r.state))
}
}
#[cfg(test)]
#[allow(clippy::many_single_char_names)]
mod test_maxub {
use std::cmp::Ordering;
use std::sync::Arc;
use binary_heap_plus::BinaryHeap;
use crate::*;
use crate::implementation::heuristics::subproblem_ranking::MaxUB;
struct CharRanking;
impl StateRanking for CharRanking {
type State = char;
fn compare(&self, a: &Self::State, b: &Self::State) -> Ordering {
a.cmp(b)
}
}
#[test]
fn example() {
let a = SubProblem {state: Arc::new('a'), value: 42, ub: 300, path: vec![]};
let b = SubProblem {state: Arc::new('b'), value: 2, ub: 100, path: vec![]};
let c = SubProblem {state: Arc::new('c'), value: 24, ub: 150, path: vec![]};
let d = SubProblem {state: Arc::new('d'), value: 13, ub: 60, path: vec![]};
let e = SubProblem {state: Arc::new('e'), value: 65, ub: 700, path: vec![]};
let f = SubProblem {state: Arc::new('f'), value: 19, ub: 100, path: vec![]};
let nodes = vec![a, b, c, d, e, f];
let mut priority_q = BinaryHeap::from_vec_cmp(nodes, CompareSubProblem::new(MaxUB::new(&CharRanking)));
assert_eq!('e', *priority_q.pop().unwrap().state); assert_eq!('a', *priority_q.pop().unwrap().state); assert_eq!('c', *priority_q.pop().unwrap().state); assert_eq!('f', *priority_q.pop().unwrap().state); assert_eq!('b', *priority_q.pop().unwrap().state); assert_eq!('d', *priority_q.pop().unwrap().state); }
#[test]
fn gt_because_ub() {
let a = SubProblem {state: Arc::new('a'), value: 42, ub: 300, path: vec![]};
let b = SubProblem {state: Arc::new('b'), value: 42, ub: 100, path: vec![]};
let cmp = MaxUB::new(&CharRanking);
assert_eq!(Ordering::Greater, cmp.compare(&a, &b));
}
#[test]
fn gt_because_lplen() {
let a = SubProblem {state: Arc::new('a'), value: 42, ub: 300, path: vec![]};
let b = SubProblem {state: Arc::new('b'), value: 2, ub: 300, path: vec![]};
let cmp = MaxUB::new(&CharRanking);
assert_eq!(Ordering::Greater, cmp.compare(&a, &b));
}
#[test]
fn lt_because_ub() {
let a = SubProblem {state: Arc::new('a'), value: 42, ub: 300, path: vec![]};
let b = SubProblem {state: Arc::new('b'), value: 42, ub: 100, path: vec![]};
let cmp = MaxUB::new(&CharRanking);
assert_eq!(Ordering::Less, cmp.compare(&b, &a));
}
#[test]
fn lt_because_lplen() {
let a = SubProblem {state: Arc::new('a'), value: 42, ub: 300, path: vec![]};
let b = SubProblem {state: Arc::new('b'), value: 2, ub: 300, path: vec![]};
let cmp = MaxUB::new(&CharRanking);
assert_eq!(Ordering::Less, cmp.compare(&b, &a));
}
#[test]
fn lt_because_state() {
let a = SubProblem {state: Arc::new('a'), value: 42, ub: 300, path: vec![]};
let b = SubProblem {state: Arc::new('b'), value: 42, ub: 300, path: vec![]};
let cmp = MaxUB::new(&CharRanking);
assert_eq!(Ordering::Less, cmp.compare(&a, &b));
}
#[test]
fn eq_self() {
let a = SubProblem {state: Arc::new('a'), value: 42, ub: 300, path: vec![]};
let cmp = MaxUB::new(&CharRanking);
assert_eq!(Ordering::Equal, cmp.compare(&a, &a));
}
}