59 lines
1.6 KiB
Rust
59 lines
1.6 KiB
Rust
use num_integer::Integer;
|
|
use rand::prelude::Rng;
|
|
use crate::system::{GriddedPosition, grid::Position};
|
|
|
|
pub trait Walker<P: GriddedPosition> {
|
|
fn walk<R: Rng>(&self, rng: &mut R, position: &P) -> P;
|
|
}
|
|
|
|
pub struct LocalRandomWalker;
|
|
|
|
impl<Position: GriddedPosition> Walker<Position> for LocalRandomWalker {
|
|
fn walk<R: Rng>(&self, rng: &mut R, position: &Position) -> Position {
|
|
position.neighbour(rng.gen_range(0u32..Position::NEIGHBOURS))
|
|
}
|
|
}
|
|
|
|
mod test {
|
|
use rand::rngs::SmallRng;
|
|
use rand::{SeedableRng, thread_rng};
|
|
use crate::system::{GriddedPosition, grid::Position};
|
|
use crate::system::walker::{LocalRandomWalker, Walker};
|
|
|
|
#[test]
|
|
fn uniformity() {
|
|
let walker = LocalRandomWalker::new();
|
|
let mut rng = SmallRng::from_rng(thread_rng()).unwrap();
|
|
let mut results: Vec<Position> = vec![];
|
|
|
|
let origin = &Position::zero();
|
|
|
|
let x: u32 = (1_000000_000);
|
|
for i in 0..x {
|
|
results.push(walker.walk(&mut rng, origin));
|
|
}
|
|
|
|
let a = results
|
|
.iter()
|
|
.filter(|a| **a == Position(0, 1))
|
|
.count();
|
|
|
|
let b = results
|
|
.iter()
|
|
.filter(|a| **a == Position(0, -1))
|
|
.count();
|
|
|
|
let c = results
|
|
.iter()
|
|
.filter(|a| **a == Position(1, 0))
|
|
.count();
|
|
|
|
let d = results
|
|
.iter()
|
|
.filter(|a| **a == Position(-1, 0))
|
|
.count();
|
|
|
|
println!("{} {} {} {}", a as f32 / x as f32, b as f32 / x as f32, c as f32 / x as f32, d as f32 / x as f32);
|
|
}
|
|
}
|