TdZdd  1.1
A top-down/breadth-first decision diagram manipulation framework
DdSweeper.hpp
1 /*
2  * TdZdd: a Top-down/Breadth-first Decision Diagram Manipulation Framework
3  * by Hiroaki Iwashita <iwashita@erato.ist.hokudai.ac.jp>
4  * Copyright (c) 2014 ERATO MINATO Project
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the "Software"),
8  * to deal in the Software without restriction, including without limitation
9  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10  * and/or sell copies of the Software, and to permit persons to whom the
11  * Software is furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22  * DEALINGS IN THE SOFTWARE.
23  */
24 
25 #pragma once
26 
27 #include <cassert>
28 #include <ostream>
29 
30 #include "Node.hpp"
31 #include "NodeTable.hpp"
32 #include "../util/MessageHandler.hpp"
33 #include "../util/MyVector.hpp"
34 
35 namespace tdzdd {
36 
42 template<int ARITY>
43 class DdSweeper {
44  static size_t const SWEEP_RATIO = 20;
45 
46  NodeTableEntity<ARITY>& diagram;
47  MyVector<NodeBranchId>* oneSrcPtr;
48 
49  MyVector<int> sweepLevel;
50  MyVector<size_t> deadCount;
51  size_t allCount;
52  size_t maxCount;
53  NodeId* rootPtr;
54 
55 public:
60  DdSweeper(NodeTableEntity<ARITY>& diagram) :
61  diagram(diagram), oneSrcPtr(0), allCount(0), maxCount(0), rootPtr(0) {
62  }
63 
69  DdSweeper(NodeTableEntity<ARITY>& diagram,
70  MyVector<NodeBranchId>& oneSrcPtr) :
71  diagram(diagram),
72  oneSrcPtr(&oneSrcPtr),
73  allCount(0),
74  maxCount(0),
75  rootPtr(0) {
76  }
77 
82  void setRoot(NodeId& root) {
83  rootPtr = &root;
84  }
85 
92  void update(int current, int child, size_t count) {
93  assert(1 <= current);
94  assert(0 <= child);
95  if (current <= 1) return;
96 
97  if (size_t(current) >= sweepLevel.size()) {
98  sweepLevel.resize(current + 1);
99  deadCount.resize(current + 2);
100  }
101 
102  for (int i = child; i <= current; ++i) {
103  if (sweepLevel[i] > 0) break;
104  sweepLevel[i] = current + 1;
105  }
106 
107  deadCount[current] = count;
108  allCount += diagram[current].size();
109 
110  int k = sweepLevel[current - 1];
111  for (int i = sweepLevel[current]; i > k; --i) {
112  deadCount[k] += deadCount[i];
113  deadCount[i] = 0;
114  }
115  if (maxCount < allCount) maxCount = allCount;
116  if (deadCount[k] * SWEEP_RATIO < maxCount) return;
117 
118  MyVector<MyVector<NodeId> > newId(diagram.numRows());
119 
120  MessageHandler mh;
121  mh.begin("sweeping") << " <" << diagram.size() << "> ...";
122 
123  for (int i = k; i < diagram.numRows(); ++i) {
124  size_t m = diagram[i].size();
125  newId[i].resize(m);
126 
127  size_t jj = 0;
128 
129  for (size_t j = 0; j < m; ++j) {
130  Node<ARITY>& p = diagram[i][j];
131  bool dead = true;
132 
133  for (int b = 0; b < ARITY; ++b) {
134  NodeId& f = p.branch[b];
135  if (f.row() >= k) f = newId[f.row()][f.col()];
136  if (f != 0) dead = false;
137  }
138 
139  if (dead) {
140  newId[i][j] = 0;
141  }
142  else {
143  newId[i][j] = NodeId(i, jj);
144  diagram[i][jj] = p;
145  ++jj;
146  }
147  }
148 
149  diagram[i].resize(jj);
150  }
151 
152  if (oneSrcPtr) {
153  for (size_t i = 0; i < oneSrcPtr->size(); ++i) {
154  NodeBranchId& nbi = (*oneSrcPtr)[i];
155  if (nbi.row >= k) {
156  NodeId f = newId[nbi.row][nbi.col];
157  nbi.row = f.row();
158  nbi.col = f.col();
159  }
160  }
161  }
162 
163  *rootPtr = newId[rootPtr->row()][rootPtr->col()];
164  deadCount[k] = 0;
165  allCount = diagram.size();
166  mh.end(diagram.size());
167  }
168 };
169 
170 } // namespace tdzdd
void update(int current, int child, size_t count)
Updates status and sweeps the DD if necessary.
Definition: DdSweeper.hpp:92
DdSweeper(NodeTableEntity< ARITY > &diagram, MyVector< NodeBranchId > &oneSrcPtr)
Constructor.
Definition: DdSweeper.hpp:69
On-the-fly DD cleaner.
Definition: DdSweeper.hpp:43
DdSweeper(NodeTableEntity< ARITY > &diagram)
Constructor.
Definition: DdSweeper.hpp:60
void setRoot(NodeId &root)
Set the root pointer.
Definition: DdSweeper.hpp:82