32 template <
typename GUM_SCALAR,
36 class TerminalNodePolicy >
42 __DG2(DG2), __function(),
43 __DG1InstantiationNeeded(DG1->realSize(), true, false),
44 __DG2InstantiationNeeded(DG2->realSize(), true, false) {
48 TerminalNodePolicy >::getReducedAndOrderedInstance();
57 template <
typename GUM_SCALAR,
61 class TerminalNodePolicy >
83 template <
typename GUM_SCALAR,
87 class TerminalNodePolicy >
95 Idx* varInst =
nullptr;
107 __rd->manager()->setRootNode(root);
116 template <
typename GUM_SCALAR,
117 template <
typename >
119 template <
typename >
120 class TerminalNodePolicy >
124 __DG1->variablesSequence().beginSafe();
126 __DG2->variablesSequence().beginSafe();
128 while (fite !=
__DG1->variablesSequence().endSafe()
129 && site !=
__DG2->variablesSequence().endSafe()) {
132 if (
__rd->variablesSequence().exists(*fite)) {
139 if (
__rd->variablesSequence().exists(*site)) {
146 if (!
__DG2->variablesSequence().exists(*fite)) {
154 if (!
__DG1->variablesSequence().exists(*site)) {
162 if (*fite == *site) {
191 if (fite ==
__DG1->variablesSequence().endSafe()) {
192 for (; site !=
__DG2->variablesSequence().endSafe(); ++site)
193 if (!
__rd->variablesSequence().exists(*site))
__rd->add(**site);
195 for (; fite !=
__DG1->variablesSequence().endSafe(); ++fite)
196 if (!
__rd->variablesSequence().exists(*fite))
__rd->add(**fite);
213 template <
typename GUM_SCALAR,
214 template <
typename >
216 template <
typename >
217 class TerminalNodePolicy >
224 Idx posi = d->variablesSequence().pos(from);
227 while (d->variablesSequence().atPos(posi) != to) {
228 dist *= (*(d->variablesSequence().atPos(posi))).domainSize();
238 template <
typename GUM_SCALAR,
239 template <
typename >
241 template <
typename >
242 class TerminalNodePolicy >
251 for (
auto varIter = dg->variablesSequence().rbeginSafe();
252 varIter != dg->variablesSequence().rendSafe();
254 Idx varPos =
__rd->variablesSequence().pos(*varIter);
255 const Link< NodeId >* nodeIter = dg->varNodeListe(*varIter)->list();
256 while (nodeIter !=
nullptr) {
257 short int* instantiationNeeded =
261 short int* varDescendant =
263 nodesVarDescendant.
insert(nodeIter->
element(), varDescendant);
265 instantiationNeeded[j] = (
short int)0;
266 varDescendant[j] = (
short int)0;
269 varDescendant[varPos] = (
short int)1;
270 for (
Idx modality = 0; modality < dg->node(nodeIter->
element())->nbSons();
272 if (!dg->isTerminalNode(dg->node(nodeIter->
element())->son(modality))) {
273 short int* sonVarDescendant =
274 nodesVarDescendant[dg->node(nodeIter->
element())->son(modality)];
275 for (
Idx varIdx = 0; varIdx <
__nbVar; varIdx++) {
276 varDescendant[varIdx] += sonVarDescendant[varIdx];
277 if (varDescendant[varIdx] && varIdx < varPos)
278 instantiationNeeded[varIdx] = (
short int)1;
286 for (
auto varIter = dg->variablesSequence().beginSafe();
287 varIter != dg->variablesSequence().endSafe();
289 const Link< NodeId >* nodeIter = dg->varNodeListe(*varIter)->list();
290 while (nodeIter !=
nullptr) {
291 for (
Idx modality = 0; modality < dg->node(nodeIter->
element())->nbSons();
294 if (!dg->isTerminalNode(sonId)) {
295 for (
Idx varIdx = 0; varIdx <
__nbVar; ++varIdx) {
296 if (dgInstNeed[nodeIter->
element()][varIdx]
297 && nodesVarDescendant[sonId][varIdx]) {
298 dgInstNeed[sonId][varIdx] = (
short int)1;
308 it != nodesVarDescendant.
end();
312 nodesVarDescendant.
clear();
337 template <
typename GUM_SCALAR,
338 template <
typename >
340 template <
typename >
341 class TerminalNodePolicy >
355 return __rd->manager()->addTerminalNode(
366 short int* dg1NeededVar =
370 Idx dg1CurrentVarPos =
373 :
__rd->variablesSequence().pos(
375 short int* dg2NeededVar =
379 Idx dg2CurrentVarPos =
382 :
__rd->variablesSequence().pos(
385 short int* instNeeded =
388 instNeeded[i] = dg1NeededVar[i] + dg2NeededVar[i];
390 double curSitKey = currentSituation.
key(instNeeded);
400 origDG2 = currentSituation.
DG2Node();
405 Idx leadVarPos =
__rd->variablesSequence().size();
407 SetNodeFunction leadFunction =
nullptr;
409 bool sameVar =
false;
411 if (!
__DG1->isTerminalNode(currentSituation.
DG1Node())) {
412 if (currentSituation.
varModality(dg1CurrentVarPos) != 0) {
415 ->son(currentSituation.
varModality(dg1CurrentVarPos) - 1));
417 newNode =
__compute(currentSituation, lastInstVarPos);
428 leadNodeId = currentSituation.
DG1Node();
429 leadVarPos = dg1CurrentVarPos;
433 if (!
__DG2->isTerminalNode(currentSituation.
DG2Node())) {
434 if (currentSituation.
varModality(dg2CurrentVarPos) != 0) {
437 ->son(currentSituation.
varModality(dg2CurrentVarPos) - 1));
439 newNode =
__compute(currentSituation, lastInstVarPos);
449 if (leadVarPos == dg2CurrentVarPos) { sameVar =
true; }
451 if (leadVarPos > dg2CurrentVarPos) {
453 leadNodeId = currentSituation.
DG2Node();
454 leadVarPos = dg2CurrentVarPos;
463 for (
Idx varPos = lastInstVarPos + 1; varPos < leadVarPos; ++varPos) {
464 if (instNeeded[varPos]) {
469 for (
Idx modality = 0; modality < curVar->
domainSize(); modality++) {
472 sonsIds[modality] =
__compute(currentSituation, varPos);
475 newNode =
__rd->manager()->addInternalNode(curVar, sonsIds);
499 Idx varPos =
__rd->variablesSequence().pos(curVar);
504 for (
Idx modality = 0; modality < curVar->
domainSize(); modality++) {
509 sonsIds[modality] =
__compute(currentSituation, varPos);
512 newNode =
__rd->manager()->addInternalNode(curVar, sonsIds);
525 const InternalNode* leaddgNode = leaddg->node(leadNodeId);
531 for (
Idx modality = 0; modality < curVar->
domainSize(); modality++) {
533 (currentSituation.*leadFunction)(leaddgNode->
son(modality));
535 sonsIds[modality] =
__compute(currentSituation, leadVarPos);
538 newNode =
__rd->manager()->addInternalNode(curVar, sonsIds);
551 template <
typename GUM_SCALAR,
552 template <
typename >
554 template <
typename >
555 class TerminalNodePolicy >
562 template <
typename GUM_SCALAR,
563 template <
typename >
565 template <
typename >
566 class TerminalNodePolicy >
573 template <
typename GUM_SCALAR,
574 template <
typename >
576 template <
typename >
577 class TerminalNodePolicy >
iterator begin()
Returns an unsafe iterator pointing to the beginning of the hashtable.
const NodeId & DG2Node() const
Get DG2 diagram current explored Node.
Safe iterators for Sequence.
const iterator & end() noexcept
Returns the unsafe iterator pointing to the end of the hashtable.
const iterator_safe & endSafe() noexcept
Returns the safe iterator pointing to the end of the hashtable.
const DiscreteVariable * nodeVar() const
Returns the node variable.
void __findRetrogradeVariables(const MultiDimFunctionGraph< GUM_SCALAR, TerminalNodePolicy > *dg, HashTable< NodeId, short int * > &dgInstNeed)
Establish for each node in both function graph if it has retrograde variables beneath it...
Unsafe Iterators for hashtablesHashTableIterator provides a fast but unsafe way to parse HashTables...
MultiDimFunctionGraph< GUM_SCALAR, TerminalNodePolicy > * compute()
Computes and builds the Function Graph that is the result of the operation.
MultiDimFunctionGraph< GUM_SCALAR, TerminalNodePolicy > * __rd
The resulting function graph.
#define SOA_DEALLOCATE(x, y)
NodeId son(Idx modality) const
Returns the son at a given index.
short int * __default
Just a comptuationnal trick.
Headers of the InternalNode class.
HashTable< NodeId, short int *> __DG1InstantiationNeeded
Table uses to know if a given node of first function graph has retrograde vrariables.
bool exists(const Key &key) const
Checks whether there exists an element with a given key in the hashtable.
const double & key(short int *instNeeded)
Returns o4DGContext key.
Idx __nbVar
The total number of variable implied in the operation.
void chgVarModality(Idx, Idx)
Changes given variable modality.
Base class for discrete random variable.
gum is the global namespace for all aGrUM entities
const T & element() const
Returns the element stored in this link.
virtual Size domainSize() const =0
Idx __distance(const MultiDimFunctionGraph< GUM_SCALAR, TerminalNodePolicy > *, const DiscreteVariable *, const DiscreteVariable *)
Heuristic methods to decide which of two retrograde variables should come first.
const NodeId & DG1Node() const
Get DG1 diagram current explored Node.
HashTable< double, NodeId > __explorationTable
The hashtable used to know if two pair of nodes have already been visited.
void setDG1Node(const NodeId &)
Set DG1 diagram current explored Node.
HashTable< NodeId, short int *> __DG2InstantiationNeeded
Table uses to know if a given node of second function graph has retrograde vrariables.
Structure used to represent a node internal structure.
Link of a chain list allocated using the SmallObjectAllocator.
Class used to compute the operation between two decision diagrams.
Class implementingting a function graph.
Class used to perform Function Graph Operations.
const FUNCTOR< GUM_SCALAR > __function
The function to be performed on the leaves.
void setDG2Node(const NodeId &)
Set DG2 diagram current explored Node.
const MultiDimFunctionGraph< GUM_SCALAR, TerminalNodePolicy > * __DG1
One of the two function graphs used for the operation.
void clear()
Removes all the elements in the hash table.
iterator_safe beginSafe()
Returns the safe iterator pointing to the beginning of the hashtable.
MultiDimFunctionGraphOperator(const MultiDimFunctionGraph< GUM_SCALAR, TerminalNodePolicy > *DG1, const MultiDimFunctionGraph< GUM_SCALAR, TerminalNodePolicy > *DG2)
Default constructor.
Size Idx
Type for indexes.
std::size_t Size
In aGrUM, hashed values are unsigned long int.
Class used to manipulate context during Function Graph Operations.
~MultiDimFunctionGraphOperator()
Default destructor.
value_type & insert(const Key &key, const Val &val)
Adds a new element (actually a copy of this element) into the hash table.
const Link< T > * nextLink() const
Returns next link.
void __establishVarOrder()
Computes an order for the final Decision graph that will minimize the number of re exploration...
Size NodeId
Type for node ids.
Idx varModality(Idx)
Changes given variable modality.
NodeId __compute(O4DGContext ¤tSituation, Idx lastInstVarPos)
The main recursion function.
const MultiDimFunctionGraph< GUM_SCALAR, TerminalNodePolicy > * __DG2
The other one.