AI 24/25 Project Software
Documentation for the AI 24/25 course programming project software
Loading...
Searching...
No Matches
equivalence_relation.h
1#ifndef ALGORITHMS_EQUIVALENCE_RELATION_H
2#define ALGORITHMS_EQUIVALENCE_RELATION_H
3
4#include <algorithm>
5#include <cmath>
6#include <list>
7#include <unordered_map>
8#include <vector>
9
10namespace equivalence_relation {
11class Block;
12class EquivalenceRelation;
13
14using ElementListIter = std::list<int>::iterator;
15using ElementListConstIter = std::list<int>::const_iterator;
16using BlockListIter = std::list<Block>::iterator;
17using BlockListConstIter = std::list<Block>::const_iterator;
18
19class Block {
20 std::list<int> elements;
21 /*
22 During the refinement step of EquivalenceRelation, every existing block B
23 is split along every new block X into the intersection and difference of
24 B and X. The way the algorithm is set up, the difference remains in the
25 block that previously represented B. To store the intersection, a new
26 block is created and stored in B for easier access.
27 */
28 friend class EquivalenceRelation;
29 BlockListIter it_intersection_block;
30
31public:
32 bool empty() const { return elements.empty(); }
33
34 ElementListIter insert(int element)
35 {
36 return elements.insert(elements.end(), element);
37 }
38
39 void erase(ElementListIter it) { elements.erase(it); }
40
41 ElementListIter begin() { return elements.begin(); }
42
43 ElementListIter end() { return elements.end(); }
44
45 ElementListConstIter begin() const { return elements.begin(); }
46
47 ElementListConstIter end() const { return elements.end(); }
48};
49
50class EquivalenceRelation {
51 std::list<Block> blocks;
52 /*
53 With each element we associate a pair of iterators (block_it, element_it).
54 block_it is an iterator from the list blocks pointing to the block that
55 contains the element and element_it is an iterator from the list in this
56 block and points to the element within it.
57 */
58 using ElementPosition = std::pair<BlockListIter, ElementListIter>;
59 using ElementPositionMap = std::unordered_map<int, ElementPosition>;
60 ElementPositionMap element_positions;
61
62 BlockListIter add_empty_block();
63
64public:
65 explicit EquivalenceRelation(const std::vector<int>& elements);
66
67 BlockListConstIter begin() const { return blocks.begin(); }
68 BlockListConstIter end() const { return blocks.end(); }
69
70 /*
71 Refining a relation with a block X is equivalent to splitting every block
72 B into two blocks (B \cap X) and (B \setminus X). After refining, two
73 items A and B are in the same block if and only if they were in the same
74 block before and they are in one block in the other relation. The
75 amortized runtime is linear in the number of elements specified in other.
76 */
77 void refine(const std::vector<int>& block);
78};
79}
80
81#endif