aGrUM  0.14.2
treeOperator_tpl.h
Go to the documentation of this file.
1 /****************************************************************************
2  * Copyright (C) 2005 by Pierre-Henri WUILLEMIN et Christophe GONZALES *
3  * {prenom.nom}_at_lip6.fr *
4  * *
5  * This program is free software; you can redistribute it and/or modify *
6  * it under the terms of the GNU General Public License as published by *
7  * the Free Software Foundation; either version 2 of the License, or *
8  * (at your option) any later version. *
9  * *
10  * This program is distributed in the hope that it will be useful, *
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13  * GNU General Public License for more details. *
14  * *
15  * You should have received a copy of the GNU General Public License *
16  * along with this program; if not, write to the *
17  * Free Software Foundation, Inc., *
18  * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19  ****************************************************************************/
30 
31 #define ALLOCATE(x) SmallObjectAllocator::instance().allocate(x)
32 #define DEALLOCATE(x, y) SmallObjectAllocator::instance().deallocate(x, y)
33 
34 namespace gum {
35 
36  template < typename GUM_SCALAR,
37  template < typename >
38  class COMBINEOPERATOR,
39  template < typename >
40  class TerminalNodePolicy >
41  INLINE
45  __dt1(dt1),
46  __dt2(dt2), __combine() {
47  GUM_CONSTRUCTOR(TreeOperator);
48 
49  __rd =
51  }
52 
53  template < typename GUM_SCALAR,
54  template < typename >
55  class COMBINEOPERATOR,
56  template < typename >
57  class TerminalNodePolicy >
58  INLINE
62  const HashTable< const DiscreteVariable*, Idx > givenContext) :
63  __dt1(dt1),
64  __dt2(dt2), __combine(), __context(givenContext) {
65  GUM_CONSTRUCTOR(TreeOperator);
66 
67  __rd =
69  }
70 
71  template < typename GUM_SCALAR,
72  template < typename >
73  class COMBINEOPERATOR,
74  template < typename >
75  class TerminalNodePolicy >
78  GUM_DESTRUCTOR(TreeOperator);
79  }
80 
81  // This function is the main function. To be call every time an operation
82  // between the two given Function Graphs is required
83  template < typename GUM_SCALAR,
84  template < typename >
85  class COMBINEOPERATOR,
86  template < typename >
87  class TerminalNodePolicy >
90  __rd->manager()->setRootNode(__xPloreDT1(__dt1->root()));
91 
92  return __rd;
93  }
94 
95  // Main recursion function, called every time we move on a node to determine
96  // what we have to do
97  template < typename GUM_SCALAR,
98  template < typename >
99  class COMBINEOPERATOR,
100  template < typename >
101  class TerminalNodePolicy >
102  INLINE NodeId
104  NodeId currentNodeId) {
105  if (__dt1->isTerminalNode(currentNodeId)) {
106  __curDT1Leaf = currentNodeId;
107  return __xPloreDT2(__dt2->root());
108  }
109 
110  const InternalNode* currentNode = __dt1->node(currentNodeId);
111 
112  if (!__rd->variablesSequence().exists(currentNode->nodeVar()))
113  __rd->add(*(currentNode->nodeVar()));
114 
115  NodeId* sonsMap = static_cast< NodeId* >(
116  ALLOCATE(sizeof(NodeId) * currentNode->nodeVar()->domainSize()));
117  for (Idx moda = 0; moda < currentNode->nodeVar()->domainSize(); ++moda) {
118  __context.insert(currentNode->nodeVar(), moda);
119  sonsMap[moda] = __xPloreDT1(currentNode->son(moda));
120  __context.erase(currentNode->nodeVar());
121  }
122  return __checkRedundancy(currentNode->nodeVar(), sonsMap);
123  }
124 
125  template < typename GUM_SCALAR,
126  template < typename >
127  class COMBINEOPERATOR,
128  template < typename >
129  class TerminalNodePolicy >
130  INLINE NodeId
132  NodeId currentNodeId) {
133  if (__dt2->isTerminalNode(currentNodeId))
134  return __rd->manager()->addTerminalNode(__combine(
135  __dt1->nodeValue(__curDT1Leaf), __dt2->nodeValue(currentNodeId)));
136 
137  const InternalNode* currentNode = __dt2->node(currentNodeId);
138 
139  if (!__rd->variablesSequence().exists(currentNode->nodeVar()))
140  __rd->add(*(currentNode->nodeVar()));
141 
142  if (__context.exists(currentNode->nodeVar()))
143  return __xPloreDT2(currentNode->son(__context[currentNode->nodeVar()]));
144 
145  NodeId* sonsMap = static_cast< NodeId* >(
146  ALLOCATE(sizeof(NodeId) * currentNode->nodeVar()->domainSize()));
147  for (Idx moda = 0; moda < currentNode->nodeVar()->domainSize(); ++moda) {
148  __context.insert(currentNode->nodeVar(), moda);
149  sonsMap[moda] = __xPloreDT2(currentNode->son(moda));
150  __context.erase(currentNode->nodeVar());
151  }
152  return __checkRedundancy(currentNode->nodeVar(), sonsMap);
153  }
154 
155  template < typename GUM_SCALAR,
156  template < typename >
157  class COMBINEOPERATOR,
158  template < typename >
159  class TerminalNodePolicy >
162  bool diff = false;
163  for (Idx moda = 1; moda < var->domainSize() && !diff; ++moda)
164  if (sonsMap[0] != sonsMap[moda]) diff = true;
165 
166  if (!diff) {
167  NodeId zero = sonsMap[0];
168  DEALLOCATE(sonsMap, sizeof(NodeId) * var->domainSize());
169  return zero;
170  }
171 
172  return __rd->manager()->addInternalNode(var, sonsMap);
173  }
174 
175 } // namespace gum
Class used to compute the operation between two decision diagrams.
const DiscreteVariable * nodeVar() const
Returns the node variable.
NodeId __checkRedundancy(const DiscreteVariable *, NodeId *)
NodeId son(Idx modality) const
Returns the son at a given index.
Headers of the InternalNode class.
Base class for discrete random variable.
gum is the global namespace for all aGrUM entities
Definition: agrum.h:25
Class used to perform Decision Tree Operation in the FMDP Framework.
Definition: treeOperator.h:50
HashTable< const DiscreteVariable *, Idx > __context
Definition: treeOperator.h:108
NodeId __xPloreDT2(NodeId currentNodeId)
The main recursion function.
The class for generic Hash Tables.
Definition: hashTable.h:676
virtual Size domainSize() const =0
NodeId __xPloreDT1(NodeId currentNodeId)
The main recursion function.
const MultiDimFunctionGraph< GUM_SCALAR, TerminalNodePolicy > * __dt1
The two function graphs used for the operation.
Definition: treeOperator.h:99
MultiDimFunctionGraph< GUM_SCALAR, TerminalNodePolicy > * compute()
Computes and builds the Function Graph that is the result of the operation.
Structure used to represent a node internal structure.
Definition: internalNode.h:100
Class implementingting a function graph.
#define DEALLOCATE(x, y)
const COMBINEOPERATOR< GUM_SCALAR > __combine
The function to be performed on the leaves.
Definition: treeOperator.h:106
~TreeOperator()
Default destructor.
MultiDimFunctionGraph< GUM_SCALAR, TerminalNodePolicy > * __rd
The resulting function graph.
Definition: treeOperator.h:103
TreeOperator(const MultiDimFunctionGraph< GUM_SCALAR, TerminalNodePolicy > *dt1, const MultiDimFunctionGraph< GUM_SCALAR, TerminalNodePolicy > *dt2)
Default constructor.
static MultiDimFunctionGraph< GUM_SCALAR, TerminalNodePolicy > * getTreeInstance()
Returns an arborescent instance.
const MultiDimFunctionGraph< GUM_SCALAR, TerminalNodePolicy > * __dt2
Definition: treeOperator.h:100
Size Idx
Type for indexes.
Definition: types.h:50
Size NodeId
Type for node ids.
Definition: graphElements.h:97
#define ALLOCATE(x)