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:
- offset:
x: 0
y: 2
y: 3
dir: Left
connections:
- startblock: 1

View file

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

View file

@ -213,12 +213,16 @@ impl ConflictAvoidance {
}
}
let start_pos_offset = start_pos - offset;
b.set_blocked(
start_pos_offset.x as usize,
start_pos_offset.y as usize,
true,
);
if xrange.contains(&(start_pos.x as usize))
&& yrange.contains(&(start_pos.y as usize))
{
let p = start_pos - offset;
// 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] {
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));
mapping.push((i, start_index, end_index));
@ -255,6 +260,7 @@ impl ConflictAvoidance {
while b.next_finish_state() {
// println!("{}", b);
// b.print();
let c = b.cost();
if c < min_cost {
min_cost = c;
@ -363,6 +369,7 @@ impl ConflictAvoidance {
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);
if let Some(r) = result {
// println!("Here");
for BruteForceEntry {
path_id,
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
}

View file

@ -215,7 +215,7 @@ impl<'a> WheightedGraph for MapInternal<'a> {
count += 1;
if count == num {
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());
population[0].print_visualization();
@ -56,14 +56,16 @@ impl<'a> GeneticAlgorithm<'a> {
for i in (self.population_keep + self.population_new)..self.population_size {
let j = i - (self.population_keep + self.population_new);
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;
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());
self.population[0].print_visualization();
}
@ -122,20 +124,26 @@ pub struct PathLayout<'a> {
impl<'a> 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 start = std::time::Instant::now();
if !p.find_path() {
return None;
}
p.print();
// println!("Find Path: {:.2}", start.elapsed().as_secs_f32());
let mut c = ConflictAvoidance::new(p);
// let start = std::time::Instant::now();
if !c.remove_all_conflicts() {
return None;
}
// println!("Conflict avoidance: {:.2}", start.elapsed().as_secs_f32());
let paths = c.get_paths().to_vec();
let score = paths
@ -302,13 +310,13 @@ impl Layout<'_> {
let r: &[(&dyn Fn(&mut Layout, &mut R) -> bool, _)] = &[
(&Self::mutate_replace::<R>, 30),
(&Self::mutate_flip::<R>, 50),
(&Self::mutate_jiggle::<R>, 80),
(&Self::mutate_jiggle::<R>, 160),
];
loop {
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;
}
}

View file

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