use super::deterministic::{ElimPolicy, eliminate_greedy};
use super::*;
#[derive(Eq, PartialEq)]
pub(super) struct DegEntry {
pub key: (Reverse<u64>, Reverse<u32>, Reverse<u32>),
pub vertex: u32,
pub degree: u64,
}
impl DegEntry {
pub(super) fn new(degree: u64, salt: u32, v: u32) -> Self {
DegEntry {
key: (Reverse(degree), Reverse(salt), Reverse(v)),
vertex: v,
degree,
}
}
}
ord_by_key!(DegEntry);
impl ElimEntry for DegEntry {
fn vertex(&self) -> u32 {
self.vertex
}
fn snapshot(&self) -> u64 {
self.degree
}
}
struct MinDegree<'a> {
heap: BinaryHeap<DegEntry>,
salt: &'a [u32],
}
impl ElimPolicy for MinDegree<'_> {
type Entry = DegEntry;
const CHEAP_MODE: bool = true;
const MAINTAIN_BITSET: bool = false;
const ZERO_SCORE_IS_SIMPLICIAL: bool = false;
fn heap(&mut self) -> &mut BinaryHeap<DegEntry> {
&mut self.heap
}
fn push(&mut self, _: &EliminationGraph, v: u32, score: u64) {
self.heap
.push(DegEntry::new(score, self.salt[v as usize], v));
}
fn live_score(&mut self, graph: &EliminationGraph, v: u32) -> u64 {
graph.degree(v) as u64
}
}
pub(crate) fn eliminate_min_degree(
graph: &mut EliminationGraph,
salt: &[u32],
sink: ElimSink<'_>,
stop: ElimStop,
) -> ElimExit {
let n = graph.len();
assert_eq!(salt.len(), n);
let mut policy = MinDegree {
heap: BinaryHeap::with_capacity(n),
salt,
};
eliminate_greedy(&mut policy, graph, sink, stop)
}