effspm 0.1.5__cp312-cp312-macosx_11_0_arm64.whl → 0.2.6__cp312-cp312-macosx_11_0_arm64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of effspm might be problematic. Click here for more details.

Files changed (52) hide show
  1. effspm/__init__.py +9 -2
  2. effspm/_core.cpp +91 -13
  3. effspm/_effspm.cpp +609 -0
  4. effspm/_effspm.cpython-312-darwin.so +0 -0
  5. effspm/btminer/src/build_mdd.cpp +63 -0
  6. effspm/btminer/src/build_mdd.hpp +40 -0
  7. effspm/btminer/src/freq_miner.cpp +179 -0
  8. effspm/btminer/src/freq_miner.hpp +39 -0
  9. effspm/btminer/src/load_inst.cpp +200 -0
  10. effspm/btminer/src/load_inst.hpp +25 -0
  11. effspm/btminer/src/utility.cpp +65 -0
  12. effspm/btminer/src/utility.hpp +40 -0
  13. effspm/freq_miner.hpp +7 -2
  14. effspm/htminer/src/build_mdd.cpp +192 -0
  15. effspm/htminer/src/build_mdd.hpp +64 -0
  16. effspm/htminer/src/freq_miner.cpp +350 -0
  17. effspm/htminer/src/freq_miner.hpp +60 -0
  18. effspm/htminer/src/load_inst.cpp +394 -0
  19. effspm/htminer/src/load_inst.hpp +23 -0
  20. effspm/htminer/src/utility.cpp +72 -0
  21. effspm/htminer/src/utility.hpp +77 -0
  22. effspm/largebm/src/build_mdd.cpp +137 -0
  23. effspm/largebm/src/build_mdd.hpp +47 -0
  24. effspm/largebm/src/freq_miner.cpp +349 -0
  25. effspm/largebm/src/freq_miner.hpp +48 -0
  26. effspm/largebm/src/load_inst.cpp +230 -0
  27. effspm/largebm/src/load_inst.hpp +45 -0
  28. effspm/largebm/src/utility.cpp +45 -0
  29. effspm/largebm/src/utility.hpp +18 -0
  30. effspm/largehm/src/build_mdd.cpp +174 -0
  31. effspm/largehm/src/build_mdd.hpp +93 -0
  32. effspm/largehm/src/freq_miner.cpp +445 -0
  33. effspm/largehm/src/freq_miner.hpp +77 -0
  34. effspm/largehm/src/load_inst.cpp +357 -0
  35. effspm/largehm/src/load_inst.hpp +64 -0
  36. effspm/largehm/src/utility.cpp +38 -0
  37. effspm/largehm/src/utility.hpp +29 -0
  38. effspm/largepp/src/freq_miner.cpp +170 -0
  39. effspm/largepp/src/freq_miner.hpp +43 -0
  40. effspm/largepp/src/load_inst.cpp +219 -0
  41. effspm/largepp/src/load_inst.hpp +28 -0
  42. effspm/largepp/src/utility.cpp +34 -0
  43. effspm/largepp/src/utility.hpp +21 -0
  44. effspm/load_inst.hpp +18 -12
  45. effspm-0.2.6.dist-info/METADATA +237 -0
  46. effspm-0.2.6.dist-info/RECORD +53 -0
  47. {effspm-0.1.5.dist-info → effspm-0.2.6.dist-info}/WHEEL +1 -2
  48. effspm/_core.cpython-312-darwin.so +0 -0
  49. effspm-0.1.5.dist-info/METADATA +0 -38
  50. effspm-0.1.5.dist-info/RECORD +0 -14
  51. {effspm-0.1.5.dist-info → effspm-0.2.6.dist-info}/licenses/LICENSE +0 -0
  52. {effspm-0.1.5.dist-info → effspm-0.2.6.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,230 @@
1
+
2
+ #include <sstream>
3
+ #include <algorithm>
4
+ #include <cmath>
5
+ #include <ctime>
6
+ #include <iostream> // for std::cout, std::endl
7
+ #include <fstream>
8
+ #include <vector>
9
+ #include <string>
10
+
11
+ #include "load_inst.hpp"
12
+ #include "build_mdd.hpp"
13
+ #include "utility.hpp"
14
+ #include "freq_miner.hpp"
15
+
16
+ namespace largebm {
17
+
18
+ // ── global definitions ────────────────────────────────────────────
19
+ bool use_list = false;
20
+ bool b_disp = false;
21
+ bool b_write = false;
22
+ bool use_dic = false;
23
+ bool just_build = false;
24
+ bool pre_pro = false;
25
+ bool itmset_exists = false;
26
+
27
+ unsigned int M = 0, L = 0, time_limit = 0;
28
+ unsigned long long N = 0, num_nodes = 0, theta = 0, E = 0;
29
+ std::clock_t start_time = 0;
30
+
31
+ std::vector<int> item_dic;
32
+ std::vector<Pattern> DFS;
33
+ std::vector<std::vector<int>> items;
34
+ std::vector<std::vector<int>> collected;
35
+ std::vector<int> inv_item_dic;
36
+
37
+ std::string out_file, folder;
38
+
39
+ // ───────────── helper for list‐mode DB build ─────────────────────
40
+ static void Load_items_list(const std::string& fname) {
41
+ std::ifstream in(fname);
42
+ if (!in.good()) return;
43
+ std::string line;
44
+ while (std::getline(in, line)) {
45
+ std::istringstream iss(line);
46
+ std::vector<int> seq;
47
+ int x;
48
+ while (iss >> x) {
49
+ int a = std::abs(x);
50
+ if (a < 1 || a > static_cast<int>(item_dic.size())) continue;
51
+ if (item_dic[a - 1] == -1) continue;
52
+ seq.push_back(x);
53
+ }
54
+ if (!seq.empty()) items.push_back(std::move(seq));
55
+ }
56
+ }
57
+
58
+ // ─────────────── main loader ─────────────────────────────────────
59
+ bool Load_instance(const std::string& items_file, double minsup) {
60
+ // reset state
61
+ N = L = num_nodes = theta = M = E = 0;
62
+ start_time = std::clock();
63
+
64
+ DFS.clear();
65
+ Tree.clear();
66
+ items.clear();
67
+ collected.clear();
68
+ item_dic.clear();
69
+ inv_item_dic.clear();
70
+ itmset_exists = false;
71
+
72
+ std::clock_t kk = start_time;
73
+ Tree.emplace_back(0, 0, 0); // root
74
+
75
+ if (use_list) {
76
+ if (!Preprocess(items_file, minsup)) return false;
77
+ inv_item_dic.assign(L + 1, 0);
78
+ for (int old = 1; old <= static_cast<int>(item_dic.size()); ++old) {
79
+ int cid = item_dic[old - 1];
80
+ if (cid > 0) inv_item_dic[cid] = old;
81
+ }
82
+ Load_items_list(items_file);
83
+ N = items.size();
84
+ theta = (minsup < 1.0)
85
+ ? static_cast<unsigned long long>(std::ceil(minsup * N))
86
+ : static_cast<unsigned long long>(minsup);
87
+ return true;
88
+ }
89
+
90
+ // MDD build mode
91
+ if (pre_pro) {
92
+ if (!Preprocess(items_file, minsup)) return false;
93
+ std::cout << "\nPreprocess done in "
94
+ << give_time(std::clock() - kk)
95
+ << " seconds\n\n";
96
+ DFS.clear();
97
+ DFS.reserve(L);
98
+ for (unsigned int i = 0; i < L; ++i)
99
+ DFS.emplace_back(-int(i) - 1);
100
+ kk = std::clock();
101
+ Load_items_pre(items_file);
102
+ } else {
103
+ if (!Preprocess(items_file, 0.0)) return false;
104
+ kk = std::clock();
105
+ Load_items(items_file);
106
+ }
107
+
108
+ std::cout << "\nMDD Database built in "
109
+ << give_time(std::clock() - kk)
110
+ << " seconds\n\n";
111
+ std::cout << "Found " << N
112
+ << " sequences, with max line len " << M
113
+ << ", and " << L << " items, and " << E << " entries\n";
114
+ std::cout << "Total MDD nodes: " << Tree.size() << std::endl;
115
+
116
+ return true;
117
+ }
118
+
119
+ // ────────────── Preprocess (list mode) ───────────────────────────
120
+ bool Preprocess(const std::string& inst, double thresh) {
121
+ std::ifstream file(inst);
122
+ if (!file.good()) return false;
123
+
124
+ std::vector<unsigned long long> freq(1000000);
125
+ std::vector<unsigned long long> counted(1000000, 0);
126
+ std::string line;
127
+ while (std::getline(file, line)) {
128
+ ++N;
129
+ std::istringstream iss(line);
130
+ int x;
131
+ while (iss >> x) {
132
+ int a = std::abs(x);
133
+ L = std::max(L, static_cast<unsigned int>(a));
134
+ if (freq.size() < L) {
135
+ freq.resize(L);
136
+ counted.resize(L);
137
+ }
138
+ if (counted[a - 1] != N) {
139
+ freq[a - 1]++;
140
+ counted[a - 1] = N;
141
+ }
142
+ }
143
+ }
144
+
145
+ theta = (thresh < 1.0)
146
+ ? static_cast<unsigned long long>(std::ceil(thresh * N))
147
+ : static_cast<unsigned long long>(thresh);
148
+
149
+ item_dic.assign(L, -1);
150
+ unsigned int newid = 0;
151
+ for (unsigned int old = 1; old <= L; ++old) {
152
+ if (freq[old - 1] >= theta) {
153
+ ++newid;
154
+ item_dic[old - 1] = static_cast<int>(newid);
155
+ }
156
+ }
157
+
158
+ return true;
159
+ }
160
+
161
+ // Load_items_pre: MDD insert from file
162
+ void Load_items_pre(const std::string& inst_name) {
163
+ std::ifstream file(inst_name);
164
+ if (!file.good()) return;
165
+
166
+ std::string line;
167
+ while (std::getline(file, line)) {
168
+ std::istringstream word(line);
169
+ std::string itm;
170
+ std::vector<int> temp_vec;
171
+ bool sgn = false;
172
+ while (word >> itm) {
173
+ int ditem;
174
+ try { ditem = std::stoi(itm); } catch (...) { continue; }
175
+ int absidx = std::abs(ditem) - 1;
176
+ if (absidx < 0 || absidx >= static_cast<int>(item_dic.size())) {
177
+ if (!sgn && ditem < 0) sgn = true;
178
+ continue;
179
+ }
180
+ if (item_dic[absidx] == -1) {
181
+ if (!sgn && ditem < 0) sgn = true;
182
+ continue;
183
+ }
184
+ if (ditem > 0) { ditem = item_dic[ditem - 1]; itmset_exists = true; }
185
+ else { ditem = -item_dic[-ditem - 1]; }
186
+ if (sgn) { if (ditem > 0) ditem = -ditem; sgn = false; }
187
+ temp_vec.push_back(ditem);
188
+ }
189
+ if (temp_vec.empty()) continue;
190
+ ++N;
191
+ M = std::max<unsigned>(M, temp_vec.size());
192
+ Build_MDD(temp_vec);
193
+ }
194
+ }
195
+
196
+ // Load_items: full MDD build
197
+ bool Load_items(const std::string& inst_name) {
198
+ std::ifstream file(inst_name);
199
+ if (!file.good()) return false;
200
+
201
+ std::string line;
202
+ while (std::getline(file, line)) {
203
+ ++N;
204
+ std::istringstream word(line);
205
+ std::string itm;
206
+ std::vector<int> temp_vec;
207
+ while (word >> itm) {
208
+ int ditem;
209
+ try { ditem = std::stoi(itm); } catch (...) { continue; }
210
+ if (ditem > 0) itmset_exists = true;
211
+ unsigned int ad = static_cast<unsigned int>(std::abs(ditem));
212
+ if (L < ad) {
213
+ L = ad;
214
+ DFS.reserve(L);
215
+ while (DFS.size() < L)
216
+ DFS.emplace_back(-int(DFS.size()) - 1);
217
+ }
218
+ temp_vec.push_back(ditem);
219
+ }
220
+ if (temp_vec.size() > M) M = temp_vec.size();
221
+ Build_MDD(temp_vec);
222
+ }
223
+ return true;
224
+ }
225
+
226
+ void ClearCollected() { collected.clear(); }
227
+ const std::vector<std::vector<int>>& GetCollected() { return collected; }
228
+
229
+ } // namespace largebm
230
+
@@ -0,0 +1,45 @@
1
+ #pragma once
2
+
3
+ #include <vector>
4
+ #include <string>
5
+ #include <fstream>
6
+ #include <cmath>
7
+ #include <ctime>
8
+
9
+
10
+ namespace largebm {
11
+ using namespace std;
12
+
13
+ // forward-declare Pattern (defined in freq_miner.hpp)
14
+ class Pattern;
15
+
16
+ struct Arc;
17
+ extern std::vector<Arc> Tree; // <-- add this
18
+ void Build_MDD(const std::vector<int>& seq);
19
+ // ─── Entry points ─────────────────────────────────────────────────────────
20
+ bool Load_instance(const string& items_file, double thresh);
21
+ bool Preprocess(const string& fname, double thresh);
22
+ void Load_items_pre(const string& fname);
23
+ bool Load_items(const string& fname);
24
+ extern std::vector<int> inv_item_dic;
25
+ // Called by the Python‐wrapper when passing a Python list of lists
26
+
27
+
28
+ // ─── Config globals (must match btminer types exactly) ────────────────────
29
+ extern string out_file, folder;
30
+ extern bool use_list;
31
+ extern bool b_disp, b_write, use_dic, just_build, pre_pro, itmset_exists;
32
+ extern unsigned int M, L, time_limit;
33
+ extern unsigned long long N, num_nodes, theta, E;
34
+ extern clock_t start_time;
35
+ // extern std::vector<Arc> Tree;
36
+ // ─── Data for list-based (LargeBTMiner) mode ───────────────────────────────
37
+ extern std::vector<std::vector<int>> items;
38
+ extern std::vector<int> item_dic;
39
+ extern std::vector<Pattern> DFS; // Pattern is now declared
40
+ extern std::vector<std::vector<int>> collected;
41
+ void ClearCollected();
42
+ const std::vector<std::vector<int>>& GetCollected();
43
+
44
+
45
+ } // namespace largebm
@@ -0,0 +1,45 @@
1
+ #include "utility.hpp"
2
+ #include "build_mdd.hpp"
3
+ #include "load_inst.hpp"
4
+
5
+ #include <vector>
6
+ #include <ctime>
7
+ #include <algorithm>
8
+
9
+ namespace largebm {
10
+
11
+ bool check_parent(unsigned long long cur_arc,
12
+ unsigned long long str_pnt,
13
+ unsigned long long start,
14
+ std::vector<unsigned long long>& strpnt_vec)
15
+ {
16
+ std::vector<unsigned long long> ancestors;
17
+
18
+ unsigned long long cur_anct = Tree[cur_arc].anct;
19
+
20
+ while (Tree[cur_anct].itmset > Tree[str_pnt].itmset) {
21
+ if (Tree[cur_anct].item > 0)
22
+ ancestors.push_back(cur_anct);
23
+ cur_anct = Tree[cur_anct].anct;
24
+ }
25
+
26
+ if (Tree[cur_anct].itmset == Tree[str_pnt].itmset)
27
+ return true;
28
+ else {
29
+ for (auto it = ancestors.rbegin(); it != ancestors.rend(); ++it) {
30
+ for (unsigned long long i = start; i < strpnt_vec.size(); ++i) {
31
+ if (strpnt_vec[i] == *it)
32
+ return true;
33
+ }
34
+ }
35
+ }
36
+
37
+ return false;
38
+ }
39
+
40
+ // return elapsed time in seconds
41
+ double give_time(std::clock_t ticks) {
42
+ return static_cast<double>(ticks) / CLOCKS_PER_SEC;
43
+ }
44
+
45
+ } // namespace largebm
@@ -0,0 +1,18 @@
1
+ #pragma once
2
+
3
+ #include <vector>
4
+ #include <time.h>
5
+ #include <string>
6
+ #include "build_mdd.hpp"
7
+ #include <ctime>
8
+
9
+ namespace largebm {
10
+ using namespace std;
11
+
12
+ double give_time(std::clock_t kk);
13
+
14
+
15
+
16
+ bool check_parent(unsigned long long int cur_arc, unsigned long long int str_pnt, unsigned long long int start, vector<unsigned long long int>& strpnt_vec);
17
+
18
+ }
@@ -0,0 +1,174 @@
1
+ // ─── effspm/largehm/src/build_mdd.cpp ─────────────────────────────────────────
2
+
3
+ #include "build_mdd.hpp"
4
+
5
+ // ─── Definitions of the extern globals declared in build_mdd.hpp ─────────────
6
+ std::vector<largehm::Arc> largehm::Tree;
7
+ std::vector<largehm::VArc> largehm::VTree;
8
+ std::vector<largehm::CArc> largehm::CTree;
9
+
10
+ #include <vector>
11
+ #include <iostream>
12
+ #include <cmath> // for std::abs
13
+ #include <unordered_map>
14
+ #include <cstdint> // for std::uint64_t
15
+ #include "load_inst.hpp"
16
+ #include "freq_miner.hpp"
17
+ #include "utility.hpp"
18
+
19
+ namespace largehm {
20
+
21
+ //
22
+ // ─── Build the MDD by sequentially calling Add_arc() then possibly Add_vec() ──
23
+ //
24
+ void Build_MDD(std::vector<int>& items, std::vector<int>& items_lim) {
25
+ // SANITY CHECK: show sizes before building
26
+
27
+ std::unordered_map<int, std::uint64_t> ancest_map;
28
+ std::uint64_t last_arc = 0;
29
+ int itmset = 0;
30
+
31
+ // Insert each prefix item as an arc
32
+ for (auto it = items.begin(); it != items.end(); ++it) {
33
+ last_arc = Add_arc(*it, last_arc, itmset, ancest_map);
34
+ }
35
+
36
+ // If there is a suffix beyond mlim, attach it via Add_vec()
37
+ if (!items_lim.empty()) {
38
+ Add_vec(items_lim, ancest_map, last_arc, itmset);
39
+ }
40
+ }
41
+
42
+
43
+ //
44
+ // ─── Add_arc: insert a single “item” into the MDD under parent last_arc. ──────
45
+ //
46
+ int Add_arc(int item,
47
+ std::uint64_t last_arc,
48
+ int& itmset,
49
+ std::unordered_map<int, std::uint64_t>& ancest_map)
50
+ {
51
+ // Ensure DFS is at least size |item|
52
+ size_t needed = static_cast<size_t>(std::abs(item));
53
+ if (DFS.size() < needed) {
54
+ size_t old = DFS.size();
55
+ DFS.resize(needed);
56
+ for (size_t i = old; i < needed; ++i) {
57
+ DFS[i] = Pattern(-static_cast<int>(i) - 1);
58
+ }
59
+ }
60
+
61
+ unsigned int anct = 0;
62
+ auto p = ancest_map.find(std::abs(item));
63
+ if (p != ancest_map.end()) {
64
+ anct = p->second;
65
+ }
66
+
67
+ if (item < 0) {
68
+ ++itmset;
69
+ }
70
+
71
+ std::uint64_t last_sibl = Tree[last_arc].chld;
72
+ if (last_sibl == 0) {
73
+ // No child yet: create a new Arc
74
+ Tree.emplace_back(item, itmset, anct);
75
+ last_sibl = Tree.size() - 1;
76
+ Tree[last_arc].chld = last_sibl;
77
+ if (anct == 0) {
78
+ DFS[std::abs(item) - 1].str_pnt.push_back(last_sibl);
79
+ }
80
+ }
81
+ else {
82
+ // Traverse siblings until we find a match or append
83
+ while (Tree[last_sibl].item != item) {
84
+ if (Tree[last_sibl].sibl == 0) {
85
+ Tree.emplace_back(item, itmset, anct);
86
+ Tree[last_sibl].sibl = Tree.size() - 1;
87
+ last_sibl = Tree.size() - 1;
88
+ if (anct == 0) {
89
+ DFS[std::abs(item) - 1].str_pnt.push_back(last_sibl);
90
+ }
91
+ break;
92
+ }
93
+ last_sibl = Tree[last_sibl].sibl;
94
+ }
95
+ }
96
+
97
+ if (anct == 0) {
98
+ ++DFS[std::abs(item) - 1].freq;
99
+ }
100
+ ++Tree[last_sibl].freq;
101
+ ancest_map[std::abs(item)] = last_sibl;
102
+ return static_cast<int>(last_sibl);
103
+ }
104
+
105
+
106
+ //
107
+ // ─── Add_vec: attach the “items_lim” vector as children/vertical arcs ─────────
108
+ //
109
+ void Add_vec(std::vector<int>& items_lim,
110
+ std::unordered_map<int, std::uint64_t>& ancest_map,
111
+ std::uint64_t last_arc,
112
+ int itmset)
113
+ {
114
+ // Ensure VDFS and DFS are at least size L
115
+ if (VDFS.size() < static_cast<size_t>(L)) {
116
+ size_t old = VDFS.size();
117
+ VDFS.resize(static_cast<size_t>(L));
118
+ for (size_t i = old; i < VDFS.size(); ++i) {
119
+ VDFS[i] = VPattern(static_cast<int>(i));
120
+ }
121
+ }
122
+ if (DFS.size() < static_cast<size_t>(L)) {
123
+ size_t old = DFS.size();
124
+ DFS.resize(static_cast<size_t>(L));
125
+ for (size_t i = old; i < DFS.size(); ++i) {
126
+ DFS[i] = Pattern(-static_cast<int>(i) - 1);
127
+ }
128
+ }
129
+
130
+ items_lim.shrink_to_fit();
131
+ std::vector<bool> counted(L, false);
132
+
133
+ // If this node has positive itmset (>0) or no CTree child yet, create first child entry
134
+ if (Tree[last_arc].itmset > 0 || Tree[last_arc].chld == 0) {
135
+ std::vector<std::uint64_t> ancest(L + 1, 0ULL);
136
+ for (auto& kv : ancest_map) {
137
+ ancest[kv.first - 1] = kv.second;
138
+ counted[kv.first - 1] = true;
139
+ }
140
+ for (int i = 0; i < static_cast<int>(items_lim.size()); ++i) {
141
+ int cur_itm = std::abs(items_lim[i]);
142
+ if (!counted[cur_itm - 1]) {
143
+ if (i + 1 < static_cast<int>(items_lim.size())) {
144
+ VDFS[cur_itm - 1].str_pnt.push_back(-i - 1);
145
+ VDFS[cur_itm - 1].seq_ID.push_back(CTree.size());
146
+ }
147
+ ++DFS[cur_itm - 1].freq;
148
+ counted[cur_itm - 1] = true;
149
+ }
150
+ }
151
+ CTree.emplace_back(ancest, items_lim);
152
+ Tree[last_arc].chld = CTree.size() - 1;
153
+ Tree[last_arc].itmset = -itmset;
154
+ }
155
+ else {
156
+ // Normal “existing CTree child” path
157
+ auto& ancest = CTree[ Tree[last_arc].chld ].ancest;
158
+ for (int i = 0; i < static_cast<int>(items_lim.size()); ++i) {
159
+ int cur_itm = std::abs(items_lim[i]);
160
+ if (!counted[cur_itm - 1] && ancest[cur_itm - 1] == 0ULL) {
161
+ if (i + 1 < static_cast<int>(items_lim.size())) {
162
+ VDFS[cur_itm - 1].str_pnt.push_back(i + 1);
163
+ VDFS[cur_itm - 1].seq_ID.push_back(VTree.size());
164
+ }
165
+ ++DFS[cur_itm - 1].freq;
166
+ counted[cur_itm - 1] = true;
167
+ }
168
+ }
169
+ VTree.emplace_back(items_lim, CTree[ Tree[last_arc].chld ].ancest.back());
170
+ CTree[ Tree[last_arc].chld ].ancest.back() = VTree.size();
171
+ }
172
+ }
173
+
174
+ } // namespace largehm
@@ -0,0 +1,93 @@
1
+ #ifndef LARGEHM_BUILD_MDD_HPP
2
+ #define LARGEHM_BUILD_MDD_HPP
3
+
4
+ #include <vector>
5
+ #include <unordered_map>
6
+ #include <cstddef> // for size_t
7
+ #include <cstdint> // for uint64_t
8
+
9
+ #include "load_inst.hpp" // defines L, DFS, VDFS, Tree, etc.
10
+ #include "freq_miner.hpp" // for Pattern, VPattern
11
+ #include "utility.hpp" // if you need check_parent or collected
12
+
13
+ namespace largehm {
14
+
15
+ //
16
+ // ─── Types & Globals ─────────────────────────────────────────────────────────
17
+ //
18
+
19
+ struct Arc;
20
+ struct VArc;
21
+ struct CArc;
22
+
23
+ extern std::vector<Arc> Tree;
24
+ extern std::vector<VArc> VTree;
25
+ extern std::vector<CArc> CTree;
26
+
27
+ //
28
+ // ─── Public API ───────────────────────────────────────────────────────────────
29
+ //
30
+
31
+ void Build_MDD(std::vector<int>& items,
32
+ std::vector<int>& items_lim);
33
+
34
+ //
35
+ // ─── Internal Helpers ─────────────────────────────────────────────────────────
36
+ //
37
+
38
+ int Add_arc(int item,
39
+ std::uint64_t last_arc,
40
+ int& itmset,
41
+ std::unordered_map<int, std::uint64_t>& ancest_map);
42
+
43
+ void Add_vec(std::vector<int>& items_lim,
44
+ std::unordered_map<int, std::uint64_t>& ancest_map,
45
+ std::uint64_t last_arc,
46
+ int itmset);
47
+
48
+ //
49
+ // ─── Struct Definitions ───────────────────────────────────────────────────────
50
+ //
51
+
52
+ struct Arc {
53
+ int item;
54
+ int itmset;
55
+ std::uint64_t anct;
56
+ std::uint64_t chld;
57
+ std::uint64_t sibl;
58
+ unsigned long long freq;
59
+
60
+ Arc(int _item, int _itmset, std::uint64_t _anct)
61
+ : item(_item), itmset(_itmset), anct(_anct),
62
+ chld(0), sibl(0), freq(0u) {}
63
+ };
64
+
65
+ struct VArc {
66
+ std::vector<int> seq;
67
+ std::uint64_t sibl;
68
+ unsigned long long freq;
69
+
70
+ explicit VArc(std::vector<int>& items, std::uint64_t _sibl)
71
+ : seq(), sibl(_sibl), freq(0u)
72
+ {
73
+ seq.swap(items);
74
+ }
75
+ };
76
+
77
+ struct CArc {
78
+ std::vector<std::uint64_t> ancest;
79
+ std::vector<int> seq;
80
+ unsigned long long freq;
81
+
82
+ explicit CArc(std::vector<std::uint64_t>& _anc,
83
+ std::vector<int>& items)
84
+ : ancest(), seq(), freq(0u)
85
+ {
86
+ ancest.swap(_anc);
87
+ seq.swap(items);
88
+ }
89
+ };
90
+
91
+ } // namespace largehm
92
+
93
+ #endif // LARGEHM_BUILD_MDD_HPP