1#ifndef PDBS_DOMINANCE_PRUNING_H
2#define PDBS_DOMINANCE_PRUNING_H
4#include "downward/pdbs/types.h"
6#include "downward/pdbs/pattern_database.h"
8#include "downward/utils/countdown_timer.h"
9#include "downward/utils/hash.h"
10#include "downward/utils/logging.h"
50 const PatternCollection& patterns;
51 const std::vector<PatternClique>& pattern_cliques;
52 const int num_variables;
54 std::vector<int> variable_to_pattern_id;
55 std::vector<bool> dominated_patterns;
57 void set_current_clique(
int clique_id)
64 variable_to_pattern_id.assign(num_variables, -1);
65 assert(variable_to_pattern_id == std::vector<int>(num_variables, -1));
66 for (PatternID pattern_id : pattern_cliques[clique_id]) {
67 for (
int variable : patterns[pattern_id]) {
68 assert(variable_to_pattern_id[variable] == -1);
69 variable_to_pattern_id[variable] = pattern_id;
73 dominated_patterns.clear();
74 dominated_patterns.reserve(patterns.size());
75 for (
size_t i = 0; i < patterns.size(); ++i) {
76 dominated_patterns.push_back(is_pattern_dominated(i));
80 bool is_pattern_dominated(
int pattern_id)
const
86 const Pattern& pattern = patterns[pattern_id];
87 assert(!pattern.empty());
88 PatternID clique_pattern_id = variable_to_pattern_id[pattern[0]];
89 if (clique_pattern_id == -1) {
92 int pattern_size = pattern.size();
93 for (
int i = 1; i < pattern_size; ++i) {
94 if (variable_to_pattern_id[pattern[i]] != clique_pattern_id) {
101 bool is_clique_dominated(
int clique_id)
const
107 for (PatternID pattern_id : pattern_cliques[clique_id]) {
108 if (!dominated_patterns[pattern_id]) {
117 const PatternCollection& patterns,
118 const std::vector<PatternClique>& pattern_cliques,
121 , pattern_cliques(pattern_cliques)
122 , num_variables(num_variables)
127 get_pruned_cliques(
const utils::CountdownTimer& timer, utils::LogProxy& log)
129 int num_cliques = pattern_cliques.size();
130 std::vector<bool> pruned(num_cliques,
false);
137 for (
int c1 = 0; c1 < num_cliques; ++c1) {
139 set_current_clique(c1);
140 for (
int c2 = 0; c2 < num_cliques; ++c2) {
141 if (c1 != c2 && !pruned[c2] && is_clique_dominated(c2))
145 if (timer.is_expired()) {
152 if (log.is_at_least_normal()) {
153 log <<
"Time limit reached. Abort dominance pruning."
170extern void prune_dominated_cliques(
171 PatternCollection& patterns,
172 std::vector<T>& pdbs,
173 std::vector<PatternClique>& pattern_cliques,
176 utils::LogProxy& log)
178 utils::CountdownTimer timer(max_time);
180 int num_patterns = patterns.size();
181 int num_cliques = pattern_cliques.size();
183 std::vector<bool> pruned = Pruner(patterns, pattern_cliques, num_variables)
184 .get_pruned_cliques(timer, log);
186 std::vector<PatternClique> remaining_pattern_cliques;
187 std::vector<bool> is_remaining_pattern(num_patterns,
false);
188 int num_remaining_patterns = 0;
189 for (
size_t i = 0; i < pattern_cliques.size(); ++i) {
191 PatternClique& clique = pattern_cliques[i];
192 for (PatternID pattern_id : clique) {
193 if (!is_remaining_pattern[pattern_id]) {
194 is_remaining_pattern[pattern_id] =
true;
195 ++num_remaining_patterns;
198 remaining_pattern_cliques.push_back(std::move(clique));
202 PatternCollection remaining_patterns;
203 std::vector<T> remaining_pdbs;
204 remaining_patterns.reserve(num_remaining_patterns);
205 remaining_pdbs.reserve(num_remaining_patterns);
206 std::vector<PatternID> old_to_new_pattern_id(num_patterns, -1);
207 for (PatternID old_pattern_id = 0; old_pattern_id < num_patterns;
209 if (is_remaining_pattern[old_pattern_id]) {
210 PatternID new_pattern_id = remaining_patterns.size();
211 old_to_new_pattern_id[old_pattern_id] = new_pattern_id;
212 remaining_patterns.push_back(std::move(patterns[old_pattern_id]));
213 remaining_pdbs.push_back(std::move(pdbs[old_pattern_id]));
216 for (PatternClique& clique : remaining_pattern_cliques) {
217 for (
size_t i = 0; i < clique.size(); ++i) {
218 PatternID old_pattern_id = clique[i];
219 PatternID new_pattern_id = old_to_new_pattern_id[old_pattern_id];
220 assert(new_pattern_id != -1);
221 clique[i] = new_pattern_id;
225 int num_pruned_collections = num_cliques - remaining_pattern_cliques.size();
226 int num_pruned_patterns = num_patterns - num_remaining_patterns;
228 patterns.swap(remaining_patterns);
229 pdbs.swap(remaining_pdbs);
230 pattern_cliques.swap(remaining_pattern_cliques);
232 if (log.is_at_least_normal()) {
233 log <<
"Pruned " << num_pruned_collections <<
" of " << num_cliques
234 <<
" pattern cliques" << std::endl;
235 log <<
"Pruned " << num_pruned_patterns <<
" of " << num_patterns
236 <<
" PDBs" << std::endl;
237 log <<
"Dominance pruning took " << timer.get_elapsed_time()