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…
Reference in a new issue