AI 24/25 Project Software
Documentation for the AI 24/25 course programming project software
Loading...
Searching...
No Matches
exhaustive_dfs.h
1#ifndef PROBFD_ALGORITHMS_EXHAUSTIVE_DFS_H
2#define PROBFD_ALGORITHMS_EXHAUSTIVE_DFS_H
3
4#include "probfd/algorithms/state_properties.h"
5
6#include "probfd/algorithms/types.h"
7
8#include "probfd/storage/per_state_storage.h"
9
10#include "probfd/distribution.h"
11#include "probfd/mdp_algorithm.h"
12#include "probfd/progress_report.h"
13
14#include <deque>
15#include <limits>
16
17// Forward Declarations
18namespace probfd::algorithms {
19template <typename, typename>
20class TransitionSorter;
21}
22
25
26struct Statistics {
27 unsigned long long expanded = 0;
28 unsigned long long evaluations = 0;
29 unsigned long long evaluated = 0;
30 unsigned long long goal_states = 0;
31 unsigned long long transitions = 0;
32 unsigned long long dead_ends = 0;
33 unsigned long long terminal = 0;
34 unsigned long long self_loop = 0;
35
36 unsigned long long value_updates = 0;
37 unsigned long long backtracks = 0;
38 unsigned long long sccs = 0;
39 unsigned long long dead_end_sccs = 0;
40 unsigned long long pruned_dead_end_sccs = 0;
41 unsigned long long summed_dead_end_scc_sizes = 0;
42
43 void print(std::ostream& out) const;
44};
45
46struct ExpansionInformation {
47 explicit ExpansionInformation(unsigned stack_index)
48 : stack_index(stack_index)
49 {
50 }
51
52 std::vector<Distribution<StateID>> successors;
53 Distribution<StateID>::const_iterator succ;
54 unsigned stack_index;
55
56 bool all_successors_are_dead = true;
57 bool all_successors_marked_dead = true;
58
59 void update_successors_dead(bool successors_dead)
60 {
61 all_successors_are_dead = all_successors_are_dead && successors_dead;
62 }
63};
64
65struct SCCTransition {
66 Distribution<StateID> successors;
67 value_t base = 0_vt;
68 value_t self_loop = 0_vt;
69};
70
71struct StackInformation {
72 explicit StackInformation(StateID state_ref)
73 : state_ref(state_ref)
74 {
75 }
76
77 StateID state_ref;
78 std::vector<SCCTransition> successors;
79 int i = -1;
80};
81
82template <bool UseInterval>
83struct SearchNodeInformation {
84 static constexpr uint8_t NEW = 0;
85 static constexpr uint8_t CLOSED = 1;
86 static constexpr uint8_t OPEN = 2;
87 static constexpr uint8_t ONSTACK = 4;
88 static constexpr uint8_t DEAD = 3;
89 static constexpr uint8_t MARKED = 7;
90
91 // TODO store lowlink in hash map -> only required for states still on
92 // stack
93 unsigned lowlink = std::numeric_limits<unsigned int>::max();
94 uint8_t status = NEW;
96 value_t term_cost;
97
98 [[nodiscard]]
99 bool is_new() const
100 {
101 return status == NEW;
102 }
103 [[nodiscard]]
104 bool is_open() const
105 {
106 return status == OPEN;
107 }
108 [[nodiscard]]
109 bool is_onstack() const
110 {
111 return status == ONSTACK;
112 }
113 [[nodiscard]]
114 bool is_closed() const
115 {
116 return status & CLOSED;
117 }
118 [[nodiscard]]
119 bool is_dead_end() const
120 {
121 return status == DEAD || status == MARKED;
122 }
123 [[nodiscard]]
124 bool is_marked_dead_end() const
125 {
126 return status == MARKED;
127 }
128
129 void open()
130 {
131 assert(is_new());
132 status = OPEN;
133 }
134
135 void set_onstack(const unsigned idx)
136 {
137 assert(is_open());
138 status = ONSTACK;
139 lowlink = idx;
140 }
141
142 void close() { status = CLOSED; }
143
144 void set_dead_end()
145 {
146 assert(!is_marked_dead_end());
147 status = DEAD;
148 }
149
150 void mark_dead_end() { status = MARKED; }
151
152 [[nodiscard]]
153 value_t get_value() const
154 {
155 if constexpr (UseInterval) {
156 return value.lower;
157 } else {
158 return value;
159 }
160 }
161
162 [[nodiscard]]
163 Interval get_bounds() const
164 {
165 if constexpr (!UseInterval) {
166 return Interval(value, INFINITE_VALUE);
167 } else {
168 return value;
169 }
170 }
171};
172
173template <bool UseInterval>
174struct SearchNodeInfos : public StateProperties {
175 storage::PerStateStorage<SearchNodeInformation<UseInterval>> infos;
176
177 SearchNodeInformation<UseInterval>& operator[](StateID state_id)
178 {
179 return infos[state_id];
180 }
181
182 const SearchNodeInformation<UseInterval>& operator[](StateID state_id) const
183 {
184 return infos[state_id];
185 }
186
187 value_t lookup_value(StateID state_id) override
188 {
189 return infos[state_id].get_value();
190 }
191
192 Interval lookup_bounds(StateID state_id) override
193 {
194 return infos[state_id].get_bounds();
195 }
196};
197
209template <typename State, typename Action, bool UseInterval>
210class ExhaustiveDepthFirstSearch : public MDPAlgorithm<State, Action> {
211 using Base = typename ExhaustiveDepthFirstSearch::MDPAlgorithm;
212
213 using MDPType = typename Base::MDPType;
214 using EvaluatorType = typename Base::EvaluatorType;
215 using PolicyType = Base::PolicyType;
216
218
219 using AlgorithmValueType = AlgorithmValue<UseInterval>;
220 using SearchNodeInfo = SearchNodeInformation<UseInterval>;
221
222 // Algorithm parameters
223 const std::shared_ptr<TransitionSorterType> transition_sort_;
224
225 const Interval cost_bound_;
226 const AlgorithmValueType trivial_bound_;
227
228 const bool value_propagation_;
229 const bool only_propagate_when_changed_;
230
231 // Algorithm state
232 SearchNodeInfos<UseInterval> search_space_;
233
234 std::deque<ExpansionInformation> expansion_infos_;
235 std::deque<StackInformation> stack_infos_;
236 std::vector<StateID> neighbors_;
237
238 bool last_all_dead_ = true;
239 bool last_all_marked_dead_ = true;
240
241 Statistics statistics_;
242
243public:
245 std::shared_ptr<TransitionSorterType> transition_sorting,
246 Interval cost_bound,
247 bool path_updates,
248 bool only_propagate_when_changed);
249
250 Interval solve(
251 MDPType& mdp,
252 EvaluatorType& heuristic,
253 param_type<State> state,
254 ProgressReport progress,
255 double max_time) override;
256
257 std::unique_ptr<PolicyType> compute_policy(
258 MDPType& mdp,
259 EvaluatorType& heuristic,
260 param_type<State> state,
261 ProgressReport progress,
262 double max_time) override;
263
264 void print_statistics(std::ostream& out) const override;
265
266private:
267 void register_value_reports(
268 const SearchNodeInfo& info,
269 ProgressReport& progress);
270
271 bool initialize_search_node(
272 MDPType& mdp,
273 EvaluatorType& heuristic,
274 StateID state_id,
275 SearchNodeInfo& info);
276
277 bool initialize_search_node(
278 MDPType& mdp,
279 EvaluatorType& heuristic,
280 param_type<State> state,
281 SearchNodeInfo& info);
282
283 bool push_state(
284 MDPType& mdp,
285 EvaluatorType& heuristic,
286 StateID state_id,
287 SearchNodeInfo& info);
288
289 void run_exploration(
290 MDPType& mdp,
291 EvaluatorType& heuristic,
292 ProgressReport& progress);
293
294 void propagate_value_along_trace(
295 bool was_poped,
296 value_t val,
297 ProgressReport& progress);
298
299 bool check_early_convergence(const SearchNodeInfo& node) const;
300};
301
302} // namespace probfd::algorithms::exhaustive_dfs
303
304#define GUARD_INCLUDE_PROBFD_ALGORITHMS_EXHAUSTIVE_DFS_H
305#include "probfd/algorithms/exhaustive_dfs_impl.h"
306#undef GUARD_INCLUDE_PROBFD_ALGORITHMS_EXHAUSTIVE_DFS_H
307
308#endif // PROBFD_ALGORITHMS_EXHAUSTIVE_DFS_H
A convenience class that represents a finite probability distribution.
Definition task_state_space.h:27
Interface for MDP algorithm implementations.
Definition mdp_algorithm.h:29
A registry for print functions related to search progress.
Definition progress_report.h:33
Interface providing access to various state properties during heuristic search.
Definition state_properties.h:22
An interface used to reorder a list of transitions.
Definition transition_sorter.h:27
Implementation of an anytime topological value iteration variant.
Definition exhaustive_dfs.h:210
void print_statistics(std::ostream &out) const override
Prints algorithm statistics to the specified output stream.
Definition exhaustive_dfs_impl.h:117
namespace for anytime TVI
Definition exhaustive_dfs.h:24
This namespace contains implementations of SSP search algorithms.
Definition acyclic_value_iteration.h:22
std::conditional_t< UseInterval, Interval, value_t > AlgorithmValue
Convenience value type alias for algorithms selecting interval iteration behaviour based on a templat...
Definition types.h:14
double value_t
Typedef for the state value type.
Definition aliases.h:7
typename std::conditional_t< is_cheap_to_copy_v< T >, T, const T & > param_type
Alias template defining the best way to pass a parameter of a given type.
Definition type_traits.h:25
Represents a closed interval over the extended reals as a pair of lower and upper bound.
Definition interval.h:12
A StateID represents a state within a StateIDMap. Just like Fast Downward's StateID type,...
Definition types.h:22