Add --bidi flag to path command
This commit is contained in:
parent
535d7ff236
commit
6611dd3160
1 changed files with 55 additions and 21 deletions
|
|
@ -3,6 +3,7 @@ use std::io;
|
|||
use crate::{
|
||||
algo::Dijkstra,
|
||||
data::Data,
|
||||
graph::NodeIdx,
|
||||
util::{self, TitleNormalizer},
|
||||
};
|
||||
|
||||
|
|
@ -11,6 +12,46 @@ use crate::{
|
|||
pub struct Cmd {
|
||||
start: String,
|
||||
goal: String,
|
||||
|
||||
// Search for a path in both directions.
|
||||
#[arg(long, short)]
|
||||
bidi: bool,
|
||||
}
|
||||
|
||||
fn search_path(data: &Data, start: NodeIdx, goal: NodeIdx) -> Option<(u32, Vec<NodeIdx>)> {
|
||||
println!("> Preparing dijkstra");
|
||||
let mut dijkstra = Dijkstra::new(&data.graph);
|
||||
println!("> Running dijkstra");
|
||||
dijkstra.run(
|
||||
start,
|
||||
|node| node == goal,
|
||||
|source, _edge, _target| !data.pages[source.usize()].redirect as u32,
|
||||
);
|
||||
|
||||
if dijkstra.cost(goal) == u32::MAX {
|
||||
return None;
|
||||
}
|
||||
|
||||
println!("> Collecting path");
|
||||
let cost = dijkstra.cost(goal);
|
||||
let path = dijkstra.path(goal);
|
||||
Some((cost, path))
|
||||
}
|
||||
|
||||
fn print_path(data: &Data, start: NodeIdx, goal: NodeIdx, path: Option<(u32, Vec<NodeIdx>)>) {
|
||||
let start = &data.pages[start.usize()].title;
|
||||
let goal = &data.pages[goal.usize()].title;
|
||||
|
||||
let Some((cost, path)) = path else {
|
||||
println!("No path found from {start} to {goal}");
|
||||
return;
|
||||
};
|
||||
|
||||
println!("Path found (cost {cost}, length {}):", path.len());
|
||||
|
||||
for page in path {
|
||||
println!("{}", util::fmt_page(&data.pages[page.usize()]));
|
||||
}
|
||||
}
|
||||
|
||||
impl Cmd {
|
||||
|
|
@ -23,29 +64,22 @@ impl Cmd {
|
|||
println!("Start: {}", data.pages[start.usize()].title);
|
||||
println!("Goal: {}", data.pages[goal.usize()].title);
|
||||
|
||||
println!(">> Find path");
|
||||
println!("> Preparing dijkstra");
|
||||
let mut dijkstra = Dijkstra::new(&data.graph);
|
||||
println!("> Running dijkstra");
|
||||
dijkstra.run(
|
||||
start,
|
||||
|node| node == goal,
|
||||
|source, _edge, _target| !data.pages[source.usize()].redirect as u32,
|
||||
);
|
||||
|
||||
if dijkstra.cost(goal) == u32::MAX {
|
||||
println!("No path found");
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
println!("> Collecting path");
|
||||
let path = dijkstra.path(goal);
|
||||
let cost = dijkstra.cost(goal);
|
||||
if self.bidi {
|
||||
println!(">> Find path forward");
|
||||
let forward = search_path(&data, start, goal);
|
||||
println!(">> Find path backward");
|
||||
let backward = search_path(&data, goal, start);
|
||||
|
||||
println!();
|
||||
println!("Path found (cost {cost}, length {}):", path.len());
|
||||
for page in path {
|
||||
println!("{}", util::fmt_page(&data.pages[page.usize()]));
|
||||
print_path(&data, start, goal, forward);
|
||||
println!();
|
||||
print_path(&data, goal, start, backward);
|
||||
} else {
|
||||
println!(">> Find path");
|
||||
let path = search_path(&data, start, goal);
|
||||
|
||||
println!();
|
||||
print_path(&data, start, goal, path);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue