Bug fixes

This commit is contained in:
hal8174 2024-08-31 02:00:28 +02:00
parent a11b39cf9f
commit f20a1841c9
6 changed files with 75 additions and 25 deletions

View file

@ -44,7 +44,7 @@ blocks:
output: output:
- offset: - offset:
x: 0 x: 0
y: 2 y: 3
dir: Left dir: Left
connections: connections:
- startblock: 1 - startblock: 1

View file

@ -65,7 +65,7 @@ impl PathField {
pub fn cost(&self) -> usize { pub fn cost(&self) -> usize {
match self { match self {
PathField::Belt { pos: _, dir: _ } => 300, PathField::Belt { pos: _, dir: _ } => 150,
PathField::Underground { PathField::Underground {
pos: _, pos: _,
dir: _, dir: _,

View file

@ -213,12 +213,16 @@ impl ConflictAvoidance {
} }
} }
let start_pos_offset = start_pos - offset; if xrange.contains(&(start_pos.x as usize))
b.set_blocked( && yrange.contains(&(start_pos.y as usize))
start_pos_offset.x as usize, {
start_pos_offset.y as usize, let p = start_pos - offset;
true, // println!("Blocked {:?}", p);
); if b.get_blocked(p.x as usize, p.y as usize) {
return None;
}
b.set_blocked(p.x as usize, p.y as usize, true);
}
if let PathField::Underground { pos, dir, len } = path[start_index] { if let PathField::Underground { pos, dir, len } = path[start_index] {
for l in 1..len { for l in 1..len {
@ -231,6 +235,7 @@ impl ConflictAvoidance {
} }
} }
let start_pos_offset = start_pos - offset;
b.add_path((start_pos_offset, start_dir), (end_pos - offset, end_dir)); b.add_path((start_pos_offset, start_dir), (end_pos - offset, end_dir));
mapping.push((i, start_index, end_index)); mapping.push((i, start_index, end_index));
@ -255,6 +260,7 @@ impl ConflictAvoidance {
while b.next_finish_state() { while b.next_finish_state() {
// println!("{}", b); // println!("{}", b);
// b.print();
let c = b.cost(); let c = b.cost();
if c < min_cost { if c < min_cost {
min_cost = c; min_cost = c;
@ -363,6 +369,7 @@ impl ConflictAvoidance {
let yrange = c.min.y as usize..=c.max.y as usize; let yrange = c.min.y as usize..=c.max.y as usize;
let offset = Position::new(*xrange.start() as i32 - 1, *yrange.start() as i32 - 1); let offset = Position::new(*xrange.start() as i32 - 1, *yrange.start() as i32 - 1);
if let Some(r) = result { if let Some(r) = result {
// println!("Here");
for BruteForceEntry { for BruteForceEntry {
path_id, path_id,
start, start,
@ -454,6 +461,32 @@ impl ConflictAvoidance {
} }
} }
for path in &self.belts {
for p in &path[1..] {
match p {
PathField::Belt { pos, dir: _ } => {
if conflicts.get(pos.x as usize, pos.y as usize) == &true {
return false;
} else {
conflicts.set(pos.x as usize, pos.y as usize, true);
}
}
PathField::Underground { pos, dir, len } => {
if conflicts.get(pos.x as usize, pos.y as usize) == &true {
return false;
} else {
conflicts.set(pos.x as usize, pos.y as usize, true);
}
let end = pos.in_direction(dir, *len as PositionType);
if conflicts.get(end.x as usize, end.y as usize) == &true {
return false;
} else {
conflicts.set(end.x as usize, end.y as usize, true);
}
}
}
}
}
true true
} }

View file

@ -215,7 +215,7 @@ impl<'a> WheightedGraph for MapInternal<'a> {
count += 1; count += 1;
if count == num { if count == num {
let penalty = penalty + self.map.get(n.x as usize, n.y as usize).weight; let penalty = penalty + self.map.get(n.x as usize, n.y as usize).weight;
return Some(((n, node.1), 17.5 + penalty)); return Some(((n, node.1), 35.0 + penalty));
} }
} }
} }

View file

@ -29,7 +29,7 @@ impl<'a> GeneticAlgorithm<'a> {
} }
} }
population.sort_by_cached_key(|p| p.score()); population.sort_by_key(|p| p.score());
println!("Best score: {}", population[0].score()); println!("Best score: {}", population[0].score());
population[0].print_visualization(); population[0].print_visualization();
@ -56,14 +56,16 @@ impl<'a> GeneticAlgorithm<'a> {
for i in (self.population_keep + self.population_new)..self.population_size { for i in (self.population_keep + self.population_new)..self.population_size {
let j = i - (self.population_keep + self.population_new); let j = i - (self.population_keep + self.population_new);
loop { loop {
if let Some(p) = PathLayout::new(self.population[j].layout.mutate(rng)) { if let Some(p) =
PathLayout::new(self.population[j % self.population_keep].layout.mutate(rng))
{
self.population[i] = p; self.population[i] = p;
break; break;
} }
} }
} }
self.population.sort_by_cached_key(|p| p.score()); self.population.sort_by_key(|p| p.score());
println!("Best score: {}", self.population[0].score()); println!("Best score: {}", self.population[0].score());
self.population[0].print_visualization(); self.population[0].print_visualization();
} }
@ -122,20 +124,26 @@ pub struct PathLayout<'a> {
impl<'a> PathLayout<'a> { impl<'a> PathLayout<'a> {
pub fn new(layout: Layout<'a>) -> Option<PathLayout<'a>> { pub fn new(layout: Layout<'a>) -> Option<PathLayout<'a>> {
layout.print_visualization();
let mut p = crate::belt_finding::Problem::from_layout(&layout); let mut p = crate::belt_finding::Problem::from_layout(&layout);
// let start = std::time::Instant::now();
if !p.find_path() { if !p.find_path() {
return None; return None;
} }
p.print();
// 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();
if !c.remove_all_conflicts() { if !c.remove_all_conflicts() {
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
@ -302,13 +310,13 @@ impl Layout<'_> {
let r: &[(&dyn Fn(&mut Layout, &mut R) -> bool, _)] = &[ let r: &[(&dyn Fn(&mut Layout, &mut R) -> bool, _)] = &[
(&Self::mutate_replace::<R>, 30), (&Self::mutate_replace::<R>, 30),
(&Self::mutate_flip::<R>, 50), (&Self::mutate_flip::<R>, 50),
(&Self::mutate_jiggle::<R>, 80), (&Self::mutate_jiggle::<R>, 160),
]; ];
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.4) { if p.0(&mut s, rng) && rng.gen_bool(0.2) {
break; break;
} }
} }

View file

@ -19,7 +19,13 @@ where
#[derive(Debug)] #[derive(Debug)]
pub struct BinaryHeap<Item> { pub struct BinaryHeap<Item> {
nextfree: usize, nextfree: usize,
data: Vec<(usize, Item)>, data: Vec<BinaryHeapEntry<Item>>,
}
#[derive(Debug)]
struct BinaryHeapEntry<Item> {
id: usize,
item: Item,
} }
impl<Item> BinaryHeap<Item> impl<Item> BinaryHeap<Item>
@ -31,16 +37,16 @@ where
let right = 2 * index + 2; let right = 2 * index + 2;
if right < self.data.len() { if right < self.data.len() {
let smaller = if self.data[left] < self.data[right] { let smaller = if self.data[left].item < self.data[right].item {
left left
} else { } else {
right right
}; };
if self.data[index] > self.data[smaller] { if self.data[index].item > self.data[smaller].item {
self.data.swap(index, smaller); self.data.swap(index, smaller);
self.downheap(smaller); self.downheap(smaller);
} }
} else if left < self.data.len() && self.data[index] > self.data[left] { } else if left < self.data.len() && self.data[index].item > self.data[left].item {
self.data.swap(index, left); self.data.swap(index, left);
self.downheap(left); self.downheap(left);
} }
@ -49,7 +55,7 @@ where
fn upheap(&mut self, index: usize) { fn upheap(&mut self, index: usize) {
if index > 0 { if index > 0 {
let parent = (index - 1) / 2; let parent = (index - 1) / 2;
if self.data[parent].1 > self.data[index].1 { if self.data[parent].item > self.data[index].item {
self.data.swap(parent, index); self.data.swap(parent, index);
self.upheap(parent); self.upheap(parent);
} }
@ -58,7 +64,7 @@ where
fn search(&self, id: usize) -> Option<usize> { fn search(&self, id: usize) -> Option<usize> {
for (i, d) in self.data.iter().enumerate() { for (i, d) in self.data.iter().enumerate() {
if d.0 == id { if d.id == id {
return Some(i); return Some(i);
} }
} }
@ -73,7 +79,10 @@ where
type Handle = usize; type Handle = usize;
fn insert(&mut self, item: Item) -> Self::Handle { fn insert(&mut self, item: Item) -> Self::Handle {
self.data.push((self.nextfree, item.clone())); self.data.push(BinaryHeapEntry {
id: self.nextfree,
item: item.clone(),
});
self.upheap(self.data.len() - 1); self.upheap(self.data.len() - 1);
self.nextfree += 1; self.nextfree += 1;
self.nextfree - 1 self.nextfree - 1
@ -85,13 +94,13 @@ where
} else { } else {
let d = self.data.swap_remove(0); let d = self.data.swap_remove(0);
self.downheap(0); self.downheap(0);
Some(d.1) Some(d.item)
} }
} }
fn decrease_key(&mut self, handle: &Self::Handle, f: impl Fn(&mut Item)) { fn decrease_key(&mut self, handle: &Self::Handle, f: impl Fn(&mut Item)) {
if let Some(index) = self.search(*handle) { if let Some(index) = self.search(*handle) {
f(&mut self.data[index].1); f(&mut self.data[index].item);
self.upheap(index); self.upheap(index);
} }
} }