AI 24/25 Project Software
Documentation for the AI 24/25 course programming project software
Loading...
Searching...
No Matches
pattern_collection_generator_genetic.h
1#ifndef PDBS_PATTERN_COLLECTION_GENERATOR_GENETIC_H
2#define PDBS_PATTERN_COLLECTION_GENERATOR_GENETIC_H
3
4#include "downward/pdbs/pattern_generator.h"
5#include "downward/pdbs/types.h"
6
7#include <memory>
8#include <vector>
9
10class AbstractTask;
11
12namespace utils {
13class RandomNumberGenerator;
14}
15
16namespace pdbs {
17/*
18 Implementation of the pattern generation algorithm by Edelkamp. See:
19 Stefan Edelkamp, Automated Creation of Pattern Database Search
20 Heuristics. Proceedings of the 4th Workshop on Model Checking and
21 Artificial Intelligence (MoChArt 2006), pp. 35-50, 2007.
22*/
23class PatternCollectionGeneratorGenetic : public PatternCollectionGenerator {
24 // Maximum number of states for each pdb
25 const int pdb_max_size;
26 const int num_collections;
27 const int num_episodes;
28 const double mutation_probability;
29 /* Specifies whether patterns in each pattern collection need to be disjoint
30 or not. */
31 const bool disjoint_patterns;
32 std::shared_ptr<utils::RandomNumberGenerator> rng;
33
34 std::shared_ptr<AbstractTask> task;
35
36 // All current pattern collections.
37 std::vector<std::vector<std::vector<bool>>> pattern_collections;
38
39 // Store best pattern collection over all episodes and its fitness value.
40 std::shared_ptr<PatternCollection> best_patterns;
41 double best_fitness;
42
43 /*
44 The fitness values (from evaluate) are used as probabilities. Then
45 num_collections many pattern collections are chosen from the vector of all
46 pattern collections according to their probabilities. If all fitness
47 values are 0, we select uniformly randomly. Note that the set of pattern
48 collection where we select from is only changed by mutate, NOT by
49 evaluate. All changes there (i.e. transformation and removal of irrelevant
50 variables) are just temporary for improved PDB computation.
51 */
52 void select(const std::vector<double>& fitness_values);
53
54 /*
55 Iterate over all patterns and flip every variable (set 0 if 1 or 1 if 0)
56 with the given probability from options. This method does not check for
57 pdb_max_size or disjoint patterns.
58 */
59 void mutate();
60
61 /*
62 Transforms a bit vector (internal pattern representation in this class,
63 mainly for easy mutation) to the "normal" pattern form vector<int>, which
64 we need for ZeroOnePDBsHeuristic.
65 */
66 Pattern
67 transform_to_pattern_normal_form(const std::vector<bool>& bitvector) const;
68
69 /*
70 Calculates the mean h-value (fitness value) for each pattern collection.
71 For each pattern collection, we iterate over all patterns, first checking
72 whether they respect the size limit, then modifying them in a way that
73 only causally relevant variables remain in the patterns. Then the zero one
74 partitioning pattern collection heuristic is constructed and its fitness
75 ( = summed up mean h-values (dead ends are ignored) of all PDBs in the
76 collection) computed. The overall best heuristic is eventually updated and
77 saved for further episodes.
78 */
79 void evaluate(std::vector<double>& fitness_values);
80 bool is_pattern_too_large(const Pattern& pattern) const;
81
82 /*
83 Mark used variables in variables_used and return true iff
84 anything was already used (in which case we do not mark the
85 remaining variables).
86 */
87 bool mark_used_variables(
88 const Pattern& pattern,
89 std::vector<bool>& variables_used) const;
90 void remove_irrelevant_variables(Pattern& pattern) const;
91
92 /*
93 Calculates the initial pattern collections with a next-fit bin packing
94 algorithm. Variables are shuffled to obtain a different random ordering
95 for every pattern collection. Then, variables are inserted into a pattern
96 as long as pdb_max_sizes allows. If the "bin" is full, a new one is
97 opened. This is repeated until all variables have been treated. Every
98 initial pattern collection contains every variable exactly once and all
99 initial patterns of each pattern collection are disjoint (regardless of
100 the disjoint_patterns flag).
101 */
102 void bin_packing();
103
104 /*
105 Main genetic algorithm loop. All pattern collections are initialized with
106 bin packing. In each iteration (or episode), all patterns are first
107 mutated, then evaluated and finally some patterns in each collection are
108 selected to be part of the next episode. Note that we do not do any kind
109 of recombination.
110 */
111 void genetic_algorithm();
112
113 virtual std::string name() const override;
114 virtual PatternCollectionInformation
115 compute_patterns(const std::shared_ptr<AbstractTask>& task) override;
116
117public:
118 PatternCollectionGeneratorGenetic(
119 int pdb_max_size,
120 int num_collections,
121 int num_episodes,
122 double mutation_probability,
123 bool disjoint,
124 int random_seed,
125 utils::Verbosity verbosity);
126};
127} // namespace pdbs
128
129#endif