The iddfs (Iterative Deepening Depth-First Search) function computes the shortest path from a start node to a node that satisfies the success condition. It is useful for finding shortest paths in unweighted graphs while maintaining the memory efficiency of depth-first search.
Parameters
start: The starting node of type N.successors: A closure FnMut(&N) -> IN that returns an iterator of successor nodes for a given node.success: A closure FnMut(&N) -> bool that returns true if the given node is the goal. Note that the goal does not have to be a specific node; it can be a dynamic condition.
Behavior
- Returns
Some(Vec<N>) containing the shortest path (including both the start and end nodes) if a path is found. - Returns
None if no path can be found. - A node will never be included twice in the path (it avoids cycles based on the
Eq relationship). - The
start node's ownership is taken by iddfs as no clones are made.
use pathfinding::prelude::iddfs;
// Example 1: Using a custom struct
#[derive(Eq, PartialEq, Clone, Debug)]
struct Pos(i32, i32);
impl Pos {
fn successors(&self) -> Vec<Pos> {
let &Pos(x, y) = self;
vec![Pos(x+1,y+2), Pos(x+1,y-2), Pos(x-1,y+2), Pos(x-1,y-2),
Pos(x+2,y+1), Pos(x+2,y-1), Pos(x-2,y+1), Pos(x-2,y-1)]
}
}
static GOAL: Pos = Pos(4, 6);
let result = iddfs(Pos(1, 1), |p| p.successors(), |p| *p == GOAL);
assert_eq!(result.expect("no path found").len(), 5);
// Example 2: Using closures and tuples for brevity
static GOAL_TUPLE: (i32, i32) = (4, 6);
let result = iddfs((1, 1),
|&(x, y)| vec![(x+1,y+2), (x+1,y-2), (x-1,y+2), (x-1,y-2),
(x+2,y+1), (x+2,y-1), (x-2,y+1), (x-2,y-1)],
|&p| p == GOAL_TUPLE);
assert_eq!(result.expect("no path found").len(), 5);