57 template <
typename GUM_ELEMENT,
58 template <
typename >
class FUNCTOR,
59 template <
typename >
class TerminalNodePolicy >
76 template <
typename GUM_ELEMENT,
77 template <
typename >
class FUNCTOR,
78 template <
typename >
class TerminalNodePolicy >
99 template <
typename GUM_ELEMENT,
100 template <
typename >
class FUNCTOR,
101 template <
typename >
class TerminalNodePolicy >
108 Idx* varInst =
nullptr;
120 _rd_->manager()->setRootNode(root);
129 template <
typename GUM_ELEMENT,
130 template <
typename >
class FUNCTOR,
131 template <
typename >
class TerminalNodePolicy >
137 while (fite !=
_DG1_->variablesSequence().endSafe()
138 && site !=
_DG2_->variablesSequence().endSafe()) {
141 if (
_rd_->variablesSequence().exists(*fite)) {
148 if (
_rd_->variablesSequence().exists(*site)) {
155 if (!
_DG2_->variablesSequence().exists(*fite)) {
163 if (!
_DG1_->variablesSequence().exists(*site)) {
171 if (*fite == *site) {
200 if (fite ==
_DG1_->variablesSequence().endSafe()) {
201 for (; site !=
_DG2_->variablesSequence().endSafe(); ++site)
202 if (!
_rd_->variablesSequence().exists(*site))
_rd_->add(**site);
204 for (; fite !=
_DG1_->variablesSequence().endSafe(); ++fite)
205 if (!
_rd_->variablesSequence().exists(*fite))
_rd_->add(**fite);
221 template <
typename GUM_ELEMENT,
222 template <
typename >
class FUNCTOR,
223 template <
typename >
class TerminalNodePolicy >
241 template <
typename GUM_ELEMENT,
242 template <
typename >
class FUNCTOR,
243 template <
typename >
class TerminalNodePolicy >
253 Idx varPos =
_rd_->variablesSequence().pos(*varIter);
254 const Link< NodeId >* nodeIter = dg->varNodeListe(*varIter)->list();
255 while (nodeIter !=
nullptr) {
256 short int* instantiationNeeded =
static_cast< short int*
>(
SOA_ALLOCATE(tableSize));
259 short int* varDescendant =
static_cast< short int*
>(
SOA_ALLOCATE(tableSize));
260 nodesVarDescendant.
insert(nodeIter->
element(), varDescendant);
262 instantiationNeeded[j] = (
short int)0;
263 varDescendant[j] = (
short int)0;
266 varDescendant[varPos] = (
short int)1;
267 for (
Idx modality = 0; modality < dg->node(nodeIter->
element())->nbSons(); ++modality) {
268 if (!dg->isTerminalNode(dg->node(nodeIter->
element())->son(modality))) {
269 short int* sonVarDescendant
270 = nodesVarDescendant[dg->node(nodeIter->
element())->son(modality)];
271 for (
Idx varIdx = 0; varIdx <
_nbVar_; varIdx++) {
272 varDescendant[varIdx] += sonVarDescendant[varIdx];
273 if (varDescendant[varIdx] && varIdx < varPos)
274 instantiationNeeded[varIdx] = (
short int)1;
285 const Link< NodeId >* nodeIter = dg->varNodeListe(*varIter)->list();
286 while (nodeIter !=
nullptr) {
287 for (
Idx modality = 0; modality < dg->node(nodeIter->
element())->nbSons(); ++modality) {
289 if (!dg->isTerminalNode(sonId)) {
290 for (
Idx varIdx = 0; varIdx <
_nbVar_; ++varIdx) {
291 if (dgInstNeed[nodeIter->
element()][varIdx] && nodesVarDescendant[sonId][varIdx]) {
292 dgInstNeed[sonId][varIdx] = (
short int)1;
302 it != nodesVarDescendant.
end();
306 nodesVarDescendant.
clear();
330 template <
typename GUM_ELEMENT,
331 template <
typename >
class FUNCTOR,
332 template <
typename >
class TerminalNodePolicy >
335 Idx lastInstVarPos) {
347 return _rd_->manager()->addTerminalNode(
364 :
_rd_->variablesSequence().pos(
_DG1_->node(currentSituation.
DG1Node())->nodeVar());
371 :
_rd_->variablesSequence().pos(
_DG2_->node(currentSituation.
DG2Node())->nodeVar());
373 short int* instNeeded =
static_cast< short int*
>(
SOA_ALLOCATE(
sizeof(
short int) *
_nbVar_));
375 instNeeded[i] = dg1NeededVar[i] + dg2NeededVar[i];
377 double curSitKey = currentSituation.
key(instNeeded);
390 Idx leadVarPos =
_rd_->variablesSequence().size();
393 SetNodeFunction leadFunction =
nullptr;
395 bool sameVar =
false;
397 if (!
_DG1_->isTerminalNode(currentSituation.
DG1Node())) {
398 if (currentSituation.
varModality(dg1CurrentVarPos) != 0) {
400 ->son(currentSituation.
varModality(dg1CurrentVarPos) - 1));
402 newNode =
_compute_(currentSituation, lastInstVarPos);
413 leadNodeId = currentSituation.
DG1Node();
414 leadVarPos = dg1CurrentVarPos;
418 if (!
_DG2_->isTerminalNode(currentSituation.
DG2Node())) {
419 if (currentSituation.
varModality(dg2CurrentVarPos) != 0) {
421 ->son(currentSituation.
varModality(dg2CurrentVarPos) - 1));
423 newNode =
_compute_(currentSituation, lastInstVarPos);
433 if (leadVarPos == dg2CurrentVarPos) { sameVar =
true; }
435 if (leadVarPos > dg2CurrentVarPos) {
437 leadNodeId = currentSituation.
DG2Node();
438 leadVarPos = dg2CurrentVarPos;
447 for (
Idx varPos = lastInstVarPos + 1; varPos < leadVarPos; ++varPos) {
448 if (instNeeded[varPos]) {
453 for (
Idx modality = 0; modality < curVar->
domainSize(); modality++) {
456 sonsIds[modality] =
_compute_(currentSituation, varPos);
459 newNode =
_rd_->manager()->addInternalNode(curVar, sonsIds);
483 Idx varPos =
_rd_->variablesSequence().pos(curVar);
487 for (
Idx modality = 0; modality < curVar->
domainSize(); modality++) {
492 sonsIds[modality] =
_compute_(currentSituation, varPos);
495 newNode =
_rd_->manager()->addInternalNode(curVar, sonsIds);
508 const InternalNode* leaddgNode = leaddg->node(leadNodeId);
513 for (
Idx modality = 0; modality < curVar->
domainSize(); modality++) {
515 (currentSituation.*leadFunction)(leaddgNode->
son(modality));
517 sonsIds[modality] =
_compute_(currentSituation, leadVarPos);
520 newNode =
_rd_->manager()->addInternalNode(curVar, sonsIds);
533 template <
typename GUM_ELEMENT,
534 template <
typename >
class FUNCTOR,
535 template <
typename >
class TerminalNodePolicy >
540 template <
typename GUM_ELEMENT,
541 template <
typename >
class FUNCTOR,
542 template <
typename >
class TerminalNodePolicy >
547 template <
typename GUM_ELEMENT,
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.
value_type & insert(const Key &key, const Val &val)
Adds a new element (actually a copy of this element) into the hash table.
void clear()
Removes all the elements in the hash table.
iterator begin()
Returns an unsafe iterator pointing to the beginning of the hashtable.
const iterator & end() noexcept
Returns the unsafe iterator pointing to the end of the hashtable.
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 T & element() const
Returns the element stored in this link.
const Link< T > * nextLink() const
Returns next link.
short int * _default_
Just a comptuationnal trick.
void _establishVarOrder_()
Computes an order for the final Decision graph that will minimize the number of re exploration.
const MultiDimFunctionGraph< GUM_ELEMENT, TerminalNodePolicy > * _DG1_
One of the two function graphs used for the operation.
MultiDimFunctionGraphOperator(const MultiDimFunctionGraph< GUM_ELEMENT, TerminalNodePolicy > *DG1, const MultiDimFunctionGraph< GUM_ELEMENT, TerminalNodePolicy > *DG2)
Default constructor.
HashTable< NodeId, short int * > _DG1InstantiationNeeded_
Table uses to know if a given node of first function graph has retrograde vrariables.
const MultiDimFunctionGraph< GUM_ELEMENT, TerminalNodePolicy > * _DG2_
The other one.
Idx _nbVar_
The total number of variable implied in the operation.
MultiDimFunctionGraph< GUM_ELEMENT, TerminalNodePolicy > * _rd_
The resulting function graph.
HashTable< double, NodeId > _explorationTable_
The hashtable used to know if two pair of nodes have already been visited.
HashTable< NodeId, short int * > _DG2InstantiationNeeded_
Table uses to know if a given node of second function graph has retrograde vrariables.
Idx _distance_(const MultiDimFunctionGraph< GUM_ELEMENT, TerminalNodePolicy > *, const DiscreteVariable *, const DiscreteVariable *)
Heuristic methods to decide which of two retrograde variables should come first.
MultiDimFunctionGraph< GUM_ELEMENT, TerminalNodePolicy > * compute()
Computes and builds the Function Graph that is the result of the operation.
NodeId _compute_(O4DGContext ¤tSituation, Idx lastInstVarPos)
The main recursion function.
const FUNCTOR< GUM_ELEMENT > _function_
The function to be performed on the leaves.
~MultiDimFunctionGraphOperator()
Default destructor.
void _findRetrogradeVariables_(const MultiDimFunctionGraph< GUM_ELEMENT, TerminalNodePolicy > *dg, HashTable< NodeId, short int * > &dgInstNeed)
Establish for each node in both function graph if it has retrograde variables beneath it.
static MultiDimFunctionGraph< GUM_ELEMENT, TerminalNodePolicy > * getReducedAndOrderedInstance()
Returns a reduced and ordered instance.
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.
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.
const NodeId & DG1Node() const
Get DG1 diagram current explored Node.
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)