use crate::graph::Graph;
use crate::Node;
use crate::traits::*;
use rand::seq::SliceRandom;
use crate::iter::{NContainedIterMut, ContainedIterMut};
use crate::graph::NodeContainer;
#[cfg(feature = "serde_support")]
use serde::{Serialize, Deserialize};
#[derive(Debug)]
pub struct ErStepM{
pub(crate) removed: (u32, u32),
pub(crate) i_removed: usize,
pub(crate) inserted: (u32, u32),
pub(crate) i_inserted: usize,
}
impl ErStepM{
fn invert(&mut self){
std::mem::swap(
&mut self.removed,
&mut self.inserted
);
}
}
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde_support", derive(Serialize, Deserialize))]
pub struct ErEnsembleM<T: Node, R: rand::Rng>
where T: Node,
R: rand::Rng
{
graph: Graph<T>,
m: usize,
rng: R,
all_edges: Vec<(u32, u32)>,
possible_edges: Vec<(u32, u32)>,
current_edges: Vec<(u32, u32)>,
}
impl<T, R> HasRng<R> for ErEnsembleM<T, R>
where T: Node,
R: rand::Rng,
{
fn rng(&mut self) -> &mut R {
&mut self.rng
}
fn swap_rng(&mut self, mut rng: R) -> R {
std::mem::swap(&mut self.rng, &mut rng);
rng
}
}
impl<T, R> SimpleSample for ErEnsembleM<T, R>
where T: Node + SerdeStateConform,
R: rand::Rng,
{
fn randomize(&mut self){
self.graph.clear_edges();
self.shuffle_all_edges();
self.current_edges
.copy_from_slice(&self.all_edges[..self.m]);
for edge in self.current_edges.iter()
{
self.graph
.add_edge(edge.0, edge.1)
.unwrap();
}
self.possible_edges
.copy_from_slice(&self.all_edges[self.m..]);
}
}
impl <T, R> MarkovChain<ErStepM, ErStepM> for ErEnsembleM<T, R>
where T: Node + SerdeStateConform,
R: rand::Rng,
{
fn undo_step(&mut self, mut step: ErStepM) -> ErStepM {
step.invert();
self.step(&step);
step
}
fn undo_step_quiet(&mut self, mut step: ErStepM) -> (){
step.invert();
self.step(&step);
}
fn m_step(&mut self) -> ErStepM{
let index_current = self.rng.gen_range(0, self.current_edges.len());
let index_possible = self.rng.gen_range(0, self.possible_edges.len());
let step = ErStepM{
removed: self.current_edges[index_current],
i_removed: index_current,
inserted: self.possible_edges[index_possible],
i_inserted: index_possible
};
self.step(&step);
step
}
}
impl<T, R> ErEnsembleM<T, R>
where T: Node + SerdeStateConform,
R: rand::Rng
{
fn step(&mut self, step: &ErStepM){
self.graph
.remove_edge(step.removed.0, step.removed.1)
.unwrap();
self.graph
.add_edge(step.inserted.0, step.inserted.1)
.unwrap();
std::mem::swap(
&mut self.current_edges[step.i_removed],
&mut self.possible_edges[step.i_inserted]
);
}
pub fn new(n: u32, m: usize, rng: R) -> Self {
let graph: Graph<T> = Graph::new(n);
let n_usize = n as usize;
let p_edges = (n_usize * (n_usize - 1)) / 2;
assert!(
m <= p_edges,
format!(
"A complete graph with {} vertices has {} edges. \
You requested {} edges, i.e., to many. Panic at function `new` of struct {}",
n,
p_edges,
m,
std::any::type_name::<Self>(),
)
);
let mut vec = Vec::with_capacity(p_edges);
for i in 0..n {
for j in i+1..n {
vec.push((i, j));
}
}
let mut e = ErEnsembleM {
graph,
m,
rng,
all_edges: vec,
possible_edges: vec![(0, 0); p_edges - m], current_edges: vec![(0, 0); m], };
e.randomize();
e
}
fn graph_mut(&mut self) -> &mut Graph<T> {
&mut self.graph
}
pub fn get_m(&self) -> usize {
self.m
}
fn shuffle_all_edges(&mut self) -> () {
self.all_edges
.shuffle(&mut self.rng);
}
pub fn sort_adj(&mut self) {
self.graph_mut().sort_adj();
}
}
impl<'a, T, R> GraphIteratorsMut<'a, T, Graph<T>, NodeContainer<T>> for ErEnsembleM<T, R>
where T: Node + SerdeStateConform,
R: rand::Rng
{
fn contained_iter_neighbors_mut(&'a mut self, index: usize) ->
NContainedIterMut<'a, T, NodeContainer<T>>
{
self.graph.contained_iter_neighbors_mut(index)
}
fn contained_iter_mut(&'a mut self) -> ContainedIterMut<'a, T, NodeContainer<T>> {
self.graph.contained_iter_mut()
}
}
impl<T, R> WithGraph<T, Graph<T>> for ErEnsembleM<T, R>
where T: Node + SerdeStateConform,
R: rand::Rng
{
fn at(&self, index: usize) -> &T{
self.graph.at(index)
}
fn at_mut(&mut self, index: usize) -> &mut T{
self.graph.at_mut(index)
}
fn graph(&self) -> &Graph<T> {
&self.graph
}
}