OILS / vendor / souffle / utility / SubsetCache.h View on Github | oilshell.org

61 lines, 25 significant
1/*
2 * Souffle - A Datalog Compiler
3 * Copyright (c) 2022, The Souffle Developers. All rights reserved
4 * Licensed under the Universal Permissive License v 1.0 as shown at:
5 * - https://opensource.org/licenses/UPL
6 * - <souffle root>/licenses/SOUFFLE-UPL.txt
7 */
8
9/************************************************************************
10 *
11 * @file SubsetCache.h
12 *
13 * Data structure for efficiently generating subsets without recomputation
14 *
15 ***********************************************************************/
16
17#pragma once
18
19namespace souffle {
20
21class SubsetCache {
22public:
23 using PowerSet = std::set<std::vector<std::size_t>>;
24
25 const PowerSet& getSubsets(std::size_t N, std::size_t K) const {
26 if (cache.count({N, K})) {
27 return cache.at({N, K});
28 }
29
30 PowerSet res;
31
32 // generate the next permutation of the bitmask
33 std::vector<std::size_t> cur;
34 cur.reserve(K);
35
36 // use bitmask for subset generation
37 std::string bitmask(K, 1); // K leading 1's
38 bitmask.resize(N, 0); // N-K trailing 0's
39
40 // generate the combination while there are combinations to go
41 do {
42 cur.clear();
43
44 // construct the subset using the set bits in the bitmask
45 for (std::size_t i = 0; i < N; ++i) // [0..N-1] integers
46 {
47 if (bitmask[i]) {
48 cur.push_back(i);
49 }
50 }
51 res.insert(cur);
52 } while (std::prev_permutation(bitmask.begin(), bitmask.end()));
53 cache[std::make_pair(N, K)] = res;
54 return cache.at({N, K});
55 }
56
57private:
58 mutable std::map<std::pair<std::size_t, std::size_t>, PowerSet> cache;
59};
60
61} // namespace souffle