16 const Node& node = data_[idx];
17 if (node.actions_ == 0) {
19 n->data.condition = rs_.conditions[node.max_gain_index_];
21 size_t pow3 = pow3_[node.max_gain_index_];
22 size_t idx1 = idx - pow3;
23 size_t idx0 = idx1 - pow3;
25 CreateTreeRec(t, n->left = t.
make_node(), idx0);
26 CreateTreeRec(t, n->right = t.
make_node(), idx1);
30 n->data.action = node.actions_;
35 std::string s(nbits,
'0');
37 for (
size_t pos = 0; pos < nbits; ++pos) {
38 if ((indif >> pos) & 1) {
39 s[nbits - 1 - pos] =
'-';
42 s[nbits - 1 - pos] = ((value >> vbits) & 1) + 48;
50 static inline int __builtin_ctz(
unsigned x) {
52 _BitScanForward(&ret, x);
60 #ifdef HYPERCUBE_VERBOSE
62 for (
size_t i = 0; i < 1ull << nbits_; ++i) {
63 size_t idx = GetIndex(i);
65 if (data_[idx].actions_ == 0) {
69 for (
size_t i = 1; i < 128; i++) {
70 if (data_[idx].actions_[i - 1]) {
71 std::cout << i <<
",";
77 std::cout <<
"------------------------\n";
80 for (
size_t num_indif = 1; num_indif <= nbits_; num_indif++) {
81 #ifndef HYPERCUBE_VERBOSE
82 std::cout << num_indif <<
" " << std::flush;
85 int indif = (1 << num_indif) - 1;
86 int last = indif << (nbits_ - num_indif);
92 int max_value = 1 << (nbits_ - num_indif);
93 for (
int i = 0; i < max_value; ++i) {
94 #ifdef HYPERCUBE_VERBOSE
98 size_t idx = GetIndexWithIndifference(i, indif);
99 int tmp_indif = indif;
101 Node& max_gain_node = data_[idx];
102 while (tmp_indif>0) {
104 size_t pow3 = pow3_[pos_indif];
105 size_t idx1 = idx - pow3;
106 size_t idx0 = idx1 - pow3;
108 Node& node0 = data_[idx0], node1 = data_[idx1];
123 #ifdef HYPERCUBE_VERBOSE
124 nodes_.push_back(cur_node);
131 max_gain_node = cur_node;
140 #ifdef HYPERCUBE_VERBOSE
142 if (data_[idx].actions_ == 0) {
146 for (
size_t i = 1; i < 128; i++) {
147 if (data_[idx].actions_[i - 1]) {
148 std::cout << i <<
",";
153 for (
const auto& x : nodes_) {
154 std::cout << x.gain_;
157 else if (x.gain_ == max_gain_node.
gain_)
161 std::cout << max_gain_node.
num_equiv_ <<
"\n";
164 #ifdef HYPERCUBE_VERBOSE
173 int t = indif | (indif - 1);
174 indif = (t + 1) | (((~t & -~t) - 1) >> (__builtin_ctz(indif) + 1));
176 #ifdef HYPERCUBE_VERBOSE
177 std::cout <<
"------------------------\n";
182 CreateTreeRec(t, t.
make_root(), data_.size() - 1);
187 TLOG(
"Allocating hypercube",
191 TLOG(
"Optimizing rules",
192 auto t = hcube.Optimize();
node * make_root()
Creates a new root updating the roots_ vector.
node * make_node(Args &&... args)
Creates and returns a new node updating the nodes_ vector.
bool WriteConactTree(const BinaryDrag< conact > &t, const string &filename)
bool LoadConactTree(BinaryDrag< conact > &t, const string &filename)
std::string BinaryWithIndifference(size_t value, size_t indif, size_t nbits)
BinaryDrag< conact > GetOdt(const rule_set &rs, bool force_generation)
Returns the optimal (or pseudo optimal) decision tree generated from the given rule set.
BinaryDrag< conact > GenerateOdt(const rule_set &rs, const string &filename)
BinaryDrag< conact > GetOdtWithFileSuffix(const rule_set &rs, const string &file_suffix, bool force_generation)
std::filesystem::path GetCustomOdtPath(const std::string &custom_suffix) const
std::filesystem::path odt_path_
bool force_odt_generation_
unsigned long long frequency_
std::bitset< 131 > actions_
#define TLOG(message, instructions)