Version: 1.0
hypercube.cpp
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 #include "hypercube.h"
8 
9 #include "utilities.h"
10 
11 using namespace std;
12 
13 void CreateTree_rec(BinaryDrag<conact>& t, BinaryDrag<conact>::node *n, const rule_set& rs, const VHyperCube &hcube, const VIndex &idx) {
14  VNode node = hcube[idx];
15  if (node.uiAction == 0) {
16  n->data.t = conact::type::CONDITION;
17  n->data.condition = rs.conditions[node.uiMaxGainIndex];
18 
19  // Extract the two (n-1)-cubes
20  string sChild0(idx.GetIndexString());
21  string sChild1(sChild0);
22  sChild0[node.uiMaxGainIndex] = '0';
23  sChild1[node.uiMaxGainIndex] = '1';
24  VIndex idx0(sChild0), idx1(sChild1);
25 
26  CreateTree_rec(t, n->left = t.make_node(), rs, hcube, idx0);
27  CreateTree_rec(t, n->right = t.make_node(), rs, hcube, idx1);
28  }
29  else {
30  n->data.t = conact::type::ACTION;
31  n->data.action = node.uiAction;
32  }
33 }
34 
36 {
37  std::string s;
38  s.resize(m_iDim, '0');
39  VIndex idx(s);
40  if (bVerbose) {
41  // Print the table
42  do {
43  std::cout << idx.GetIndexString() << "\t" << m_arrIndex[idx.GetIndex()].uiProb << "\t";
44  if (m_arrIndex[idx.GetIndex()].uiAction == 0)
45  std::cout << "0";
46  else
47  for (size_t i = 1; i < 128; i++)
48  if (m_arrIndex[idx.GetIndex()].uiAction[i - 1])
49  std::cout << i << ",";
50  std::cout << "\n";
51  } while (idx.MoveNext());
52  std::cout << "------------------------\n";
53  }
54 
55  for (size_t iNumIndifference = 1; iNumIndifference <= m_iDim; iNumIndifference++) {
56  if (!bVerbose)
57  std::cout << iNumIndifference << " " << std::flush;
58  // Initialize the Indifferences
59  bool bFine;
60  std::vector<size_t> arrPosIndifference(iNumIndifference);
61  int iPos = 0;
62  for (size_t i = 0; i < iNumIndifference; i++) {
63  arrPosIndifference[i] = iPos;
64  iPos++;
65  }
66 
67  std::vector</*unsigned*/unsigned long long> arrProb(iNumIndifference);
68  std::vector</*unsigned*/unsigned long long> arrGain(iNumIndifference);
69  std::vector<unsigned> arrNEq(iNumIndifference);
70 
71  // Do all the combinations
72  do {
73  // Generate the Indifference Mask
74  std::string s;
75  s.resize(m_iDim, '0');
76  for (size_t i = 0; i < iNumIndifference; i++)
77  s[arrPosIndifference[i]] = '-';
78 
79  // Print all the combinations
80  if (!idx.SetIndex(s))
81  throw;
82  do {
83  for (size_t i = 0; i < iNumIndifference; i++) {
84  std::string sChild0(idx.GetIndexString());
85  std::string sChild1(sChild0);
86  sChild0[arrPosIndifference[i]] = '0';
87  sChild1[arrPosIndifference[i]] = '1';
88  VIndex idx0(sChild0), idx1(sChild1);
89  VNode node0(m_arrIndex[idx0.GetIndex()]), node1(m_arrIndex[idx1.GetIndex()]);
90 
91  // Calculate the intersection of all possible actions
92  auto uiIntersezione = node0.uiAction & node1.uiAction;
93 
94  m_arrIndex[idx.GetIndex()].uiAction = uiIntersezione;
95  arrProb[i] = node0.uiProb + node1.uiProb;
96  arrGain[i] = node0.uiGain + node1.uiGain;
97  arrNEq[i] = node0.neq * node1.neq;
98 
99  if (uiIntersezione != 0) {
100  arrGain[i] += arrProb[i];
101  arrNEq[i] = 0;
102  }
103  }
104  /*unsigned*/unsigned long long uiMaxGain(0);
105  /*unsigned*/unsigned long long uiMaxGainProb(0);
106  size_t uiMaxGainIndex(0);
107  unsigned uiNEq(0);
108  for (size_t i = 0; i < iNumIndifference; i++) {
109  if (uiMaxGain <= arrGain[i]) {
110  if (uiMaxGain < arrGain[i])
111  uiNEq = arrNEq[i];
112  else
113  uiNEq += arrNEq[i];
114  uiMaxGain = arrGain[i];
115  uiMaxGainProb = arrProb[i];
116  uiMaxGainIndex = arrPosIndifference[i];
117  }
118  }
119  m_arrIndex[idx.GetIndex()].uiGain = uiMaxGain;
120  m_arrIndex[idx.GetIndex()].uiProb = uiMaxGainProb;
121  m_arrIndex[idx.GetIndex()].uiMaxGainIndex = static_cast<::byte>(uiMaxGainIndex);
122  m_arrIndex[idx.GetIndex()].neq = std::max(uiNEq, 1u);
123 
124  if (bVerbose) {
125  std::cout << idx.GetIndexString() << "\t" << m_arrIndex[idx.GetIndex()].uiProb << "\t";
126  if (m_arrIndex[idx.GetIndex()].uiAction == 0)
127  std::cout << "0";
128  else
129  for (unsigned j = 1; j < 32; j++)
130  if (m_arrIndex[idx.GetIndex()].uiAction[j - 1])
131  std::cout << j << ",";
132  std::cout << "\t";
133 
134  for (size_t i = 0; i < iNumIndifference; i++) {
135  std::cout << arrGain[i];
136  if (arrPosIndifference[i] == uiMaxGainIndex)
137  std::cout << "*";
138  else if (arrGain[i] == uiMaxGain)
139  std::cout << "#";
140  std::cout << "\t";
141  }
142 
143  std::cout << m_arrIndex[idx.GetIndex()].neq << "\n";
144  }
145  } while (idx.MoveNext());
146  if (bVerbose)
147  std::cout << "\n";
148 
149  // Move on to the next permutation of indifference
150  bFine = true;
151  for (int i = int(iNumIndifference) -1; i >= 0; i--) {
152  arrPosIndifference[i]++;
153  // Does this have a valid position?
154  if (arrPosIndifference[i] < m_iDim) {
155  // Are there any other indifferences?
156  if (m_iDim - 1 - arrPosIndifference[i] >= iNumIndifference - 1 - i) {
157  // The position is valid, there are positions,
158  // therefore, we fix the following indifferences
159  iPos = int(arrPosIndifference[i]) + 1;
160  for (size_t j = i + 1; j < iNumIndifference; j++) {
161  arrPosIndifference[j] = iPos;
162  iPos++;
163  }
164  bFine = false;
165  break;
166  }
167  }
168  }
169  } while (!bFine);
170  if (bVerbose)
171  std::cout << "------------------------\n";
172  }
173 
175  CreateTree_rec(t, t.make_root(), m_rs, *this, string(m_iDim, '-'));
176  return t;
177 }
178 
180  TLOG("Allocating hypercube",
181  VHyperCube hcube(rs);
182  );
183 
184  TLOG("Optimizing rules",
185  auto t = hcube.optimize(false);
186  );
187 
188  return t;
189 }
190 
191 BinaryDrag<conact> GenerateOdt(const rule_set& rs, const string& filename)
192 {
193  auto t = GenerateOdt(rs);
194  WriteConactTree(t, filename);
195  return t;
196 }
197 
198 BinaryDrag<conact> GetOdt(const rule_set& rs, bool force_generation) {
199  string odt_filename = conf.odt_path_.string();
201  if (conf.force_odt_generation_ || force_generation || !LoadConactTree(t, odt_filename)) {
202  t = GenerateOdt(rs, odt_filename);
203  }
204  return t;
205 }
206 
207 BinaryDrag<conact> GetOdtWithFileSuffix(const rule_set& rs, const string& file_suffix, bool force_generation) {
208  string odt_filename = conf.GetCustomOdtPath(file_suffix).string();
210  if (conf.force_odt_generation_ || force_generation || !LoadConactTree(t, odt_filename)) {
211  t = GenerateOdt(rs, odt_filename);
212  }
213  return t;
214 }
node * make_root()
Creates a new root updating the roots_ vector.
Definition: drag.h:145
node * make_node(Args &&... args)
Creates and returns a new node updating the nodes_ vector.
Definition: drag.h:53
bool WriteConactTree(const BinaryDrag< conact > &t, const string &filename)
Definition: conact_tree.cpp:76
bool LoadConactTree(BinaryDrag< conact > &t, const string &filename)
Definition: conact_tree.cpp:46
BinaryDrag< conact > GetOdt(const rule_set &rs, bool force_generation)
Returns the optimal (or pseudo optimal) decision tree generated from the given rule set.
Definition: hypercube.cpp:198
BinaryDrag< conact > GenerateOdt(const rule_set &rs)
Definition: hypercube.cpp:179
void CreateTree_rec(BinaryDrag< conact > &t, BinaryDrag< conact >::node *n, const rule_set &rs, const VHyperCube &hcube, const VIndex &idx)
Definition: hypercube.cpp:13
BinaryDrag< conact > GetOdtWithFileSuffix(const rule_set &rs, const string &file_suffix, bool force_generation)
Definition: hypercube.cpp:207
std::filesystem::path GetCustomOdtPath(const std::string &custom_suffix) const
Definition: config_data.h:110
std::filesystem::path odt_path_
Definition: config_data.h:45
bool force_odt_generation_
Definition: config_data.h:83
BinaryDrag< conact > optimize(bool bVerbose=false)
Definition: hypercube.cpp:35
bool MoveNext()
Definition: hypercube.h:73
std::string GetIndexString() const
Definition: hypercube.h:54
unsigned GetIndex() const
Definition: hypercube.h:64
bool SetIndex(const std::string &s)
Definition: hypercube.h:38
byte uiMaxGainIndex
Definition: hypercube.h:94
unsigned neq
Definition: hypercube.h:95
unsigned long long uiProb
Definition: hypercube.h:92
unsigned long long uiGain
Definition: hypercube.h:93
std::bitset< 131 > uiAction
Definition: hypercube.h:91
std::vector< std::string > conditions
Definition: rule_set.h:48
ConfigData conf
Definition: utilities.cpp:9
#define TLOG(message, instructions)
Definition: utilities.h:93