56 template <
typename GUM_SCALAR,
57 template <
typename >
class FUNCTOR,
58 template <
typename >
class TerminalNodePolicy >
75 template <
typename GUM_SCALAR,
76 template <
typename >
class FUNCTOR,
77 template <
typename >
class TerminalNodePolicy >
98 template <
typename GUM_SCALAR,
99 template <
typename >
class FUNCTOR,
100 template <
typename >
class TerminalNodePolicy >
107 Idx* varInst =
nullptr;
119 _rd_->manager()->setRootNode(root);
128 template <
typename GUM_SCALAR,
129 template <
typename >
class FUNCTOR,
130 template <
typename >
class TerminalNodePolicy >
136 while (fite !=
_DG1_->variablesSequence().endSafe()
137 && site !=
_DG2_->variablesSequence().endSafe()) {
140 if (
_rd_->variablesSequence().exists(*fite)) {
147 if (
_rd_->variablesSequence().exists(*site)) {
154 if (!
_DG2_->variablesSequence().exists(*fite)) {
162 if (!
_DG1_->variablesSequence().exists(*site)) {
170 if (*fite == *site) {
199 if (fite ==
_DG1_->variablesSequence().endSafe()) {
200 for (; site !=
_DG2_->variablesSequence().endSafe(); ++site)
201 if (!
_rd_->variablesSequence().exists(*site))
_rd_->add(**site);
203 for (; fite !=
_DG1_->variablesSequence().endSafe(); ++fite)
204 if (!
_rd_->variablesSequence().exists(*fite))
_rd_->add(**fite);
220 template <
typename GUM_SCALAR,
221 template <
typename >
class FUNCTOR,
222 template <
typename >
class TerminalNodePolicy >
240 template <
typename GUM_SCALAR,
241 template <
typename >
class FUNCTOR,
242 template <
typename >
class TerminalNodePolicy >
252 Idx varPos =
_rd_->variablesSequence().pos(*varIter);
253 const Link< NodeId >* nodeIter = dg->varNodeListe(*varIter)->list();
254 while (nodeIter !=
nullptr) {
255 short int* instantiationNeeded =
static_cast< short int*
>(
SOA_ALLOCATE(tableSize));
258 short int* varDescendant =
static_cast< short int*
>(
SOA_ALLOCATE(tableSize));
259 nodesVarDescendant.
insert(nodeIter->
element(), varDescendant);
261 instantiationNeeded[j] = (
short int)0;
262 varDescendant[j] = (
short int)0;
265 varDescendant[varPos] = (
short int)1;
266 for (
Idx modality = 0; modality < dg->node(nodeIter->
element())->nbSons(); ++modality) {
267 if (!dg->isTerminalNode(dg->node(nodeIter->
element())->son(modality))) {
268 short int* sonVarDescendant
269 = nodesVarDescendant[dg->node(nodeIter->
element())->son(modality)];
270 for (
Idx varIdx = 0; varIdx <
_nbVar_; varIdx++) {
271 varDescendant[varIdx] += sonVarDescendant[varIdx];
272 if (varDescendant[varIdx] && varIdx < varPos)
273 instantiationNeeded[varIdx] = (
short int)1;
284 const Link< NodeId >* nodeIter = dg->varNodeListe(*varIter)->list();
285 while (nodeIter !=
nullptr) {
286 for (
Idx modality = 0; modality < dg->node(nodeIter->
element())->nbSons(); ++modality) {
288 if (!dg->isTerminalNode(sonId)) {
289 for (
Idx varIdx = 0; varIdx <
_nbVar_; ++varIdx) {
290 if (dgInstNeed[nodeIter->
element()][varIdx] && nodesVarDescendant[sonId][varIdx]) {
291 dgInstNeed[sonId][varIdx] = (
short int)1;
301 it != nodesVarDescendant.
end();
305 nodesVarDescendant.
clear();
329 template <
typename GUM_SCALAR,
330 template <
typename >
class FUNCTOR,
331 template <
typename >
class TerminalNodePolicy >
334 Idx lastInstVarPos) {
346 return _rd_->manager()->addTerminalNode(
363 :
_rd_->variablesSequence().pos(
_DG1_->node(currentSituation.
DG1Node())->nodeVar());
370 :
_rd_->variablesSequence().pos(
_DG2_->node(currentSituation.
DG2Node())->nodeVar());
372 short int* instNeeded =
static_cast< short int*
>(
SOA_ALLOCATE(
sizeof(
short int) *
_nbVar_));
374 instNeeded[i] = dg1NeededVar[i] + dg2NeededVar[i];
376 double curSitKey = currentSituation.
key(instNeeded);
389 Idx leadVarPos =
_rd_->variablesSequence().size();
392 SetNodeFunction leadFunction =
nullptr;
394 bool sameVar =
false;
396 if (!
_DG1_->isTerminalNode(currentSituation.
DG1Node())) {
397 if (currentSituation.
varModality(dg1CurrentVarPos) != 0) {
399 ->son(currentSituation.
varModality(dg1CurrentVarPos) - 1));
401 newNode =
_compute_(currentSituation, lastInstVarPos);
412 leadNodeId = currentSituation.
DG1Node();
413 leadVarPos = dg1CurrentVarPos;
417 if (!
_DG2_->isTerminalNode(currentSituation.
DG2Node())) {
418 if (currentSituation.
varModality(dg2CurrentVarPos) != 0) {
420 ->son(currentSituation.
varModality(dg2CurrentVarPos) - 1));
422 newNode =
_compute_(currentSituation, lastInstVarPos);
432 if (leadVarPos == dg2CurrentVarPos) { sameVar =
true; }
434 if (leadVarPos > dg2CurrentVarPos) {
436 leadNodeId = currentSituation.
DG2Node();
437 leadVarPos = dg2CurrentVarPos;
446 for (
Idx varPos = lastInstVarPos + 1; varPos < leadVarPos; ++varPos) {
447 if (instNeeded[varPos]) {
452 for (
Idx modality = 0; modality < curVar->
domainSize(); modality++) {
455 sonsIds[modality] =
_compute_(currentSituation, varPos);
458 newNode =
_rd_->manager()->addInternalNode(curVar, sonsIds);
482 Idx varPos =
_rd_->variablesSequence().pos(curVar);
486 for (
Idx modality = 0; modality < curVar->
domainSize(); modality++) {
491 sonsIds[modality] =
_compute_(currentSituation, varPos);
494 newNode =
_rd_->manager()->addInternalNode(curVar, sonsIds);
507 const InternalNode* leaddgNode = leaddg->node(leadNodeId);
512 for (
Idx modality = 0; modality < curVar->
domainSize(); modality++) {
514 (currentSituation.*leadFunction)(leaddgNode->
son(modality));
516 sonsIds[modality] =
_compute_(currentSituation, leadVarPos);
519 newNode =
_rd_->manager()->addInternalNode(curVar, sonsIds);
532 template <
typename GUM_SCALAR,
533 template <
typename >
class FUNCTOR,
534 template <
typename >
class TerminalNodePolicy >
539 template <
typename GUM_SCALAR,
540 template <
typename >
class FUNCTOR,
541 template <
typename >
class TerminalNodePolicy >
547 template <
typename GUM_SCALAR,
548 template <
typename >
class FUNCTOR,
549 template <
typename >
class TerminalNodePolicy >
Unsafe Iterators for hashtables.
Base class for discrete random variable.
virtual Size domainSize() const =0
The class for generic Hash Tables.
iterator begin()
Returns an unsafe iterator pointing to the beginning of the hashtable.
value_type & insert(const Key &key, const Val &val)
Adds a new element (actually a copy of this element) into the hash table.
const iterator & end() noexcept
Returns the unsafe iterator pointing to the end of the hashtable.
void clear()
Removes all the elements in the hash table.
Structure used to represent a node internal structure.
const DiscreteVariable * nodeVar() const
Returns the node variable.
NodeId son(Idx modality) const
Returns the son at a given index.
const Link< T > * nextLink() const
Returns next link.
const T & element() const
Returns the element stored in this link.
Idx _nbVar_
The total number of variable implied in the operation.
~MultiDimFunctionGraphOperator()
Default destructor.
Idx _distance_(const MultiDimFunctionGraph< GUM_SCALAR, TerminalNodePolicy > *, const DiscreteVariable *, const DiscreteVariable *)
Heuristic methods to decide which of two retrograde variables should come first.
const MultiDimFunctionGraph< GUM_SCALAR, TerminalNodePolicy > * _DG2_
The other one.
HashTable< double, NodeId > _explorationTable_
The hashtable used to know if two pair of nodes have already been visited.
void _establishVarOrder_()
Computes an order for the final Decision graph that will minimize the number of re exploration.
MultiDimFunctionGraph< GUM_SCALAR, TerminalNodePolicy > * _rd_
The resulting function graph.
const FUNCTOR< GUM_SCALAR > _function_
The function to be performed on the leaves.
MultiDimFunctionGraph< GUM_SCALAR, TerminalNodePolicy > * compute()
Computes and builds the Function Graph that is the result of the operation.
HashTable< NodeId, short int * > _DG2InstantiationNeeded_
Table uses to know if a given node of second function graph has retrograde vrariables.
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.
MultiDimFunctionGraphOperator(const MultiDimFunctionGraph< GUM_SCALAR, TerminalNodePolicy > *DG1, const MultiDimFunctionGraph< GUM_SCALAR, TerminalNodePolicy > *DG2)
Default constructor.
HashTable< NodeId, short int * > _DG1InstantiationNeeded_
Table uses to know if a given node of first function graph has retrograde vrariables.
NodeId _compute_(O4DGContext ¤tSituation, Idx lastInstVarPos)
The main recursion function.
const MultiDimFunctionGraph< GUM_SCALAR, TerminalNodePolicy > * _DG1_
One of the two function graphs used for the operation.
short int * _default_
Just a comptuationnal trick.
static MultiDimFunctionGraph< GUM_SCALAR, TerminalNodePolicy > * getReducedAndOrderedInstance()
Returns a reduced and ordered instance.
virtual const Sequence< const DiscreteVariable * > & variablesSequence() const override
Returns a const ref to the sequence of DiscreteVariable*.
Class used to manipulate context during Function Graph Operations.
const NodeId & DG2Node() const
Get DG2 diagram current explored Node.
void setDG2Node(const NodeId &)
Set DG2 diagram current explored Node.
const NodeId & DG1Node() const
Get DG1 diagram current explored Node.
void chgVarModality(Idx, Idx)
Changes given variable modality.
void setDG1Node(const NodeId &)
Set DG1 diagram current explored Node.
const double & key(short int *instNeeded)
Returns o4DGContext key.
Idx varModality(Idx)
Changes given variable modality.
Safe iterators for Sequence.
std::size_t Size
In aGrUM, hashed values are unsigned long int.
Size Idx
Type for indexes.
Size NodeId
Type for node ids.
Headers of the InternalNode class.
Class used to compute the operation between two decision diagrams.
gum is the global namespace for all aGrUM entities
#define SOA_DEALLOCATE(x, y)