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 clap::Parser;
|
||||||
use factorio_blueprint::layout::GeneticAlgorithm;
|
use factorio_blueprint::{
|
||||||
|
common::visualize::Visualize,
|
||||||
|
layout::{genetic_algorithm2, GeneticAlgorithm, PathLayout},
|
||||||
|
};
|
||||||
use rand::{rngs::SmallRng, SeedableRng};
|
use rand::{rngs::SmallRng, SeedableRng};
|
||||||
|
|
||||||
#[derive(Debug, Parser)]
|
#[derive(Debug, Parser)]
|
||||||
|
|
@ -19,12 +22,24 @@ fn main() {
|
||||||
|
|
||||||
dbg!(&p);
|
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 {
|
// for i in 0..100 {
|
||||||
println!("Generatrion {i}");
|
// println!("Generatrion {i}");
|
||||||
g.generation(&mut rng);
|
// g.generation(&mut rng);
|
||||||
}
|
// }
|
||||||
|
|
||||||
// g.output_population();
|
// 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)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
pub(crate) struct Block {
|
pub(crate) struct Block {
|
||||||
pub(crate) size: Position,
|
pub(crate) size: Position,
|
||||||
|
|
@ -189,7 +231,7 @@ impl<'a> PathLayout<'a> {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn score(&self) -> usize {
|
pub fn score(&self) -> usize {
|
||||||
self.score
|
self.score
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -347,7 +389,7 @@ impl Layout<'_> {
|
||||||
loop {
|
loop {
|
||||||
let p = r.choose_weighted(rng, |i| i.1).unwrap();
|
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;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue