The main recursion function.
317 if (
_DG1_->isTerminalNode(currentSituation.DG1Node())
318 &&
_DG2_->isTerminalNode(currentSituation.DG2Node())) {
322 GUM_SCALAR tempVal =
_combine_(
_DG1_->nodeValue(currentSituation.DG1Node()),
323 _DG2_->nodeValue(currentSituation.DG2Node()));
326 return _rd_->manager()->addTerminalNode(newVal);
338 =
_DG1_->isTerminalNode(currentSituation.DG1Node())
340 :
_rd_->variablesSequence().pos(
_DG1_->node(currentSituation.DG1Node())->nodeVar());
345 =
_DG2_->isTerminalNode(currentSituation.DG2Node())
347 :
_rd_->variablesSequence().pos(
_DG2_->node(currentSituation.DG2Node())->nodeVar());
349 short int* instNeeded =
static_cast< short int*
>(
ALLOCATE(
sizeof(
short int) *
_nbVar_));
352 instNeeded[i] = dg1NeededVar[i] + dg2NeededVar[i];
355 double curSitKey = currentSituation.key(instNeeded);
358 DEALLOCATE(instNeeded,
sizeof(
short int) * _nbVar_);
365 NodeId origDG1 = currentSituation.DG1Node(), origDG2 = currentSituation.DG2Node();
367 const MultiDimFunctionGraph< GUM_SCALAR, TerminalNodePolicy >* leaddg =
nullptr;
369 Idx leadVarPos =
_rd_->variablesSequence().size();
370 typedef void (O4DGContext::*SetNodeFunction)(
const NodeId&);
371 SetNodeFunction leadFunction =
nullptr;
373 bool sameVar =
false;
375 if (!
_DG1_->isTerminalNode(currentSituation.DG1Node())) {
376 if (currentSituation.varModality(dg1CurrentVarPos) != 0) {
379 currentSituation.setDG1Node(
_DG1_->node(currentSituation.DG1Node())
380 ->son(currentSituation.varModality(dg1CurrentVarPos) - 1));
382 newNode =
_compute_(currentSituation, lastInstVarPos);
384 currentSituation.setDG1Node(origDG1);
385 currentSituation.setDG2Node(origDG2);
387 DEALLOCATE(instNeeded,
sizeof(
short int) * _nbVar_);
393 leadNodeId = currentSituation.DG1Node();
394 leadVarPos = dg1CurrentVarPos;
398 if (!
_DG2_->isTerminalNode(currentSituation.DG2Node())) {
399 if (currentSituation.varModality(dg2CurrentVarPos) != 0) {
402 currentSituation.setDG2Node(
_DG2_->node(currentSituation.DG2Node())
403 ->son(currentSituation.varModality(dg2CurrentVarPos) - 1));
405 newNode =
_compute_(currentSituation, lastInstVarPos);
407 currentSituation.setDG1Node(origDG1);
408 currentSituation.setDG2Node(origDG2);
410 DEALLOCATE(instNeeded,
sizeof(
short int) * _nbVar_);
415 if (leadVarPos == dg2CurrentVarPos) { sameVar =
true; }
417 if (leadVarPos > dg2CurrentVarPos) {
419 leadNodeId = currentSituation.DG2Node();
420 leadVarPos = dg2CurrentVarPos;
430 for (
Idx varPos = lastInstVarPos + 1; varPos < leadVarPos; ++varPos) {
431 if (instNeeded[varPos]) {
432 const DiscreteVariable* curVar =
_rd_->variablesSequence().atPos(varPos);
435 for (
Idx modality = 0; modality < curVar->domainSize(); modality++) {
436 currentSituation.chgVarModality(varPos, modality + 1);
438 sonsIds[modality] =
_compute_(currentSituation, varPos);
441 newNode =
_rd_->manager()->addInternalNode(curVar, sonsIds);
444 currentSituation.chgVarModality(varPos, 0);
445 currentSituation.setDG1Node(origDG1);
446 currentSituation.setDG2Node(origDG2);
448 DEALLOCATE(instNeeded,
sizeof(
short int) * _nbVar_);
461 _DG2_->nodeValue(
_DG2_->node(origDG2)->son(targetModa))));
462 newNode =
_rd_->manager()->addTerminalNode(newVal);
464 DEALLOCATE(instNeeded,
sizeof(
short int) * _nbVar_);
467 if (
_DG1_->isTerminalNode(origDG1)) {
473 _DG2_->nodeValue(
_DG2_->node(origDG2)->son(targetModa))));
474 newNode =
_rd_->manager()->addTerminalNode(newVal);
476 DEALLOCATE(instNeeded,
sizeof(
short int) * _nbVar_);
485 _DG2_->nodeValue(origDG2)));
486 newNode =
_rd_->manager()->addTerminalNode(newVal);
488 DEALLOCATE(instNeeded,
sizeof(
short int) * _nbVar_);
501 const InternalNode* dg1Node =
_DG1_->node(origDG1);
502 const InternalNode* dg2Node =
_DG2_->node(origDG2);
504 const DiscreteVariable* curVar = dg1Node->nodeVar();
505 Idx varPos =
_rd_->variablesSequence().pos(curVar);
508 for (
Idx modality = 0; modality < curVar->domainSize(); modality++) {
509 currentSituation.chgVarModality(varPos, modality + 1);
510 currentSituation.setDG1Node(dg1Node->son(modality));
511 currentSituation.setDG2Node(dg2Node->son(modality));
513 sonsIds[modality] =
_compute_(currentSituation, varPos);
516 newNode =
_rd_->manager()->addInternalNode(curVar, sonsIds);
519 currentSituation.chgVarModality(varPos, 0);
520 currentSituation.setDG1Node(origDG1);
521 currentSituation.setDG2Node(origDG2);
523 DEALLOCATE(instNeeded,
sizeof(
short int) * _nbVar_);
529 const InternalNode* leaddgNode = leaddg->node(leadNodeId);
531 const DiscreteVariable* curVar = leaddgNode->nodeVar();
534 for (
Idx modality = 0; modality < curVar->domainSize(); modality++) {
535 currentSituation.chgVarModality(leadVarPos, modality + 1);
536 (currentSituation.*leadFunction)(leaddgNode->son(modality));
538 sonsIds[modality] =
_compute_(currentSituation, leadVarPos);
541 newNode =
_rd_->manager()->addInternalNode(curVar, sonsIds);
544 currentSituation.chgVarModality(leadVarPos, 0);
545 currentSituation.setDG1Node(origDG1);
546 currentSituation.setDG2Node(origDG2);
548 DEALLOCATE(instNeeded,
sizeof(
short int) * _nbVar_);
const PROJECTOPERATOR< GUM_SCALAR > _project_
bool exists(const Key &key) const
Checks whether there exists an element with a given key in the hashtable.
NodeId _compute_(O4DGContext ¤tSituation, Idx lastInstVarPos)
The main recursion function.
HashTable< NodeId, short int *> _DG1InstantiationNeeded_
Table uses to know if a given node of given function graph has retrograde variables.
MultiDimFunctionGraph< GUM_SCALAR, TerminalNodePolicy > * _rd_
The resulting function graph.
const COMBINEOPERATOR< GUM_SCALAR > _combine_
The functions to be performed on the leaves.
virtual Size domainSize() const =0
void setDG1Node(const NodeId &)
Set DG1 diagram current explored Node.
HashTable< double, NodeId > _explorationTable_
The hashtable used to know if two pair of nodes have already been visited.
short int * _default_
Just a computationnal trick.
void setDG2Node(const NodeId &)
Set DG2 diagram current explored Node.
Idx _nbVar_
The total number of variable implied in the operation.
const MultiDimFunctionGraph< GUM_SCALAR, TerminalNodePolicy > * _DG1_
One of the two function graphs used for the operation.
const MultiDimFunctionGraph< GUM_SCALAR, TerminalNodePolicy > * _DG2_
The other one.
const DiscreteVariable * _targetVar_
The variable we work on to eleminate.
HashTable< NodeId, short int *> _DG2InstantiationNeeded_
value_type & insert(const Key &key, const Val &val)
Adds a new element (actually a copy of this element) into the hash table.
Size NodeId
Type for node ids.
const GUM_SCALAR _neutral_
The function to be performed on the leaves.