#[allow(unused_imports)]
use crate::prelude::*;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum RephasingStrategy {
Original,
Inverted,
Random,
False,
True,
Best,
Walk,
}
#[derive(Debug, Clone, Default)]
pub struct RephasingStats {
pub rephase_count: usize,
pub strategy_counts: [usize; 7],
pub last_rephase_conflicts: u64,
}
impl RephasingStats {
pub fn display(&self) {
println!("Rephasing Statistics:");
println!(" Total rephases: {}", self.rephase_count);
println!(" Strategy usage:");
println!(" Original: {}", self.strategy_counts[0]);
println!(" Inverted: {}", self.strategy_counts[1]);
println!(" Random: {}", self.strategy_counts[2]);
println!(" False: {}", self.strategy_counts[3]);
println!(" True: {}", self.strategy_counts[4]);
println!(" Best: {}", self.strategy_counts[5]);
println!(" Walk: {}", self.strategy_counts[6]);
}
}
#[derive(Debug)]
pub struct RephasingManager {
interval: u64,
initial_interval: u64,
interval_multiplier: f64,
max_interval: u64,
best_assignment: Vec<bool>,
stats: RephasingStats,
rng_state: u64,
}
impl Default for RephasingManager {
fn default() -> Self {
Self::new()
}
}
impl RephasingManager {
#[must_use]
pub fn new() -> Self {
Self {
interval: 1000,
initial_interval: 1000,
interval_multiplier: 1.1,
max_interval: 1_000_000,
best_assignment: Vec::new(),
stats: RephasingStats::default(),
rng_state: 0x853c_49e6_748f_ea9b, }
}
#[must_use]
pub fn with_interval(initial: u64, multiplier: f64, max: u64) -> Self {
Self {
interval: initial,
initial_interval: initial,
interval_multiplier: multiplier,
max_interval: max,
best_assignment: Vec::new(),
stats: RephasingStats::default(),
rng_state: 0x853c_49e6_748f_ea9b,
}
}
#[must_use]
pub fn stats(&self) -> &RephasingStats {
&self.stats
}
#[must_use]
pub fn should_rephase(&self, conflicts: u64) -> bool {
if self.stats.last_rephase_conflicts == 0 {
return conflicts >= self.interval;
}
conflicts - self.stats.last_rephase_conflicts >= self.interval
}
pub fn update_best_assignment(&mut self, assignment: &[bool]) {
self.best_assignment = assignment.to_vec();
}
pub fn rephase(
&mut self,
strategy: RephasingStrategy,
num_vars: usize,
current_phases: &[bool],
conflicts: u64,
) -> Vec<bool> {
self.stats.rephase_count += 1;
self.stats.last_rephase_conflicts = conflicts;
let strategy_idx = match strategy {
RephasingStrategy::Original => 0,
RephasingStrategy::Inverted => 1,
RephasingStrategy::Random => 2,
RephasingStrategy::False => 3,
RephasingStrategy::True => 4,
RephasingStrategy::Best => 5,
RephasingStrategy::Walk => 6,
};
self.stats.strategy_counts[strategy_idx] += 1;
self.interval =
((self.interval as f64 * self.interval_multiplier) as u64).min(self.max_interval);
match strategy {
RephasingStrategy::Original => {
vec![false; num_vars]
}
RephasingStrategy::Inverted => {
current_phases.iter().map(|&p| !p).collect()
}
RephasingStrategy::Random => {
(0..num_vars).map(|_| self.random_bool()).collect()
}
RephasingStrategy::False => {
vec![false; num_vars]
}
RephasingStrategy::True => {
vec![true; num_vars]
}
RephasingStrategy::Best => {
if self.best_assignment.len() >= num_vars {
self.best_assignment[..num_vars].to_vec()
} else {
current_phases.to_vec()
}
}
RephasingStrategy::Walk => {
(0..num_vars)
.map(|i| {
if self.random_bool() {
current_phases.get(i).copied().unwrap_or(false)
} else {
self.random_bool()
}
})
.collect()
}
}
}
#[must_use]
pub fn next_strategy(&self) -> RephasingStrategy {
let cycle = self.stats.rephase_count % 5;
match cycle {
0 => RephasingStrategy::Original,
1 => RephasingStrategy::Inverted,
2 => RephasingStrategy::Random,
3 => RephasingStrategy::False,
_ => RephasingStrategy::Best,
}
}
pub fn reset(&mut self) {
self.interval = self.initial_interval;
self.stats = RephasingStats::default();
}
fn random_u64(&mut self) -> u64 {
self.rng_state ^= self.rng_state << 13;
self.rng_state ^= self.rng_state >> 7;
self.rng_state ^= self.rng_state << 17;
self.rng_state
}
fn random_bool(&mut self) -> bool {
(self.random_u64() & 1) == 1
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_rephasing_manager_creation() {
let manager = RephasingManager::new();
assert_eq!(manager.stats.rephase_count, 0);
assert_eq!(manager.interval, 1000);
}
#[test]
fn test_should_rephase() {
let manager = RephasingManager::new();
assert!(!manager.should_rephase(500));
assert!(manager.should_rephase(1000));
assert!(manager.should_rephase(1500));
}
#[test]
fn test_rephase_original() {
let mut manager = RephasingManager::new();
let current = vec![true, false, true, false];
let result = manager.rephase(RephasingStrategy::Original, 4, ¤t, 1000);
assert_eq!(result, vec![false, false, false, false]);
assert_eq!(manager.stats.rephase_count, 1);
}
#[test]
fn test_rephase_inverted() {
let mut manager = RephasingManager::new();
let current = vec![true, false, true, false];
let result = manager.rephase(RephasingStrategy::Inverted, 4, ¤t, 1000);
assert_eq!(result, vec![false, true, false, true]);
}
#[test]
fn test_rephase_false() {
let mut manager = RephasingManager::new();
let current = vec![true, false, true, false];
let result = manager.rephase(RephasingStrategy::False, 4, ¤t, 1000);
assert_eq!(result, vec![false, false, false, false]);
}
#[test]
fn test_rephase_true() {
let mut manager = RephasingManager::new();
let current = vec![true, false, true, false];
let result = manager.rephase(RephasingStrategy::True, 4, ¤t, 1000);
assert_eq!(result, vec![true, true, true, true]);
}
#[test]
fn test_rephase_best() {
let mut manager = RephasingManager::new();
manager.update_best_assignment(&[true, true, false, false]);
let current = vec![false, false, false, false];
let result = manager.rephase(RephasingStrategy::Best, 4, ¤t, 1000);
assert_eq!(result, vec![true, true, false, false]);
}
#[test]
fn test_next_strategy() {
let mut manager = RephasingManager::new();
assert_eq!(manager.next_strategy(), RephasingStrategy::Original);
manager.rephase(RephasingStrategy::Original, 1, &[false], 1000);
assert_eq!(manager.next_strategy(), RephasingStrategy::Inverted);
manager.rephase(RephasingStrategy::Inverted, 1, &[false], 2000);
assert_eq!(manager.next_strategy(), RephasingStrategy::Random);
}
#[test]
fn test_interval_increase() {
let mut manager = RephasingManager::with_interval(100, 2.0, 10000);
manager.rephase(RephasingStrategy::Original, 1, &[false], 100);
assert_eq!(manager.interval, 200);
manager.rephase(RephasingStrategy::Original, 1, &[false], 300);
assert_eq!(manager.interval, 400);
}
#[test]
fn test_stats_display() {
let mut manager = RephasingManager::new();
manager.rephase(RephasingStrategy::Original, 1, &[false], 1000);
manager.rephase(RephasingStrategy::Inverted, 1, &[false], 2000);
let stats = manager.stats();
assert_eq!(stats.rephase_count, 2);
assert_eq!(stats.strategy_counts[0], 1); assert_eq!(stats.strategy_counts[1], 1); }
}