Add tracing support for layouting
This commit is contained in:
parent
b53d1e87bc
commit
cebdee4ec7
8 changed files with 254 additions and 53 deletions
|
|
@ -13,3 +13,4 @@ serde_json = "1.0.108"
|
|||
clap = { version = "4.4.8", features = ["derive"] }
|
||||
miette = { version = "7.2.0", features = ["fancy"] }
|
||||
serde_yaml = "0.9.34"
|
||||
tracing = "0.1.41"
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
use tracing::{Level, info, span, trace, warn};
|
||||
|
||||
use crate::{
|
||||
LayoutResult, Layouter,
|
||||
misc::{mutate, path_input_from_blocks_positions, score},
|
||||
|
|
@ -20,14 +22,23 @@ impl Layouter for GeneticAlgorithm {
|
|||
pathfinder: &P,
|
||||
rng: &mut R,
|
||||
) -> Option<crate::LayoutResult> {
|
||||
assert!(self.population_new > 0);
|
||||
assert!(self.population_new + self.population_keep <= self.population_size);
|
||||
let _complete_span = span!(Level::TRACE, "genetic_algorithm_v1").entered();
|
||||
|
||||
let mut population = Vec::new();
|
||||
|
||||
for _ in 0..self.population_size {
|
||||
loop {
|
||||
if let Some(l) = self.valid_layout.layout(input, pathfinder, rng) {
|
||||
let score = score(input, &l);
|
||||
population.push((l, score));
|
||||
break;
|
||||
{
|
||||
let _initial_generation_span = span!(Level::TRACE, "initial generation").entered();
|
||||
for i in 0..self.population_size {
|
||||
let _layout_span = span!(Level::TRACE, "layout", i).entered();
|
||||
loop {
|
||||
if let Some(l) = self.valid_layout.layout(input, pathfinder, rng) {
|
||||
let score = score(input, &l);
|
||||
population.push((l, score));
|
||||
break;
|
||||
}
|
||||
warn!("Unable to generate valid layout");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -36,38 +47,50 @@ impl Layouter for GeneticAlgorithm {
|
|||
let mut best_result = population[0].clone();
|
||||
|
||||
for g in 0..self.generations {
|
||||
for i in 0..(self.population_size - self.population_keep - self.population_new) {
|
||||
loop {
|
||||
let parent = &population[i % self.population_keep].0;
|
||||
if let Some(blocks) = mutate(input, parent, rng) {
|
||||
let (connections, map) =
|
||||
path_input_from_blocks_positions(input, parent.size, &blocks);
|
||||
let _generation_span = span!(Level::TRACE, "generation", g).entered();
|
||||
|
||||
if let Some(paths) =
|
||||
pathfinder.find_paths(factorio_pathfinding::PathInput {
|
||||
connections: &connections,
|
||||
map,
|
||||
})
|
||||
{
|
||||
let r = LayoutResult {
|
||||
positions: blocks,
|
||||
path_result: paths,
|
||||
size: parent.size,
|
||||
};
|
||||
let score = score(input, &r);
|
||||
population.push((r, score));
|
||||
break;
|
||||
{
|
||||
let _mutate_span = span!(Level::TRACE, "mutate").entered();
|
||||
for i in 0..(self.population_size - self.population_keep - self.population_new) {
|
||||
let _layout_span = span!(Level::TRACE, "layout", i).entered();
|
||||
loop {
|
||||
let parent = &population[i % self.population_keep].0;
|
||||
if let Some(blocks) = mutate(input, parent, rng) {
|
||||
let (connections, map) =
|
||||
path_input_from_blocks_positions(input, parent.size, &blocks);
|
||||
|
||||
if let Some(paths) =
|
||||
pathfinder.find_paths(factorio_pathfinding::PathInput {
|
||||
connections: &connections,
|
||||
map,
|
||||
})
|
||||
{
|
||||
let r = LayoutResult {
|
||||
positions: blocks,
|
||||
path_result: paths,
|
||||
size: parent.size,
|
||||
};
|
||||
let score = score(input, &r);
|
||||
population.push((r, score));
|
||||
break;
|
||||
}
|
||||
}
|
||||
trace!("unsuccesfull mutation");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for i in 0..self.population_new {
|
||||
loop {
|
||||
if let Some(l) = self.valid_layout.layout(input, pathfinder, rng) {
|
||||
let score = score(input, &l);
|
||||
population[self.population_size - self.population_new + i] = (l, score);
|
||||
break;
|
||||
{
|
||||
let _new_span = span!(Level::TRACE, "new").entered();
|
||||
for i in 0..self.population_new {
|
||||
let _layout_span = span!(Level::TRACE, "layout", i).entered();
|
||||
loop {
|
||||
if let Some(l) = self.valid_layout.layout(input, pathfinder, rng) {
|
||||
let score = score(input, &l);
|
||||
population[self.population_size - self.population_new + i] = (l, score);
|
||||
break;
|
||||
}
|
||||
warn!("Unable to generate valid layout");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -76,7 +99,7 @@ impl Layouter for GeneticAlgorithm {
|
|||
if population[0].1 < best_result.1 {
|
||||
best_result = population[0].clone();
|
||||
}
|
||||
eprintln!("completed generation {g}\nscore: {}", population[0].1);
|
||||
info!("completed generation {g} best score: {}", population[0].1);
|
||||
}
|
||||
|
||||
Some(best_result.0)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue