feat(router): Start implementing route pruning support
This commit is contained in:
		
							parent
							
								
									0107cf2f8e
								
							
						
					
					
						commit
						88a0378dfe
					
				
					 2 changed files with 38 additions and 25 deletions
				
			
		|  | @ -114,7 +114,7 @@ pub fn _ed_lrr(_py: Python, m: &PyModule) -> PyResult<()> { | |||
|         py: Python<'static>, | ||||
|         hops: Vec<String>, | ||||
|         range: f32, | ||||
|         prune: Option<(usize,f64)>, | ||||
|         prune: Option<(usize, f32)>, | ||||
|         mode: String, | ||||
|         primary: bool, | ||||
|         permute: bool, | ||||
|  |  | |||
|  | @ -57,7 +57,7 @@ pub struct RouteOpts { | |||
|     pub keep_last: bool, | ||||
|     pub factor: Option<f32>, | ||||
|     pub mode: Mode, | ||||
|     pub prune: Option<(usize,f64)>, | ||||
|     pub prune: Option<(usize, f32)>, | ||||
|     pub systems: Vec<SysEntry>, | ||||
|     pub callback: Box<dyn Fn(&SearchState) -> PyResult<PyObject>>, | ||||
| } | ||||
|  | @ -193,8 +193,7 @@ pub struct Router { | |||
|     range: f32, | ||||
|     primary_only: bool, | ||||
|     path: PathBuf, | ||||
|     prune: Option<(usize,f64)>, | ||||
|     prune_map: FnvHashMap<u32, (usize,f64)>, | ||||
|     prune: Option<(usize, f32)>, | ||||
|     callback: Box<dyn Fn(&SearchState) -> PyResult<PyObject>>, | ||||
| } | ||||
| 
 | ||||
|  | @ -202,7 +201,7 @@ impl Router { | |||
|     pub fn new( | ||||
|         path: &PathBuf, | ||||
|         range: f32, | ||||
|         prune: Option<(usize,f64)>, | ||||
|         prune: Option<(usize, f32)>, | ||||
|         primary_only: bool, | ||||
|         callback: Box<dyn Fn(&SearchState) -> PyResult<PyObject>>, | ||||
|     ) -> Result<Self, String> { | ||||
|  | @ -249,7 +248,6 @@ impl Router { | |||
|             path: path.clone(), | ||||
|             callback, | ||||
|             prune, | ||||
|             prune_map: FnvHashMap::default() | ||||
|         }; | ||||
|         println!( | ||||
|             "{} Systems loaded in {}", | ||||
|  | @ -307,7 +305,6 @@ impl Router { | |||
|                 path, | ||||
|                 callback, | ||||
|                 prune: None, | ||||
|                 prune_map: FnvHashMap::default() | ||||
|             }, | ||||
|         )) | ||||
|     } | ||||
|  | @ -320,10 +317,9 @@ impl Router { | |||
|         self.points_in_sphere(&sys.pos, sys.mult * r) | ||||
|     } | ||||
| 
 | ||||
|     fn valid(&self, sys: &System, src: &System, dst: &System) -> bool { | ||||
|     fn valid(&self, sys: &System) -> bool { | ||||
|         let scoopable = self.scoopable.contains(&sys.id); | ||||
|         return scoopable; | ||||
|         // TODO: check prune map
 | ||||
|     } | ||||
| 
 | ||||
|     pub fn best_multiroute( | ||||
|  | @ -379,6 +375,14 @@ impl Router { | |||
|         for pair in waypoints.windows(2) { | ||||
|             match pair { | ||||
|                 [src, dst] => { | ||||
|                     let d_total=dist(&src.pos,&dst.pos); | ||||
|                     println!("Plotting route from [{}] to [{}]...", src.system, dst.system); | ||||
|                     println!( | ||||
|                         "Jump Range: {} Ly, Distance: {} Ly, Estimated Jumps: {}", | ||||
|                         range, | ||||
|                         d_total, | ||||
|                         d_total / range | ||||
|                     ); | ||||
|                     let block = match mode { | ||||
|                         Mode::BFS => self.route_bfs(&src, &dst, range)?, | ||||
|                         Mode::Greedy => self.route_greedy(&src, &dst, range)?, | ||||
|  | @ -510,7 +514,7 @@ impl Router { | |||
|                 } | ||||
|                 queue.extend( | ||||
|                     self.neighbours(&sys, range) | ||||
|                         .filter(|&nb| (self.valid(nb, &src, &dst) || (nb.id == goal_sys.id))) | ||||
|                         .filter(|&nb| (self.valid(nb) || (nb.id == goal_sys.id))) | ||||
|                         .filter(|&nb| seen.insert(nb.id)) | ||||
|                         .map(|nb| { | ||||
|                             prev.insert(nb.id, sys); | ||||
|  | @ -583,11 +587,11 @@ impl Router { | |||
|         let mut prev = FnvHashMap::default(); | ||||
|         let mut seen = FnvHashSet::default(); | ||||
|         let mut found = false; | ||||
|         let mut queue: Vec<(f32, f32, usize, &System)> = Vec::new(); | ||||
|         queue.push((-goal_sys.mult, start_sys.distp(goal_sys), 0, &start_sys)); | ||||
|         let mut queue: Vec<(f32, usize, &System)> = Vec::new(); | ||||
|         queue.push((start_sys.distp(goal_sys), 0, &start_sys)); | ||||
|         seen.insert(start_sys.id); | ||||
|         while !(queue.is_empty() || found) { | ||||
|             while let Some((_, _, depth, sys)) = queue.pop() { | ||||
|             while let Some((_, depth, sys)) = queue.pop() { | ||||
|                 if t_last.elapsed().as_millis() > 100 { | ||||
|                     t_last = Instant::now(); | ||||
|                     state.depth = depth; | ||||
|  | @ -611,7 +615,7 @@ impl Router { | |||
|                 } | ||||
|                 queue.extend( | ||||
|                     self.neighbours(&sys, range) | ||||
|                         .filter(|&nb| (self.valid(nb, &src, &dst) || (nb.id == goal_sys.id))) | ||||
|                         .filter(|&nb| (self.valid(nb) || (nb.id == goal_sys.id))) | ||||
|                         .filter(|&nb| seen.insert(nb.id)) | ||||
|                         .map(|nb| { | ||||
|                             prev.insert(nb.id, sys); | ||||
|  | @ -619,10 +623,10 @@ impl Router { | |||
|                             if d_g < d_rem { | ||||
|                                 d_rem = d_g; | ||||
|                             } | ||||
|                             (-nb.mult, d_g, depth + 1, nb) | ||||
|                             (d_g, depth + 1, nb) | ||||
|                         }), | ||||
|                 ); | ||||
|                 queue.sort_by(|a, b| fcmp(a.0, b.0).then(fcmp(a.1, b.1))); | ||||
|                 queue.sort_by(|a, b| fcmp(a.0, b.0).then(a.1.cmp(&b.1))); | ||||
|                 queue.reverse(); | ||||
|             } | ||||
|         } | ||||
|  | @ -786,6 +790,7 @@ impl Router { | |||
|         range: f32, | ||||
|     ) -> Result<Vec<System>, String> { | ||||
|         println!("Running BFS"); | ||||
|         let min_improvement = self.prune.map(|v| (v.0,v.1*range)).unwrap_or_else(|| (0,0.0)); | ||||
|         let src_name = start_sys.system.clone(); | ||||
|         let dst_name = goal_sys.system.clone(); | ||||
|         let d_total = dist(&start_sys.pos, &goal_sys.pos); | ||||
|  | @ -804,15 +809,9 @@ impl Router { | |||
|             system: start_sys.system.clone(), | ||||
|             body: start_sys.body.clone(), | ||||
|         }; | ||||
|         println!("Plotting route from {} to {}...", src_name, dst_name); | ||||
|         println!( | ||||
|             "Jump Range: {} Ly, Distance: {} Ly, Estimated Jumps: {}", | ||||
|             range, | ||||
|             d_total, | ||||
|             d_total / range | ||||
|         ); | ||||
|         let total = self.tree.size() as f32; | ||||
|         let mut prev = FnvHashMap::default(); | ||||
|         let mut prev: FnvHashMap<u32, &System> = FnvHashMap::default(); | ||||
|         let mut prune_map: FnvHashMap<u32, (usize, f32)> = FnvHashMap::default(); | ||||
|         let mut seen = FnvHashSet::default(); | ||||
|         let mut depth = 0; | ||||
|         let mut found = false; | ||||
|  | @ -847,10 +846,24 @@ impl Router { | |||
|                     }; | ||||
|                     t_last = Instant::now(); | ||||
|                 } | ||||
|                 if self.prune.is_some() { | ||||
|                     let best_dist = if let Some(p_sys) = prev.get(&sys.id) { | ||||
|                         dist2(&p_sys.pos, &goal_sys.pos).min( | ||||
|                             prune_map | ||||
|                                 .get(&p_sys.id) | ||||
|                                 .map(|v| v.1) | ||||
|                                 .unwrap_or(std::f32::MAX), | ||||
|                         ) | ||||
|                     } else { | ||||
|                         dist2(&sys.pos, &goal_sys.pos) | ||||
|                     }; | ||||
|                     prune_map.insert(sys.id, (depth, best_dist)); | ||||
|                 } | ||||
|                 // TODO: check improvement, if too small: continue
 | ||||
|                 queue_next.extend( | ||||
|                     self.neighbours(&sys, range) | ||||
|                         .filter(|&nb| { | ||||
|                             (self.valid(nb, &start_sys, &goal_sys) || (nb.id == goal_sys.id)) | ||||
|                             (self.valid(nb) || (nb.id == goal_sys.id)) | ||||
|                         }) | ||||
|                         .filter(|&nb| seen.insert(nb.id)) | ||||
|                         .map(|nb| { | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue