Add second genetic algorithm.
This commit is contained in:
parent
29450a1c65
commit
a52816834f
2 changed files with 65 additions and 8 deletions
|
|
@ -1,5 +1,8 @@
|
|||
use clap::Parser;
|
||||
use factorio_blueprint::layout::GeneticAlgorithm;
|
||||
use factorio_blueprint::{
|
||||
common::visualize::Visualize,
|
||||
layout::{genetic_algorithm2, GeneticAlgorithm, PathLayout},
|
||||
};
|
||||
use rand::{rngs::SmallRng, SeedableRng};
|
||||
|
||||
#[derive(Debug, Parser)]
|
||||
|
|
@ -19,12 +22,24 @@ fn main() {
|
|||
|
||||
dbg!(&p);
|
||||
|
||||
let mut g = GeneticAlgorithm::new(&p, 20, 2, 0, &mut rng);
|
||||
// let mut g = GeneticAlgorithm::new(&p, 20, 2, 0, &mut rng);
|
||||
|
||||
for i in 0..100 {
|
||||
println!("Generatrion {i}");
|
||||
g.generation(&mut rng);
|
||||
}
|
||||
// for i in 0..100 {
|
||||
// println!("Generatrion {i}");
|
||||
// g.generation(&mut rng);
|
||||
// }
|
||||
|
||||
// g.output_population();
|
||||
|
||||
let mut m: Option<PathLayout> = None;
|
||||
for _ in 0..20 {
|
||||
let g = genetic_algorithm2(&p, 10, 320, &mut rng);
|
||||
|
||||
g.print_visualization();
|
||||
if m.as_ref().is_none_or(|m| g.score() < m.score()) {
|
||||
m = Some(g);
|
||||
}
|
||||
}
|
||||
|
||||
m.unwrap().print_visualization();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -105,6 +105,48 @@ impl<'a> GeneticAlgorithm<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn genetic_algorithm2<'a, R: Rng + ?Sized>(
|
||||
problem: &'a Problem,
|
||||
new_layouts: usize,
|
||||
mutation_timeout: usize,
|
||||
rng: &'_ mut R,
|
||||
) -> PathLayout<'a> {
|
||||
let mut m = (0..new_layouts)
|
||||
.map(|_| valid_path_layout(problem, rng))
|
||||
.min_by_key(|p| p.score())
|
||||
.unwrap();
|
||||
|
||||
m.print_visualization();
|
||||
|
||||
let mut last_improvement = 0;
|
||||
let mut count = 0;
|
||||
|
||||
while last_improvement < mutation_timeout {
|
||||
last_improvement += 1;
|
||||
count += 1;
|
||||
if let Some(p) = PathLayout::new(m.layout.mutate(rng)) {
|
||||
if p.score() < m.score() {
|
||||
m = p;
|
||||
println!("Step: {count}");
|
||||
m.print_visualization();
|
||||
last_improvement = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
m
|
||||
}
|
||||
|
||||
pub fn valid_path_layout<'a, R: Rng + ?Sized>(
|
||||
problem: &'a Problem,
|
||||
rng: &'_ mut R,
|
||||
) -> PathLayout<'a> {
|
||||
loop {
|
||||
if let Some(p) = PathLayout::new(Layout::new(problem, rng)) {
|
||||
return p;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub(crate) struct Block {
|
||||
pub(crate) size: Position,
|
||||
|
|
@ -189,7 +231,7 @@ impl<'a> PathLayout<'a> {
|
|||
})
|
||||
}
|
||||
|
||||
fn score(&self) -> usize {
|
||||
pub fn score(&self) -> usize {
|
||||
self.score
|
||||
}
|
||||
}
|
||||
|
|
@ -347,7 +389,7 @@ impl Layout<'_> {
|
|||
loop {
|
||||
let p = r.choose_weighted(rng, |i| i.1).unwrap();
|
||||
|
||||
if p.0(&mut s, rng) && rng.gen_bool(0.2) {
|
||||
if p.0(&mut s, rng) && rng.gen_bool(0.05) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue