Add a star for shortest path
This commit is contained in:
		
							parent
							
								
									b96ef6f2c1
								
							
						
					
					
						commit
						b53d1e87bc
					
				
					 4 changed files with 65 additions and 19 deletions
				
			
		|  | @ -29,20 +29,20 @@ fn main() { | ||||||
|     let l = ValidLayout { |     let l = ValidLayout { | ||||||
|         max_tries: 4, |         max_tries: 4, | ||||||
|         retries: 4, |         retries: 4, | ||||||
|         start_size: Position::new(128, 128), |         start_size: Position::new(256, 256), | ||||||
|         growth: Position::new(16, 16), |         growth: Position::new(16, 16), | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     let l = GeneticAlgorithm { |     let l = GeneticAlgorithm { | ||||||
|         mutation_retries: 20, |         mutation_retries: 20, | ||||||
|         population_size: 40, |         population_size: 5, | ||||||
|         population_keep: 8, |         population_keep: 8, | ||||||
|         population_new: 2, |         population_new: 2, | ||||||
|         generations: 40, |         generations: 5, | ||||||
|         valid_layout: l, |         valid_layout: l, | ||||||
|     }; |     }; | ||||||
|     let p = ConflictAvoidance { |     let p = ConflictAvoidance { | ||||||
|         timeout: Some(std::time::Duration::from_millis(20)), |         timeout: Some(std::time::Duration::from_millis(100)), | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     let mut rng = SmallRng::seed_from_u64(args.seed); |     let mut rng = SmallRng::seed_from_u64(args.seed); | ||||||
|  |  | ||||||
|  | @ -90,14 +90,14 @@ pub fn generate_factory<L: Layouter, P: Pathfinder>( | ||||||
|                     input_connections.first_chunk() |                     input_connections.first_chunk() | ||||||
|                 { |                 { | ||||||
|                     let c0_bigger = c0.amount > c1.amount + c2.amount; |                     let c0_bigger = c0.amount > c1.amount + c2.amount; | ||||||
|                     intermediate_connections.push(dbg!(( |                     intermediate_connections.push(( | ||||||
|                         HashMap::from([ |                         HashMap::from([ | ||||||
|                             (connection_id0, (block_index, if c0_bigger { 1 } else { 0 })), |                             (connection_id0, (block_index, if c0_bigger { 1 } else { 0 })), | ||||||
|                             (connection_id1, (block_index + 1, 0)), |                             (connection_id1, (block_index + 1, 0)), | ||||||
|                             (connection_id2, (block_index + 1, 1)), |                             (connection_id2, (block_index + 1, 1)), | ||||||
|                         ]), |                         ]), | ||||||
|                         intermediate_output_connection, |                         intermediate_output_connection, | ||||||
|                     ))); |                     )); | ||||||
| 
 | 
 | ||||||
|                     let beltspeed = |                     let beltspeed = | ||||||
|                         Beltspeed::from_items_per_second(2.0 * f64::max(c1.amount, c2.amount)); |                         Beltspeed::from_items_per_second(2.0 * f64::max(c1.amount, c2.amount)); | ||||||
|  | @ -144,13 +144,13 @@ pub fn generate_factory<L: Layouter, P: Pathfinder>( | ||||||
|                 } else if let Some(&[(connection_id0, c0), (connection_id1, c1)]) = |                 } else if let Some(&[(connection_id0, c0), (connection_id1, c1)]) = | ||||||
|                     input_connections.first_chunk() |                     input_connections.first_chunk() | ||||||
|                 { |                 { | ||||||
|                     intermediate_connections.push(dbg!(( |                     intermediate_connections.push(( | ||||||
|                         HashMap::from([ |                         HashMap::from([ | ||||||
|                             (connection_id0, (block_index, 0)), |                             (connection_id0, (block_index, 0)), | ||||||
|                             (connection_id1, (block_index, 1)), |                             (connection_id1, (block_index, 1)), | ||||||
|                         ]), |                         ]), | ||||||
|                         intermediate_output_connection, |                         intermediate_output_connection, | ||||||
|                     ))); |                     )); | ||||||
|                     ( |                     ( | ||||||
|                         Beltspeed::from_items_per_second(c0.amount), |                         Beltspeed::from_items_per_second(c0.amount), | ||||||
|                         Some(Beltspeed::from_items_per_second(c1.amount)), |                         Some(Beltspeed::from_items_per_second(c1.amount)), | ||||||
|  | @ -201,17 +201,18 @@ pub fn generate_factory<L: Layouter, P: Pathfinder>( | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|             Building::ExternalConnection { inputs, outputs } => { |             Building::ExternalConnection { inputs, outputs } => { | ||||||
|  |                 let step = 4; | ||||||
|                 blocks.push(MacroBlock { |                 blocks.push(MacroBlock { | ||||||
|                     size: Position::new(1, (inputs + outputs) as PositionType), |                     size: Position::new(1, step * (inputs + outputs) as PositionType), | ||||||
|                     input: (0..*inputs) |                     input: (0..*inputs) | ||||||
|                         .map(|y| Interface { |                         .map(|y| Interface { | ||||||
|                             offset: Position::new(0, y as PositionType), |                             offset: Position::new(0, step * y as PositionType), | ||||||
|                             dir: Direction::Left, |                             dir: Direction::Left, | ||||||
|                         }) |                         }) | ||||||
|                         .collect(), |                         .collect(), | ||||||
|                     output: (0..*outputs) |                     output: (0..*outputs) | ||||||
|                         .map(|y| Interface { |                         .map(|y| Interface { | ||||||
|                             offset: Position::new(0, (inputs + y) as PositionType), |                             offset: Position::new(0, step * (inputs + y) as PositionType), | ||||||
|                             dir: Direction::Right, |                             dir: Direction::Right, | ||||||
|                         }) |                         }) | ||||||
|                         .collect(), |                         .collect(), | ||||||
|  | @ -279,7 +280,12 @@ pub fn generate_factory<L: Layouter, P: Pathfinder>( | ||||||
|                 let mut blueprint = Blueprint::new(); |                 let mut blueprint = Blueprint::new(); | ||||||
|                 blueprint.add_entity(Entity::new_splitter( |                 blueprint.add_entity(Entity::new_splitter( | ||||||
|                     Beltspeed::from_items_per_second( |                     Beltspeed::from_items_per_second( | ||||||
|                         input_connections.iter().map(|&(_, c)| c.amount).sum(), |                         input_connections | ||||||
|  |                             .iter() | ||||||
|  |                             .chain(output_connections.iter()) | ||||||
|  |                             .map(|&(_, c)| c.amount) | ||||||
|  |                             .max_by(|x, y| x.partial_cmp(y).unwrap()) | ||||||
|  |                             .unwrap_or(1.0), | ||||||
|                     ), |                     ), | ||||||
|                     Position::new(2, 1), |                     Position::new(2, 1), | ||||||
|                     Direction::Up, |                     Direction::Up, | ||||||
|  | @ -324,10 +330,10 @@ pub fn generate_factory<L: Layouter, P: Pathfinder>( | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|     dbg!(&intermediate_connections); |     // dbg!(&intermediate_connections);
 | ||||||
| 
 | 
 | ||||||
|     for (i, c) in factory_graph.factory_connections.iter().enumerate() { |     for (i, c) in factory_graph.factory_connections.iter().enumerate() { | ||||||
|         dbg!(i, c); |         // dbg!(i, c);
 | ||||||
|         connections.push(Connection { |         connections.push(Connection { | ||||||
|             startblock: intermediate_connections[c.from].1[&i].0, |             startblock: intermediate_connections[c.from].1[&i].0, | ||||||
|             startpoint: intermediate_connections[c.from].1[&i].1, |             startpoint: intermediate_connections[c.from].1[&i].1, | ||||||
|  | @ -338,8 +344,8 @@ pub fn generate_factory<L: Layouter, P: Pathfinder>( | ||||||
|         }); |         }); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     dbg!(&blocks); |     // dbg!(&blocks);
 | ||||||
|     dbg!(&connections); |     // dbg!(&connections);
 | ||||||
| 
 | 
 | ||||||
|     let layout_input = LayoutInput { |     let layout_input = LayoutInput { | ||||||
|         blocks, |         blocks, | ||||||
|  |  | ||||||
|  | @ -1,4 +1,5 @@ | ||||||
| use crate::examples::HashMapMap; | use crate::examples::HashMapMap; | ||||||
|  | use crate::graph::wheighted_graph::shortest_path::a_star; | ||||||
| use crate::graph::wheighted_graph::WheightedGraph; | use crate::graph::wheighted_graph::WheightedGraph; | ||||||
| use crate::misc::Map; | use crate::misc::Map; | ||||||
| use crate::priority_queue::binary_heap::BinaryHeap; | use crate::priority_queue::binary_heap::BinaryHeap; | ||||||
|  | @ -107,7 +108,7 @@ impl Problem { | ||||||
|                 let mut weight = 0.0; |                 let mut weight = 0.0; | ||||||
| 
 | 
 | ||||||
|                 if self.map.get(x, y).blocked { |                 if self.map.get(x, y).blocked { | ||||||
|                     weight += 100.0; |                     weight += 10000.0; | ||||||
|                 } |                 } | ||||||
| 
 | 
 | ||||||
|                 self.map.get_mut(x, y).weight = weight; |                 self.map.get_mut(x, y).weight = weight; | ||||||
|  | @ -117,7 +118,7 @@ impl Problem { | ||||||
|         for (i, path) in self.path.iter().enumerate() { |         for (i, path) in self.path.iter().enumerate() { | ||||||
|             if i != without { |             if i != without { | ||||||
|                 for p in path { |                 for p in path { | ||||||
|                     let weight = 10.0; |                     let weight = 1000.0; | ||||||
|                     let x = p.0.x as usize; |                     let x = p.0.x as usize; | ||||||
|                     let y = p.0.y as usize; |                     let y = p.0.y as usize; | ||||||
| 
 | 
 | ||||||
|  | @ -269,7 +270,17 @@ impl Problem { | ||||||
|                 map: &self.map, |                 map: &self.map, | ||||||
|                 end: self.end[i], |                 end: self.end[i], | ||||||
|             }; |             }; | ||||||
|             let p = dijkstra::<MapInternal, FastBinaryHeap<_>>(&m, self.start[i], self.end[i]); |             // let p = dijkstra::<MapInternal, FastBinaryHeap<_>>(&m, self.start[i], self.end[i]);
 | ||||||
|  |             let p = a_star::<MapInternal, FastBinaryHeap<_>, _>( | ||||||
|  |                 &m, | ||||||
|  |                 self.start[i], | ||||||
|  |                 self.end[i], | ||||||
|  |                 |&(p, _)| { | ||||||
|  |                     1.5 * (PositionType::abs_diff(p.x, self.end[i].0.x) | ||||||
|  |                         + PositionType::abs_diff(p.y, self.end[i].0.y)) | ||||||
|  |                         as f64 | ||||||
|  |                 }, | ||||||
|  |             ); | ||||||
|             if let Some(p) = p { |             if let Some(p) = p { | ||||||
|                 self.path[i] = p; |                 self.path[i] = p; | ||||||
|             } else { |             } else { | ||||||
|  |  | ||||||
|  | @ -116,6 +116,35 @@ where | ||||||
|     Some(result) |     Some(result) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | struct GraphWrapper<'a, G, F> { | ||||||
|  |     g: &'a G, | ||||||
|  |     f: F, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl<G: WheightedGraph, F: Fn(&G::Node) -> f64> WheightedGraph for GraphWrapper<'_, G, F> { | ||||||
|  |     type Node = G::Node; | ||||||
|  | 
 | ||||||
|  |     fn edge(&self, node: &Self::Node, num: usize) -> Option<(Self::Node, f64)> { | ||||||
|  |         self.g.edge(node, num).map(|(n, s)| { | ||||||
|  |             let s = s - (self.f)(node) + (self.f)(&n); | ||||||
|  |             (n, s) | ||||||
|  |         }) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | pub fn a_star<G, P, F>(graph: &G, start: G::Node, end: G::Node, dist: F) -> Option<Vec<G::Node>> | ||||||
|  | where | ||||||
|  |     P: PriorityQueue<QueueObject<G::Node>> + Debug, | ||||||
|  |     P::Handle: Debug, | ||||||
|  |     G::Node: Eq + Hash + Clone + Debug, | ||||||
|  |     G: WheightedGraph, | ||||||
|  |     F: Fn(&G::Node) -> f64, | ||||||
|  | { | ||||||
|  |     let g = GraphWrapper { g: graph, f: dist }; | ||||||
|  | 
 | ||||||
|  |     dijkstra::<GraphWrapper<G, F>, P>(&g, start, end) | ||||||
|  | } | ||||||
|  | 
 | ||||||
| #[cfg(test)] | #[cfg(test)] | ||||||
| mod test { | mod test { | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue