Version: 1.0
hypercube++.h
Go to the documentation of this file.
1 // Copyright (c) 2020, the GRAPHGEN contributors, as
2 // shown by the AUTHORS file. All rights reserved.
3 //
4 // Use of this source code is governed by a BSD-style
5 // license that can be found in the LICENSE file.
6 
7 #ifndef GRAPHGEN_HYPERCUBEPP_H_
8 #define GRAPHGEN_HYPERCUBEPP_H_
9 
10 #include <algorithm>
11 #include <cassert>
12 #include <iostream>
13 
14 #include "conact_tree.h"
15 #include "rule_set.h"
16 
17 namespace hyper {
18 
19 template <typename T>
20 std::istream& rawread(std::istream& is, T& val, size_t n) {
21  return is.read(reinterpret_cast<char*>(&val), n);
22 }
23 template <typename T>
24 std::ostream& rawwrite(std::ostream& os, const T& val, size_t n) {
25  return os.write(reinterpret_cast<const char*>(&val), n);
26 }
27 
28 class HyperCube {
29  size_t GetIndexWithIndifference(size_t value, size_t indif) {
30  size_t index = 0;
31  int vbits = 0;
32  for (size_t pos = 0; pos < nbits_; ++pos) {
33  if ((indif >> pos) & 1) {
34  index += 2 * pow3_[pos];
35  }
36  else {
37  index += ((value >> vbits) & 1)*pow3_[pos];
38  ++vbits;
39  }
40  }
41  return index;
42  }
43 
44  size_t GetIndex(size_t value) {
45  size_t index = 0;
46  for (int pos = 0; pos < static_cast<int>(nbits_); ++pos) {
47  index += ((value >> pos) & 1)*pow3_[pos];
48  }
49  return index;
50  }
51 
52  void CreateTreeRec(BinaryDrag<conact>& t, BinaryDrag<conact>::node *n, size_t idx) const;
53 
54 public:
55 
56 #pragma pack(push)
57 #pragma pack(1)
58  struct Node {
59  std::bitset<131/*CTBE needs 131 bits*/> actions_ = 0;
60  unsigned long long frequency_ = 1;
61  unsigned long long gain_ = 0;
62  uint8_t max_gain_index_ = 0;
63  unsigned int num_equiv_ = 0;
64  };
65 #pragma pack(pop)
66 
67  size_t nbits_;
68  std::vector<Node> data_;
69  const rule_set& rs_;
70  std::vector<size_t> pow3_;
71 
72  HyperCube(const rule_set& rs)
73  : rs_(rs), nbits_(rs.conditions.size()),
74  data_(size_t(pow(3.0, rs.conditions.size()))), pow3_(rs.conditions.size())
75  {
76  // Initialize vector of powers of 3
77  pow3_[0] = 1;
78  for (size_t i = 1; i < nbits_; ++i) {
79  pow3_[i] = pow3_[i - 1] * 3;
80  }
81 
82  // Initialize hypercube nodes using the rules defined in the ruleset
83  auto nrules = rs.rules.size();
84  for (size_t i = 0; i < nrules; ++i) {
85  // for each rule generate the hypercube index
86  size_t idx = GetIndex(i);
87  // and set its values
88  data_[idx].frequency_ = rs.rules[i].frequency;
89  data_[idx].actions_ = rs.rules[i].actions;
90  }
91  }
92 
93  std::istream& read(std::istream& is) {
94  return rawread(is, data_[0], data_.size() * sizeof(Node));
95  }
96  std::ostream& write(std::ostream& os) {
97  return rawwrite(os, data_[0], data_.size() * sizeof(Node));
98  }
99 
100  Node& operator[](size_t idx) { return data_[idx]; }
101  const Node& operator[](size_t idx) const { return data_[idx]; }
102 
104 };
105 
106 // Generates an Optimal Decision Tree from the given rule_set,
107 // and store it in the filename when specified.
109 BinaryDrag<conact> GenerateOdt(const rule_set& rs, const std::string& filename);
110 
123 BinaryDrag<conact> GetOdt(const rule_set& rs, bool force_generation = false);
124 
125 
139 BinaryDrag<conact> GetOdtWithFileSuffix(const rule_set& rs, const std::string& file_suffix, bool force_generation = false);
140 
141 }
142 
143 #endif // !GRAPHGEN_HYPERCUBEPP_H_
Node & operator[](size_t idx)
Definition: hypercube++.h:100
HyperCube(const rule_set &rs)
Definition: hypercube++.h:72
std::ostream & write(std::ostream &os)
Definition: hypercube++.h:96
const Node & operator[](size_t idx) const
Definition: hypercube++.h:101
BinaryDrag< conact > Optimize()
Definition: hypercube++.cpp:58
std::vector< size_t > pow3_
Definition: hypercube++.h:70
std::vector< Node > data_
Definition: hypercube++.h:68
const rule_set & rs_
Definition: hypercube++.h:69
std::istream & read(std::istream &is)
Definition: hypercube++.h:93
BinaryDrag< conact > GenerateOdt(const rule_set &rs)
BinaryDrag< conact > GetOdt(const rule_set &rs, bool force_generation)
Returns the optimal (or pseudo optimal) decision tree generated from the given rule set.
std::ostream & rawwrite(std::ostream &os, const T &val, size_t n)
Definition: hypercube++.h:24
std::istream & rawread(std::istream &is, T &val, size_t n)
Definition: hypercube++.h:20
BinaryDrag< conact > GetOdtWithFileSuffix(const rule_set &rs, const string &file_suffix, bool force_generation)
unsigned int num_equiv_
Definition: hypercube++.h:63
unsigned long long gain_
Definition: hypercube++.h:61
unsigned long long frequency_
Definition: hypercube++.h:60
std::bitset< 131 > actions_
Definition: hypercube++.h:59
std::vector< rule > rules
Definition: rule_set.h:52