vectorize mutation
This commit is contained in:
parent
2e1f524476
commit
89b3e6e983
|
@ -1,6 +1,6 @@
|
||||||
# This file is automatically @generated by Cargo.
|
# This file is automatically @generated by Cargo.
|
||||||
# It is not intended for manual editing.
|
# It is not intended for manual editing.
|
||||||
version = 3
|
version = 4
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "anstream"
|
name = "anstream"
|
||||||
|
@ -53,7 +53,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bano"
|
name = "bano"
|
||||||
version = "0.1.0"
|
version = "0.2.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap",
|
"clap",
|
||||||
"rand",
|
"rand",
|
||||||
|
|
|
@ -1,9 +1,12 @@
|
||||||
[package]
|
[package]
|
||||||
name = "bano"
|
name = "bano"
|
||||||
version = "0.1.0"
|
version = "0.2.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
clap = { version = "4.5.19", features = ["derive"] }
|
clap = { version = "4.5.19", features = ["derive"] }
|
||||||
rand = "0.8.5"
|
rand = "0.8.5"
|
||||||
rayon = "1.10.0"
|
rayon = "1.10.0"
|
||||||
|
|
||||||
|
[features]
|
||||||
|
simd = []
|
||||||
|
|
62
src/lib.rs
62
src/lib.rs
|
@ -1,5 +1,8 @@
|
||||||
|
#![cfg_attr(feature = "simd", feature(portable_simd))]
|
||||||
use rayon::prelude::*;
|
use rayon::prelude::*;
|
||||||
use std::ops::{Add, Index, IndexMut, Sub};
|
use std::ops::{Add, Index, IndexMut, Sub};
|
||||||
|
#[cfg(feature = "simd")]
|
||||||
|
use std::simd::{u32x8, Simd};
|
||||||
|
|
||||||
pub enum ReadError {
|
pub enum ReadError {
|
||||||
BadSymbol,
|
BadSymbol,
|
||||||
|
@ -15,14 +18,6 @@ pub enum Error {
|
||||||
|
|
||||||
type Result<T> = std::result::Result<T, Error>;
|
type Result<T> = std::result::Result<T, Error>;
|
||||||
|
|
||||||
#[derive(PartialEq, Copy, Clone)]
|
|
||||||
enum Direction {
|
|
||||||
U,
|
|
||||||
D,
|
|
||||||
L,
|
|
||||||
R,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(PartialEq, Copy, Clone)]
|
#[derive(PartialEq, Copy, Clone)]
|
||||||
enum Cell {
|
enum Cell {
|
||||||
Wall,
|
Wall,
|
||||||
|
@ -249,13 +244,8 @@ impl State {
|
||||||
Ok((false, false))
|
Ok((false, false))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn move_dir(&mut self, dir: Direction) -> Result<(bool, bool)> {
|
fn move_dir(&mut self, dir: u32) -> Result<(bool, bool)> {
|
||||||
match dir {
|
self.move_pos(Self::DIR_POS[dir as usize])
|
||||||
Direction::U => self.move_pos(Self::DIR_POS[0]),
|
|
||||||
Direction::D => self.move_pos(Self::DIR_POS[1]),
|
|
||||||
Direction::L => self.move_pos(Self::DIR_POS[2]),
|
|
||||||
Direction::R => self.move_pos(Self::DIR_POS[3]),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_box(&self, pos: Pos, bt: bool) -> bool {
|
fn test_box(&self, pos: Pos, bt: bool) -> bool {
|
||||||
|
@ -337,7 +327,7 @@ impl State {
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
struct Agent {
|
struct Agent {
|
||||||
state: State,
|
state: State,
|
||||||
dna: Vec<Direction>,
|
dna: Vec<u32>,
|
||||||
score: f32,
|
score: f32,
|
||||||
dir: usize,
|
dir: usize,
|
||||||
goal: Solution,
|
goal: Solution,
|
||||||
|
@ -357,14 +347,14 @@ impl Agent {
|
||||||
const INACTIVE_PENALTY: f32 = 0.0010;
|
const INACTIVE_PENALTY: f32 = 0.0010;
|
||||||
const BOX_DIFF: f32 = 1024.0;
|
const BOX_DIFF: f32 = 1024.0;
|
||||||
|
|
||||||
const DIR_TABLE: &'static [Direction] =
|
const DIR_TABLE: &'static [u32] = &[0, 1, 2, 3];
|
||||||
&[Direction::U, Direction::D, Direction::L, Direction::R];
|
const DIR_STR: &[&str] = &["U", "D", "L", "R"];
|
||||||
|
|
||||||
fn chromo() -> Direction {
|
fn chromo() -> u32 {
|
||||||
Self::DIR_TABLE[rnd!(Self::DIR_TABLE.len())]
|
Self::DIR_TABLE[rnd!(Self::DIR_TABLE.len())]
|
||||||
}
|
}
|
||||||
|
|
||||||
fn with_dna(state: State, dna: Vec<Direction>) -> Self {
|
fn with_dna(state: State, dna: Vec<u32>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
state,
|
state,
|
||||||
dna,
|
dna,
|
||||||
|
@ -375,7 +365,7 @@ impl Agent {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new(state: State, size: usize) -> Self {
|
fn new(state: State, size: usize) -> Self {
|
||||||
let dna: Vec<Direction> = (0..size).map(|_| Self::chromo()).collect();
|
let dna: Vec<u32> = (0..size).map(|_| Self::chromo()).collect();
|
||||||
|
|
||||||
Self::with_dna(state, dna)
|
Self::with_dna(state, dna)
|
||||||
}
|
}
|
||||||
|
@ -386,6 +376,29 @@ impl Agent {
|
||||||
self.dna[..ratio].copy_from_slice(&seed.dna[..ratio]);
|
self.dna[..ratio].copy_from_slice(&seed.dna[..ratio]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "simd")]
|
||||||
|
fn mutate(&mut self, max: usize) {
|
||||||
|
let len = self.dna.len();
|
||||||
|
let (ni, nd) = (rnd!(max) + 8, rnd!(len));
|
||||||
|
|
||||||
|
for x in 0..ni / 8 {
|
||||||
|
let d = u32x8::from_array([Agent::chromo(); 8]);
|
||||||
|
let si = Simd::from_array([
|
||||||
|
nd + x,
|
||||||
|
nd + x + 1,
|
||||||
|
nd + x + 2,
|
||||||
|
nd + x + 3,
|
||||||
|
nd + x + 4,
|
||||||
|
nd + x + 5,
|
||||||
|
nd + x + 6,
|
||||||
|
nd + x + 7,
|
||||||
|
]);
|
||||||
|
|
||||||
|
d.scatter(&mut self.dna, si);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "simd"))]
|
||||||
fn mutate(&mut self, max: usize) {
|
fn mutate(&mut self, max: usize) {
|
||||||
let len = self.dna.len();
|
let len = self.dna.len();
|
||||||
let (ni, nd) = (rnd!(max), rnd!(len));
|
let (ni, nd) = (rnd!(max), rnd!(len));
|
||||||
|
@ -443,12 +456,7 @@ impl Agent {
|
||||||
|
|
||||||
fn solution(&self) -> String {
|
fn solution(&self) -> String {
|
||||||
(0..self.dir)
|
(0..self.dir)
|
||||||
.map(|i| match self.dna[i] {
|
.map(|i| Self::DIR_STR[self.dna[i] as usize])
|
||||||
Direction::U => "U",
|
|
||||||
Direction::D => "D",
|
|
||||||
Direction::L => "L",
|
|
||||||
Direction::R => "R",
|
|
||||||
})
|
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue