47# ifndef BACKTRACKING_H
48# define BACKTRACKING_H
57namespace state_search_detail {
63template <SearchState State, SearchMove Move>
69 return lhs.depth <
rhs.depth;
84template <BacktrackingDomain Domain>
91 using State =
typename Domain::State;
93 using Move =
typename Domain::Move;
253 template <
typename OnSolution>
258 <<
"Depth_First_Backtracking only supports depth-first strategy";
260 <<
"SearchLimits::max_solutions must be positive or Search_Unlimited";
265 const auto start_time = SearchClock::now();
289 template <
typename OnSolution>
293 auto handler = std::forward<OnSolution>(
on_solution);
320 template <
typename VisitedSet>
348 template <
typename VisitedSet,
typename OnSolution>
355 <<
"Depth_First_Backtracking only supports depth-first strategy";
357 <<
"SearchLimits::max_solutions must be positive or Search_Unlimited";
362 const auto start_time = SearchClock::now();
392 template <
typename OnSolution>
407 Solution solution{state, path, depth};
444 [&](
const Move &move) ->
bool
467 template <
typename OnSolution,
typename VisitedSet>
481 const auto key =
domain_.state_key(state);
482 if (
auto *entry = visited.search(key);
483 entry !=
nullptr and entry->second <= depth)
492 Solution solution{state, path, depth};
525 if (
auto *entry = visited.search(key); entry !=
nullptr)
526 entry->second = depth;
528 visited.insert(key, depth);
534 [&](
const Move &move) ->
bool
559template <BacktrackingDomain Domain>
570template <BacktrackingDomain Domain,
typename OnSolution>
Exception handling system with formatted messages for Aleph-w.
#define ah_invalid_argument_if(C)
Throws std::invalid_argument if condition holds.
T & append(const T &data)
Append a copy of data
bool consider(const Solution &candidate)
Consider a candidate by copy.
Recursive depth-first backtracking over an implicit state space.
typename Domain::Move Move
Move type.
Depth_First_Backtracking(Domain domain, ExplorationPolicy policy={}, const SearchLimits &limits={}, Solution_Compare compare={})
Build an engine bound to one domain adapter.
bool expansion_limit_reached(Result &result) const
ExplorationPolicy policy_
void set_limits(const SearchLimits &limits) noexcept
Replace the hard limits for future runs.
and VisitedBoundMap< VisitedSet, typename Domain::State_Key, size_t > Result search(State initial_state, VisitedSet &visited)
DFS/backtracking with a depth-aware visited-state map.
const SearchLimits & limits() const noexcept
Current hard limits.
Result search(State initial_state, OnSolution &&on_solution)
Rvalue-friendly overload for temporary solution visitors.
static constexpr bool supports_best_first
Compile-time marker: Depth_First_Backtracking only supports Depth_First strategy.
state_search_detail::PreferShallowerSolution< State, Move > Solution_Compare
Internal solution comparator.
bool stop_after_solution(Result &result) const
typename Domain::State State
Concrete search state type.
const ExplorationPolicy & policy() const noexcept
Current exploration policy.
Domain Domain_Type
Type of the problem domain.
bool dfs(State &state, SearchPath< Move > &path, const size_t depth, Result &result, OnSolution &on_solution)
void set_policy(const ExplorationPolicy &policy) noexcept
Replace the exploration policy for future runs.
Domain & domain() noexcept
Mutable access to the bound domain adapter.
Solution_Compare compare_
and VisitedBoundMap< VisitedSet, typename Domain::State_Key, size_t > bool dfs_visited(State &state, SearchPath< Move > &path, const size_t depth, Result &result, OnSolution &on_solution, VisitedSet &visited)
Result search(State initial_state, OnSolution &on_solution)
Execute DFS/backtracking and invoke on_solution on each solution.
Result search(State initial_state)
Execute a depth-first backtracking search from initial_state.
and VisitedBoundMap< VisitedSet, typename Domain::State_Key, size_t > and SearchSolutionVisitor< OnSolution, Solution > Result search(State initial_state, VisitedSet &visited, OnSolution &on_solution)
DFS/backtracking with depth-aware visited-state tracking and a solution callback.
const Domain & domain() const noexcept
Read-only access to the bound domain adapter.
Concept for callbacks invoked on each accepted solution.
Generic concept for domains that can expose a stable state key.
Concept for a map tracking the best bound seen per visited state.
bool should_prune_state(Domain &domain, const typename Domain::State &state, const size_t depth)
Dispatch helper for the optional should_prune hook.
bool is_terminal_state(const Domain &domain, const typename Domain::State &state)
Dispatch helper for the optional is_terminal hook.
bool stop_after_solution(Result &result, const ExplorationPolicy &policy, const SearchLimits &limits)
Decide whether to stop the search after a solution was accepted.
bool expansion_limit_reached(Result &result, const SearchLimits &limits)
Check whether the expansion limit has been reached.
Main namespace for Aleph-w library functions.
and
Check uniqueness with explicit hash + equality functors.
@ Exhausted
Search space within the configured bounds was exhausted.
@ StoppedOnSolution
Search stopped because solution handling requested it.
@ NotStarted
Search object exists but no traversal has run yet.
void reserve_search_path(SearchPath< Move > &path, const SearchLimits &limits)
Divide_Conquer_DP_Result< Cost > divide_and_conquer_partition_dp(const size_t groups, const size_t n, Transition_Cost_Fn transition_cost, const Cost inf=dp_optimization_detail::default_inf< Cost >())
Optimize partition DP using divide-and-conquer optimization.
double search_elapsed_ms(const SearchClock::duration &duration) noexcept
@ Domain
Preserve the order emitted by for_each_successor().
auto backtracking_search(Domain domain, typename Domain::State initial_state, ExplorationPolicy policy={}, SearchLimits limits={})
Convenience wrapper that runs a one-shot DFS/backtracking search.
Common infrastructure for implicit state-space search.
Default solution visitor that always continues the search.
Exploration controls shared across engines.
Strategy strategy
Traversal strategy.
@ Depth_First
Recursive depth-first traversal (all engines).
Hard bounds applied by the search engine.
size_t max_solutions
Maximum accepted solutions.
size_t max_depth
Maximum expansion depth.
Aggregates the outcome of one search execution.
SearchStats stats
Statistics collected during the run.
ExplorationPolicy policy
Exploration policy used for the run.
SearchLimits limits
Limits used for the run.
SearchStatus status
Final execution state.
Incumbent_Type best_solution
Best incumbent retained by the engine.
Snapshot of a concrete solution encountered during the traversal.
size_t pruned_by_visited
States skipped because already seen (visited-set duplicate suppression).
size_t pruned_by_domain
States discarded by domain-side pruning.
size_t terminal_states
Non-solution terminal states cut by the domain.
double elapsed_ms
Wall-clock time spent inside the search call.
size_t pruned_by_depth
States not expanded due to max depth.
size_t generated_successors
Number of successor moves emitted.
size_t max_depth_reached
Deepest path depth visited.
size_t solutions_found
Number of goal states accepted.
size_t expanded_states
Number of non-terminal states expanded.
size_t visited_states
Number of states entered by the engine.
Default incumbent ordering for DFS solutions.
bool operator()(const SearchSolution< State, Move > &lhs, const SearchSolution< State, Move > &rhs) const noexcept