const INITIAL_Q: f64 = 1.0;
const ALPHA_INIT: f64 = 0.4;
const ALPHA_DECAY: f64 = 1e-6;
const ALPHA_MIN: f64 = 0.06;
#[derive(Debug, Clone)]
pub struct ConflictHistory {
weights: Vec<f64>,
last_conflict: Vec<u64>,
conflicts: u64,
alpha: f64,
enabled: bool,
}
impl ConflictHistory {
pub fn new(num_constraints: usize, enabled: bool) -> Self {
Self {
weights: vec![INITIAL_Q; num_constraints],
last_conflict: vec![0; num_constraints],
conflicts: 0,
alpha: ALPHA_INIT,
enabled,
}
}
pub fn from_seed(seed: &[f64], enabled: bool) -> Self {
Self {
weights: seed.to_vec(),
last_conflict: vec![0; seed.len()],
conflicts: 0,
alpha: ALPHA_INIT,
enabled,
}
}
#[inline]
pub fn weights(&self) -> &[f64] {
&self.weights
}
#[inline]
pub fn conflicts(&self) -> u64 {
self.conflicts
}
#[inline]
pub fn bump(&mut self, ci: usize) {
if !self.enabled {
self.conflicts += 1;
return;
}
self.conflicts += 1;
let since = self.conflicts - self.last_conflict[ci] + 1;
let r = 1.0 / since as f64;
self.weights[ci] = (1.0 - self.alpha) * self.weights[ci] + self.alpha * r;
self.last_conflict[ci] = self.conflicts;
if self.alpha > ALPHA_MIN {
self.alpha = (self.alpha - ALPHA_DECAY).max(ALPHA_MIN);
}
}
}