Bug fixes
This commit is contained in:
parent
a11b39cf9f
commit
f20a1841c9
6 changed files with 75 additions and 25 deletions
|
|
@ -44,7 +44,7 @@ blocks:
|
|||
output:
|
||||
- offset:
|
||||
x: 0
|
||||
y: 2
|
||||
y: 3
|
||||
dir: Left
|
||||
connections:
|
||||
- startblock: 1
|
||||
|
|
|
|||
|
|
@ -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: _,
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue