AI 24/25 Project Software
Documentation for the AI 24/25 course programming project software
Loading...
Searching...
No Matches
split_selector.h
1#ifndef PROBFD_CARTESIAN_ABSTRACTIONS_SPLIT_SELECTOR_H
2#define PROBFD_CARTESIAN_ABSTRACTIONS_SPLIT_SELECTOR_H
3
4#include "probfd/task_proxy.h"
5
6#include <cassert>
7#include <limits>
8#include <memory>
9#include <vector>
10
11// Forward Declarations
12class PlanningTask;
13
14namespace additive_heuristic {
15class AdditiveHeuristic;
16}
17
18namespace utils {
19class RandomNumberGenerator;
20}
21
22namespace probfd::cartesian_abstractions {
23class AbstractState;
24} // namespace probfd::cartesian_abstractions
25
26namespace probfd::cartesian_abstractions {
27
28struct Split {
29 int var_id;
30 std::vector<int> values;
31};
32
33/*
34 Select split in case there are multiple possible splits.
35*/
36class SplitSelector {
37public:
38 virtual ~SplitSelector() = default;
39
40 virtual const Split& pick_split(
41 const AbstractState& state,
42 const std::vector<Split>& splits) = 0;
43};
44
45class SplitSelectorRandom : public SplitSelector {
46 std::shared_ptr<utils::RandomNumberGenerator> rng_;
47
48public:
49 explicit SplitSelectorRandom(
50 std::shared_ptr<utils::RandomNumberGenerator> rng);
51
52 const Split&
53 pick_split(const AbstractState& state, const std::vector<Split>& splits)
54 override;
55};
56
57template <class Derived>
58class RateBasedSplitSelector : public SplitSelector {
59public:
60 const Split&
61 pick_split(const AbstractState& state, const std::vector<Split>& splits)
62 override
63 {
64
65 assert(!splits.empty());
66
67 if (splits.size() == 1) {
68 return splits[0];
69 }
70
71 double max_rating = std::numeric_limits<double>::lowest();
72 const Split* selected_split = nullptr;
73 for (const Split& split : splits) {
74 double rating =
75 static_cast<const Derived*>(this)->rate_split(state, split);
76 if (rating > max_rating) {
77 selected_split = &split;
78 max_rating = rating;
79 }
80 }
81
82 assert(selected_split);
83 return *selected_split;
84 }
85};
86
87// Number of values that land in the state whose h-value is probably raised.
88class SplitSelectorUnwanted
89 : public RateBasedSplitSelector<SplitSelectorUnwanted> {
90 const int factor_;
91
92public:
93 explicit SplitSelectorUnwanted(int factor);
94
95 [[nodiscard]]
96 double rate_split(const AbstractState& state, const Split& split) const;
97};
98
99// Refinement: - (remaining_values / original_domain_size)
100class SplitSelectorRefinedness
101 : public RateBasedSplitSelector<SplitSelectorRefinedness> {
102 const ProbabilisticTaskProxy task_proxy_;
103 const double factor_;
104
105public:
106 SplitSelectorRefinedness(
107 const std::shared_ptr<ProbabilisticTask>& task,
108 double factor);
109
110 [[nodiscard]]
111 double rate_split(const AbstractState& state, const Split& split) const;
112};
113
114// Compare the h^add(s_0) values of the facts.
115class SplitSelectorHAdd {
116 const std::shared_ptr<PlanningTask> task_;
117 const ProbabilisticTaskProxy task_proxy_;
118 std::unique_ptr<additive_heuristic::AdditiveHeuristic> additive_heuristic_;
119
120public:
121 explicit SplitSelectorHAdd(const std::shared_ptr<ProbabilisticTask>& task);
122 ~SplitSelectorHAdd();
123
124protected:
125 [[nodiscard]]
126 int get_hadd_value(int var_id, int value) const;
127};
128
129class SplitSelectorMinHAdd
130 : public RateBasedSplitSelector<SplitSelectorMinHAdd>
131 , public SplitSelectorHAdd {
132public:
133 explicit SplitSelectorMinHAdd(
134 const std::shared_ptr<ProbabilisticTask>& task);
135
136 [[nodiscard]]
137 double rate_split(const AbstractState& state, const Split& split) const;
138
139private:
140 [[nodiscard]]
141 int get_min_hadd_value(int var_id, const std::vector<int>& values) const;
142};
143
144class SplitSelectorMaxHAdd
145 : public RateBasedSplitSelector<SplitSelectorMaxHAdd>
146 , public SplitSelectorHAdd {
147public:
148 explicit SplitSelectorMaxHAdd(
149 const std::shared_ptr<ProbabilisticTask>& task);
150
151 [[nodiscard]]
152 double rate_split(const AbstractState& state, const Split& split) const;
153
154private:
155 [[nodiscard]]
156 int get_max_hadd_value(int var_id, const std::vector<int>& values) const;
157};
158
159/*
160 Select split in case there are multiple possible splits.
161*/
162class SplitSelectorFactory {
163public:
164 virtual ~SplitSelectorFactory() = default;
165
166 virtual std::unique_ptr<SplitSelector>
167 create_split_selector(const std::shared_ptr<ProbabilisticTask>& task) = 0;
168};
169
170/*
171 Select split in case there are multiple possible splits.
172*/
173class SplitSelectorRandomFactory : public SplitSelectorFactory {
174 std::shared_ptr<utils::RandomNumberGenerator> rng_;
175
176public:
177 explicit SplitSelectorRandomFactory(
178 std::shared_ptr<utils::RandomNumberGenerator> rng);
179
180 std::unique_ptr<SplitSelector> create_split_selector(
181 const std::shared_ptr<ProbabilisticTask>& task) override;
182};
183
184/*
185 Select split in case there are multiple possible splits.
186*/
187class SplitSelectorMinUnwantedFactory : public SplitSelectorFactory {
188public:
189 std::unique_ptr<SplitSelector> create_split_selector(
190 const std::shared_ptr<ProbabilisticTask>& task) override;
191};
192
193/*
194 Select split in case there are multiple possible splits.
195*/
196class SplitSelectorMaxUnwantedFactory : public SplitSelectorFactory {
197public:
198 std::unique_ptr<SplitSelector> create_split_selector(
199 const std::shared_ptr<ProbabilisticTask>& task) override;
200};
201
202/*
203 Select split in case there are multiple possible splits.
204*/
205class SplitSelectorMinRefinedFactory : public SplitSelectorFactory {
206public:
207 std::unique_ptr<SplitSelector> create_split_selector(
208 const std::shared_ptr<ProbabilisticTask>& task) override;
209};
210
211/*
212 Select split in case there are multiple possible splits.
213*/
214class SplitSelectorMaxRefinedFactory : public SplitSelectorFactory {
215public:
216 std::unique_ptr<SplitSelector> create_split_selector(
217 const std::shared_ptr<ProbabilisticTask>& task) override;
218};
219
220/*
221 Select split in case there are multiple possible splits.
222*/
223class SplitSelectorMinHAddFactory : public SplitSelectorFactory {
224public:
225 std::unique_ptr<SplitSelector> create_split_selector(
226 const std::shared_ptr<ProbabilisticTask>& task) override;
227};
228
229/*
230 Select split in case there are multiple possible splits.
231*/
232class SplitSelectorMaxHAddFactory : public SplitSelectorFactory {
233public:
234 std::unique_ptr<SplitSelector> create_split_selector(
235 const std::shared_ptr<ProbabilisticTask>& task) override;
236};
237
238} // namespace probfd::cartesian_abstractions
239
240#endif // PROBFD_CARTESIAN_ABSTRACTIONS_SPLIT_SELECTOR_H