Add beltfinding timeout and debugging.
This commit is contained in:
parent
f20a1841c9
commit
79c8b0c710
13 changed files with 278 additions and 53 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -1,3 +1,4 @@
|
||||||
/target
|
/target
|
||||||
flamegraph.svg
|
flamegraph.svg
|
||||||
perf.data*
|
perf.data*
|
||||||
|
out
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ macro_rules! bench_bruteforce {
|
||||||
b.iter(|| {
|
b.iter(|| {
|
||||||
let mut b = p.clone();
|
let mut b = p.clone();
|
||||||
|
|
||||||
while b.next_finish_state() {}
|
while b.next_finish_state(None) {}
|
||||||
|
|
||||||
b.solution_count()
|
b.solution_count()
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,7 @@ fn main() {
|
||||||
|
|
||||||
match args.mode {
|
match args.mode {
|
||||||
Mode::Solutions => {
|
Mode::Solutions => {
|
||||||
while b.next_finish_state() {
|
while b.next_finish_state(None) {
|
||||||
println!("{}\n{}\n{}", b.count(), b.solution_count(), b.cost());
|
println!("{}\n{}\n{}", b.count(), b.solution_count(), b.cost());
|
||||||
b.print();
|
b.print();
|
||||||
}
|
}
|
||||||
|
|
@ -64,7 +64,7 @@ fn main() {
|
||||||
println!("Solutions: {}\nStates: {}", b.solution_count(), b.count());
|
println!("Solutions: {}\nStates: {}", b.solution_count(), b.count());
|
||||||
}
|
}
|
||||||
Mode::Statistics => {
|
Mode::Statistics => {
|
||||||
while b.next_finish_state() {}
|
while b.next_finish_state(None) {}
|
||||||
|
|
||||||
println!("Solutions: {}\nStates: {}", b.solution_count(), b.count());
|
println!("Solutions: {}\nStates: {}", b.solution_count(), b.count());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,5 @@
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use factorio_blueprint::{
|
use factorio_blueprint::layout::GeneticAlgorithm;
|
||||||
belt_finding::{conflict_avoidance::ConflictAvoidance, Problem},
|
|
||||||
common::visualize::Visualize,
|
|
||||||
layout::{GeneticAlgorithm, Layout, PathLayout},
|
|
||||||
};
|
|
||||||
use rand::{rngs::SmallRng, SeedableRng};
|
use rand::{rngs::SmallRng, SeedableRng};
|
||||||
|
|
||||||
#[derive(Debug, Parser)]
|
#[derive(Debug, Parser)]
|
||||||
|
|
@ -15,7 +11,7 @@ struct Args {
|
||||||
fn main() {
|
fn main() {
|
||||||
let args = Args::parse();
|
let args = Args::parse();
|
||||||
|
|
||||||
let file = std::fs::File::open("layout2.yml").unwrap();
|
let file = std::fs::File::open("layout3.yml").unwrap();
|
||||||
|
|
||||||
let p = serde_yaml::from_reader(file).unwrap();
|
let p = serde_yaml::from_reader(file).unwrap();
|
||||||
|
|
||||||
|
|
@ -23,7 +19,7 @@ fn main() {
|
||||||
|
|
||||||
dbg!(&p);
|
dbg!(&p);
|
||||||
|
|
||||||
let mut g = GeneticAlgorithm::new(&p, 20, 4, 2, &mut rng);
|
let mut g = GeneticAlgorithm::new(&p, 40, 5, 5, &mut rng);
|
||||||
|
|
||||||
for i in 0..100 {
|
for i in 0..100 {
|
||||||
println!("Generatrion {i}");
|
println!("Generatrion {i}");
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
use clap::{Parser, ValueEnum};
|
use clap::{Parser, ValueEnum};
|
||||||
use factorio_blueprint::belt_finding::{conflict_avoidance::ConflictAvoidance, problems, Problem};
|
use factorio_blueprint::belt_finding::{conflict_avoidance::ConflictAvoidance, problems, Problem};
|
||||||
use std::io;
|
use std::{io, path::PathBuf};
|
||||||
|
|
||||||
#[derive(ValueEnum, Clone)]
|
#[derive(ValueEnum, Clone)]
|
||||||
enum Mode {
|
enum Mode {
|
||||||
|
|
@ -59,9 +59,9 @@ fn main() {
|
||||||
p.print();
|
p.print();
|
||||||
p.find_path();
|
p.find_path();
|
||||||
p.print();
|
p.print();
|
||||||
let mut c = ConflictAvoidance::new(p);
|
let mut c = ConflictAvoidance::new(&p);
|
||||||
c.print();
|
c.print();
|
||||||
while c.remove_conflict() {
|
while c.remove_conflict(None) {
|
||||||
c.print();
|
c.print();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -75,9 +75,9 @@ fn main() {
|
||||||
p.print();
|
p.print();
|
||||||
p.find_path();
|
p.find_path();
|
||||||
p.print();
|
p.print();
|
||||||
let mut c = ConflictAvoidance::new(p);
|
let mut c = ConflictAvoidance::new(&p);
|
||||||
c.print();
|
c.print();
|
||||||
while c.remove_conflict() {
|
while c.remove_conflict(None) {
|
||||||
c.print();
|
c.print();
|
||||||
let mut s = String::new();
|
let mut s = String::new();
|
||||||
let _ = io::stdin().read_line(&mut s);
|
let _ = io::stdin().read_line(&mut s);
|
||||||
|
|
|
||||||
115
layout3.yml
Normal file
115
layout3.yml
Normal file
|
|
@ -0,0 +1,115 @@
|
||||||
|
size:
|
||||||
|
x: 50
|
||||||
|
y: 50
|
||||||
|
blocks:
|
||||||
|
- size:
|
||||||
|
x: 3
|
||||||
|
y: 2
|
||||||
|
input:
|
||||||
|
- offset:
|
||||||
|
x: 1
|
||||||
|
y: 1
|
||||||
|
dir: Up
|
||||||
|
output:
|
||||||
|
- offset:
|
||||||
|
x: 1
|
||||||
|
y: 0
|
||||||
|
dir: Up
|
||||||
|
- size:
|
||||||
|
x: 5
|
||||||
|
y: 2
|
||||||
|
input:
|
||||||
|
output:
|
||||||
|
- offset:
|
||||||
|
x: 1
|
||||||
|
y: 1
|
||||||
|
dir: Down
|
||||||
|
- size:
|
||||||
|
x: 5
|
||||||
|
y: 7
|
||||||
|
input:
|
||||||
|
- offset:
|
||||||
|
x: 0
|
||||||
|
y: 1
|
||||||
|
dir: Right
|
||||||
|
output:
|
||||||
|
- size:
|
||||||
|
x: 5
|
||||||
|
y: 5
|
||||||
|
input:
|
||||||
|
- offset:
|
||||||
|
x: 0
|
||||||
|
y: 1
|
||||||
|
dir: Right
|
||||||
|
output:
|
||||||
|
- offset:
|
||||||
|
x: 0
|
||||||
|
y: 3
|
||||||
|
dir: Left
|
||||||
|
- size:
|
||||||
|
x: 10
|
||||||
|
y: 10
|
||||||
|
input:
|
||||||
|
- offset:
|
||||||
|
x: 0
|
||||||
|
y: 1
|
||||||
|
dir: Right
|
||||||
|
- offset:
|
||||||
|
x: 0
|
||||||
|
y: 3
|
||||||
|
dir: Right
|
||||||
|
output:
|
||||||
|
- offset:
|
||||||
|
x: 9
|
||||||
|
y: 1
|
||||||
|
dir: Right
|
||||||
|
- offset:
|
||||||
|
x: 9
|
||||||
|
y: 3
|
||||||
|
dir: Right
|
||||||
|
- size:
|
||||||
|
x: 10
|
||||||
|
y: 5
|
||||||
|
input:
|
||||||
|
- offset:
|
||||||
|
x: 0
|
||||||
|
y: 1
|
||||||
|
dir: Right
|
||||||
|
- offset:
|
||||||
|
x: 0
|
||||||
|
y: 3
|
||||||
|
dir: Right
|
||||||
|
output:
|
||||||
|
- offset:
|
||||||
|
x: 9
|
||||||
|
y: 1
|
||||||
|
dir: Right
|
||||||
|
- offset:
|
||||||
|
x: 9
|
||||||
|
y: 3
|
||||||
|
dir: Right
|
||||||
|
connections:
|
||||||
|
- startblock: 1
|
||||||
|
startpoint: 0
|
||||||
|
endblock: 0
|
||||||
|
endpoint: 0
|
||||||
|
- startblock: 0
|
||||||
|
startpoint: 0
|
||||||
|
endblock: 3
|
||||||
|
endpoint: 0
|
||||||
|
- startblock: 3
|
||||||
|
startpoint: 0
|
||||||
|
endblock: 4
|
||||||
|
endpoint: 0
|
||||||
|
- startblock: 4
|
||||||
|
startpoint: 0
|
||||||
|
endblock: 5
|
||||||
|
endpoint: 0
|
||||||
|
- startblock: 4
|
||||||
|
startpoint: 1
|
||||||
|
endblock: 5
|
||||||
|
endpoint: 1
|
||||||
|
- startblock: 5
|
||||||
|
startpoint: 0
|
||||||
|
endblock: 2
|
||||||
|
endpoint: 0
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
use std::time::Instant;
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
common::{print_map, PathField},
|
common::{print_map, PathField},
|
||||||
Position,
|
Position,
|
||||||
|
|
@ -548,11 +550,12 @@ impl Bruteforce {
|
||||||
self.modify_remove()
|
self.modify_remove()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn next_finish_state(&mut self) -> bool {
|
pub fn next_finish_state(&mut self, timeout: Option<Instant>) -> bool {
|
||||||
while self.next_state() {
|
while self.next_state() {
|
||||||
// if self.count % 1000000 == 0 {
|
if self.count % 10000 == 0 && timeout.is_some_and(|t| t < std::time::Instant::now()) {
|
||||||
// println!("{}\n{}", self.count, self);
|
return false;
|
||||||
// }
|
}
|
||||||
|
|
||||||
if self.problems.iter().all(|p| p.finished) {
|
if self.problems.iter().all(|p| p.finished) {
|
||||||
self.solution_count += 1;
|
self.solution_count += 1;
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -679,7 +682,7 @@ mod test {
|
||||||
fn $i() {
|
fn $i() {
|
||||||
let mut b = problems::$i();
|
let mut b = problems::$i();
|
||||||
|
|
||||||
while b.next_finish_state() {}
|
while b.next_finish_state(None) {}
|
||||||
|
|
||||||
assert_eq!(b.solution_count(), $x);
|
assert_eq!(b.solution_count(), $x);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,10 @@ use super::{
|
||||||
};
|
};
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use crate::{belt_finding::brute_force::BruteforceBuilder, misc::Map};
|
use crate::{belt_finding::brute_force::BruteforceBuilder, misc::Map};
|
||||||
use std::ops::RangeInclusive;
|
use std::{
|
||||||
|
ops::RangeInclusive,
|
||||||
|
time::{Duration, Instant},
|
||||||
|
};
|
||||||
use termcolor::ColorSpec;
|
use termcolor::ColorSpec;
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
|
|
@ -68,7 +71,7 @@ impl Candidate {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ConflictAvoidance {
|
impl ConflictAvoidance {
|
||||||
pub fn new(problem: Problem) -> Self {
|
pub fn new(problem: &Problem) -> Self {
|
||||||
let mut map: Map<Field> = Map::new(problem.map.width, problem.map.height);
|
let mut map: Map<Field> = Map::new(problem.map.width, problem.map.height);
|
||||||
for x in 0..problem.map.width {
|
for x in 0..problem.map.width {
|
||||||
for y in 0..problem.map.height {
|
for y in 0..problem.map.height {
|
||||||
|
|
@ -130,7 +133,11 @@ impl ConflictAvoidance {
|
||||||
&self.belts
|
&self.belts
|
||||||
}
|
}
|
||||||
|
|
||||||
fn try_bruteforce(&self, candidate: &Candidate) -> Option<Vec<BruteForceEntry>> {
|
fn try_bruteforce(
|
||||||
|
&self,
|
||||||
|
candidate: &Candidate,
|
||||||
|
timeout: Option<Instant>,
|
||||||
|
) -> Option<Vec<BruteForceEntry>> {
|
||||||
let xrange = candidate.min.x as usize..=candidate.max.x as usize;
|
let xrange = candidate.min.x as usize..=candidate.max.x as usize;
|
||||||
let yrange = candidate.min.y as usize..=candidate.max.y as usize;
|
let yrange = candidate.min.y as usize..=candidate.max.y as usize;
|
||||||
|
|
||||||
|
|
@ -218,9 +225,9 @@ impl ConflictAvoidance {
|
||||||
{
|
{
|
||||||
let p = start_pos - offset;
|
let p = start_pos - offset;
|
||||||
// println!("Blocked {:?}", p);
|
// println!("Blocked {:?}", p);
|
||||||
if b.get_blocked(p.x as usize, p.y as usize) {
|
// if b.get_blocked(p.x as usize, p.y as usize) {
|
||||||
return None;
|
// return None;
|
||||||
}
|
// }
|
||||||
b.set_blocked(p.x as usize, p.y as usize, true);
|
b.set_blocked(p.x as usize, p.y as usize, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -258,7 +265,7 @@ impl ConflictAvoidance {
|
||||||
let mut min_cost = f64::INFINITY;
|
let mut min_cost = f64::INFINITY;
|
||||||
let mut solutions = Vec::new();
|
let mut solutions = Vec::new();
|
||||||
|
|
||||||
while b.next_finish_state() {
|
while b.next_finish_state(timeout) {
|
||||||
// println!("{}", b);
|
// println!("{}", b);
|
||||||
// b.print();
|
// b.print();
|
||||||
let c = b.cost();
|
let c = b.cost();
|
||||||
|
|
@ -286,7 +293,7 @@ impl ConflictAvoidance {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn remove_conflict(&mut self) -> bool {
|
pub fn remove_conflict(&mut self, timeout: Option<Instant>) -> bool {
|
||||||
let mut conflicts: Map<usize> = Map::new(self.map.width, self.map.height);
|
let mut conflicts: Map<usize> = Map::new(self.map.width, self.map.height);
|
||||||
|
|
||||||
for x in 0..self.map.width {
|
for x in 0..self.map.width {
|
||||||
|
|
@ -347,7 +354,7 @@ impl ConflictAvoidance {
|
||||||
}
|
}
|
||||||
// dbg!(&candidates);
|
// dbg!(&candidates);
|
||||||
|
|
||||||
loop {
|
while timeout.is_some_and(|t| t < Instant::now()) {
|
||||||
candidates.sort_by_key(|c| -c.area());
|
candidates.sort_by_key(|c| -c.area());
|
||||||
// dbg!(&candidates);
|
// dbg!(&candidates);
|
||||||
let c = match candidates.pop() {
|
let c = match candidates.pop() {
|
||||||
|
|
@ -359,7 +366,7 @@ impl ConflictAvoidance {
|
||||||
|
|
||||||
self.range = Some((c.min.x..=c.max.x, c.min.y..=c.max.y));
|
self.range = Some((c.min.x..=c.max.x, c.min.y..=c.max.y));
|
||||||
|
|
||||||
let result = self.try_bruteforce(&c);
|
let result = self.try_bruteforce(&c, timeout);
|
||||||
|
|
||||||
// dbg!(&solutions);
|
// dbg!(&solutions);
|
||||||
|
|
||||||
|
|
@ -442,10 +449,13 @@ impl ConflictAvoidance {
|
||||||
candidates.push(candidate);
|
candidates.push(candidate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn remove_all_conflicts(&mut self) -> bool {
|
pub fn remove_all_conflicts(&mut self, timeout: Option<Duration>) -> bool {
|
||||||
while self.remove_conflict() {}
|
let end = timeout.map(|t| std::time::Instant::now() + t);
|
||||||
|
while self.remove_conflict(end) {}
|
||||||
|
|
||||||
let mut conflicts: Map<bool> = Map::new(self.map.width, self.map.height);
|
let mut conflicts: Map<bool> = Map::new(self.map.width, self.map.height);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,10 @@
|
||||||
use crate::common::color::COLORS;
|
use crate::common::color::COLORS;
|
||||||
|
use crate::graph::wheighted_graph::shortest_path::dijkstra;
|
||||||
use crate::graph::wheighted_graph::WheightedGraph;
|
use crate::graph::wheighted_graph::WheightedGraph;
|
||||||
use crate::layout::Layout;
|
use crate::layout::Layout;
|
||||||
use crate::misc::Map;
|
use crate::misc::Map;
|
||||||
use crate::priority_queue::{BinaryHeap, Trace};
|
use crate::priority_queue::BinaryHeap;
|
||||||
use crate::{
|
use serde::{Deserialize, Serialize};
|
||||||
graph::wheighted_graph::shortest_path::dijkstra, priority_queue::fibonacci_heap::FibonacciHeap,
|
|
||||||
};
|
|
||||||
use termcolor::ColorSpec;
|
use termcolor::ColorSpec;
|
||||||
|
|
||||||
use self::common::print_map;
|
use self::common::print_map;
|
||||||
|
|
@ -15,12 +14,13 @@ pub mod brute_force;
|
||||||
pub mod common;
|
pub mod common;
|
||||||
pub mod conflict_avoidance;
|
pub mod conflict_avoidance;
|
||||||
|
|
||||||
#[derive(Default, Clone, Copy)]
|
#[derive(Debug, Default, Serialize, Deserialize, Clone, Copy)]
|
||||||
pub struct Field {
|
pub struct Field {
|
||||||
pub blocked: bool,
|
pub blocked: bool,
|
||||||
weight: f64,
|
weight: f64,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
pub struct Problem {
|
pub struct Problem {
|
||||||
map: Map<Field>,
|
map: Map<Field>,
|
||||||
start: Vec<(Position, Direction)>,
|
start: Vec<(Position, Direction)>,
|
||||||
|
|
|
||||||
80
src/bin/beltfinding.rs
Normal file
80
src/bin/beltfinding.rs
Normal file
|
|
@ -0,0 +1,80 @@
|
||||||
|
use clap::{Parser, Subcommand, ValueEnum};
|
||||||
|
use factorio_blueprint::belt_finding::{conflict_avoidance::ConflictAvoidance, problems, Problem};
|
||||||
|
use std::{io, path::PathBuf};
|
||||||
|
|
||||||
|
#[derive(ValueEnum, Clone)]
|
||||||
|
enum Mode {
|
||||||
|
Solve,
|
||||||
|
ConflictAvoidance,
|
||||||
|
ConflictStep,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Subcommand)]
|
||||||
|
enum ProblemCase {
|
||||||
|
Simple,
|
||||||
|
Level1,
|
||||||
|
Level2,
|
||||||
|
Level3,
|
||||||
|
Level5,
|
||||||
|
File { filename: PathBuf },
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ProblemCase {
|
||||||
|
fn get_problem(&self) -> Problem {
|
||||||
|
match self {
|
||||||
|
ProblemCase::Simple => problems::simple(),
|
||||||
|
ProblemCase::Level1 => problems::belt_madness_level_1(),
|
||||||
|
ProblemCase::Level2 => problems::belt_madness_level_2(),
|
||||||
|
ProblemCase::Level3 => problems::belt_madness_level_3(),
|
||||||
|
ProblemCase::Level5 => problems::belt_madness_level_5(),
|
||||||
|
ProblemCase::File { filename } => {
|
||||||
|
let file = std::fs::File::open(filename).unwrap();
|
||||||
|
serde_json::from_reader(file).unwrap()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Parser)]
|
||||||
|
struct Args {
|
||||||
|
#[arg(value_enum, default_value = "conflict-avoidance")]
|
||||||
|
mode: Mode,
|
||||||
|
#[command(subcommand)]
|
||||||
|
problem: ProblemCase,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let args = Args::parse();
|
||||||
|
|
||||||
|
let mut p = args.problem.get_problem();
|
||||||
|
|
||||||
|
match args.mode {
|
||||||
|
Mode::Solve => {
|
||||||
|
p.print();
|
||||||
|
p.find_path();
|
||||||
|
p.print();
|
||||||
|
}
|
||||||
|
Mode::ConflictAvoidance => {
|
||||||
|
p.print();
|
||||||
|
p.find_path();
|
||||||
|
p.print();
|
||||||
|
let mut c = ConflictAvoidance::new(&p);
|
||||||
|
c.print();
|
||||||
|
while c.remove_conflict(None) {
|
||||||
|
c.print();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Mode::ConflictStep => {
|
||||||
|
p.print();
|
||||||
|
p.find_path();
|
||||||
|
p.print();
|
||||||
|
let mut c = ConflictAvoidance::new(&p);
|
||||||
|
c.print();
|
||||||
|
while c.remove_conflict(None) {
|
||||||
|
c.print();
|
||||||
|
let mut s = String::new();
|
||||||
|
let _ = io::stdin().read_line(&mut s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -61,6 +61,10 @@ where
|
||||||
G::Node: Eq + Hash + Clone + Debug,
|
G::Node: Eq + Hash + Clone + Debug,
|
||||||
G: WheightedGraph,
|
G: WheightedGraph,
|
||||||
{
|
{
|
||||||
|
if start == end {
|
||||||
|
return Some(vec![start]);
|
||||||
|
}
|
||||||
|
|
||||||
let mut map: HashMap<G::Node, MapObject<G::Node, P::Handle>> = HashMap::new();
|
let mut map: HashMap<G::Node, MapObject<G::Node, P::Handle>> = HashMap::new();
|
||||||
|
|
||||||
let mut q = P::new();
|
let mut q = P::new();
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,6 @@
|
||||||
|
use std::sync::atomic::AtomicU32;
|
||||||
|
use std::time::Instant;
|
||||||
|
|
||||||
use crate::belt_finding::common::PathField;
|
use crate::belt_finding::common::PathField;
|
||||||
use crate::belt_finding::conflict_avoidance::ConflictAvoidance;
|
use crate::belt_finding::conflict_avoidance::ConflictAvoidance;
|
||||||
use crate::common::visualize::{Color, Symbol, Visualization, Visualize};
|
use crate::common::visualize::{Color, Symbol, Visualization, Visualize};
|
||||||
|
|
@ -5,6 +8,8 @@ use crate::prelude::*;
|
||||||
use rand::{seq::SliceRandom, Rng};
|
use rand::{seq::SliceRandom, Rng};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
static OUTFILEINDEX: AtomicU32 = AtomicU32::new(0);
|
||||||
|
|
||||||
pub struct GeneticAlgorithm<'a> {
|
pub struct GeneticAlgorithm<'a> {
|
||||||
problem: &'a Problem,
|
problem: &'a Problem,
|
||||||
population: Vec<PathLayout<'a>>,
|
population: Vec<PathLayout<'a>>,
|
||||||
|
|
@ -107,8 +112,8 @@ pub struct Problem {
|
||||||
pub(crate) connections: Vec<Connection>,
|
pub(crate) connections: Vec<Connection>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
// #[derive(Debug, Clone, Copy)]
|
||||||
pub struct BlockHandle(usize);
|
// pub struct BlockHandle(usize);
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Layout<'a> {
|
pub struct Layout<'a> {
|
||||||
|
|
@ -134,16 +139,25 @@ impl<'a> PathLayout<'a> {
|
||||||
|
|
||||||
// println!("Find Path: {:.2}", start.elapsed().as_secs_f32());
|
// println!("Find Path: {:.2}", start.elapsed().as_secs_f32());
|
||||||
|
|
||||||
let mut c = ConflictAvoidance::new(p);
|
let mut c = ConflictAvoidance::new(&p);
|
||||||
|
|
||||||
// let start = std::time::Instant::now();
|
let start = std::time::Instant::now();
|
||||||
|
|
||||||
if !c.remove_all_conflicts() {
|
if !c.remove_all_conflicts(Some(std::time::Duration::from_secs(2))) {
|
||||||
|
if start.elapsed().as_secs_f32() > 0.5 {
|
||||||
|
println!("Conflict avoidance: {:.2}", start.elapsed().as_secs_f32());
|
||||||
|
c.print();
|
||||||
|
let file = std::fs::File::create(format!(
|
||||||
|
"out/{}.json",
|
||||||
|
OUTFILEINDEX.fetch_add(1, std::sync::atomic::Ordering::Relaxed)
|
||||||
|
))
|
||||||
|
.unwrap();
|
||||||
|
serde_json::to_writer(file, &p).unwrap();
|
||||||
|
println!("Saved slow solve.");
|
||||||
|
}
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
// println!("Conflict avoidance: {:.2}", start.elapsed().as_secs_f32());
|
|
||||||
|
|
||||||
let paths = c.get_paths().to_vec();
|
let paths = c.get_paths().to_vec();
|
||||||
|
|
||||||
let score = paths
|
let score = paths
|
||||||
|
|
@ -210,15 +224,15 @@ impl Problem {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_block(&mut self, size: Position) -> BlockHandle {
|
// pub fn add_block(&mut self, size: Position) -> BlockHandle {
|
||||||
self.blocks.push(Block {
|
// self.blocks.push(Block {
|
||||||
size,
|
// size,
|
||||||
input: Vec::new(),
|
// input: Vec::new(),
|
||||||
output: Vec::new(),
|
// output: Vec::new(),
|
||||||
});
|
// });
|
||||||
|
|
||||||
BlockHandle(self.blocks.len() - 1)
|
// BlockHandle(self.blocks.len() - 1)
|
||||||
}
|
// }
|
||||||
|
|
||||||
// pub fn add_connection(
|
// pub fn add_connection(
|
||||||
// &mut self,
|
// &mut self,
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
#[derive(Clone, Debug)]
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
pub struct Map<T> {
|
pub struct Map<T> {
|
||||||
pub width: usize,
|
pub width: usize,
|
||||||
pub height: usize,
|
pub height: usize,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue