aGrUM 3.1.1
a C++ library for (probabilistic) graphical models
structuredPlaner_tpl.h
Go to the documentation of this file.
1/****************************************************************************
2 * This file is part of the aGrUM/pyAgrum library. *
3 * *
4 * Copyright (c) 2005-2026 by *
5 * - Pierre-Henri WUILLEMIN(_at_LIP6) *
6 * - Christophe GONZALES(_at_AMU) *
7 * *
8 * The aGrUM/pyAgrum library is free software; you can redistribute it *
9 * and/or modify it under the terms of either : *
10 * *
11 * - the GNU Lesser General Public License as published by *
12 * the Free Software Foundation, either version 3 of the License, *
13 * or (at your option) any later version, *
14 * - the MIT license (MIT), *
15 * - or both in dual license, as here. *
16 * *
17 * (see https://agrum.gitlab.io/articles/dual-licenses-lgplv3mit.html) *
18 * *
19 * This aGrUM/pyAgrum library is distributed in the hope that it will be *
20 * useful, but WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
21 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES MERCHANTABILITY or FITNESS *
22 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE *
23 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
24 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, *
25 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR *
26 * OTHER DEALINGS IN THE SOFTWARE. *
27 * *
28 * See LICENCES for more details. *
29 * *
30 * SPDX-FileCopyrightText: Copyright 2005-2026 *
31 * - Pierre-Henri WUILLEMIN(_at_LIP6) *
32 * - Christophe GONZALES(_at_AMU) *
33 * SPDX-License-Identifier: LGPL-3.0-or-later OR MIT *
34 * *
35 * Contact : info_at_agrum_dot_org *
36 * homepage : http://agrum.gitlab.io *
37 * gitlab : https://gitlab.com/agrumery/agrum *
38 * *
39 ****************************************************************************/
40
41#pragma once
42
43
51
52// =========================================================================
53#include <queue>
54#include <vector>
55// #include <algorithm>
56// #include <utility>
57// =========================================================================
59
61// =========================================================================
65// =========================================================================
67// =========================================================================
68
70#define RECAST(x) reinterpret_cast< const MultiDimFunctionGraph< GUM_ELEMENT >* >(x)
71
72namespace gum {
73
74
75 /* **************************************************************************************************
76 * **/
77 /* ** **/
78 /* ** Constructors / Destructors **/
79 /* ** **/
80 /* **************************************************************************************************
81 * **/
82
83 // ===========================================================================
84 // Default constructor
85 // ===========================================================================
86 template < typename GUM_ELEMENT >
88 GUM_ELEMENT discountFactor,
89 GUM_ELEMENT epsilon,
90 bool verbose) :
91 discountFactor_(discountFactor), operator_(opi), verbose_(verbose) {
92 GUM_CONSTRUCTOR(StructuredPlaner);
93
94 _threshold_ = epsilon;
95 vFunction_ = nullptr;
96 optimalPolicy_ = nullptr;
97 }
98
99 // ===========================================================================
100 // Default destructor
101 // ===========================================================================
102 template < typename GUM_ELEMENT >
104 GUM_DESTRUCTOR(StructuredPlaner);
105
106 if (vFunction_) { delete vFunction_; }
107
108 if (optimalPolicy_) delete optimalPolicy_;
109
110 delete operator_;
111 }
112
113 /* **************************************************************************************************
114 * **/
115 /* ** **/
116 /* ** Datastructure access methods **/
117 /* ** **/
118 /* **************************************************************************************************
119 * **/
120
121 // ===========================================================================
122 // Initializes data structure needed for making the planning
123 // ===========================================================================
124 template < typename GUM_ELEMENT >
126 // ************************************************************************
127 // Discarding the case where no \pi* have been computed
128 if (!optimalPolicy_ || optimalPolicy_->root() == 0) return "NO OPTIMAL POLICY CALCULATED YET";
129
130 // ************************************************************************
131 // Initialisation
132
133 // Declaration of the needed string stream
134 std::string output;
135 std::string terminalStream;
136 std::string nonTerminalStream;
137 std::string arcstream;
139 // First line for the toDot
140 output += "\ndigraph \" OPTIMAL POLICY \" {\n";
141
142 // Form line for the internal node stream en the terminal node stream
143 terminalStream += "node [shape = box];\n";
144 nonTerminalStream += "node [shape = ellipse];\n";
145
146 // For somme clarity in the final string
147 std::string tab = "\t";
149 // To know if we already checked a node or not
150 Set< NodeId > visited;
151
152 // FIFO of nodes to visit
153 std::queue< NodeId > fifo;
154
155 // Loading the FIFO
156 fifo.push(optimalPolicy_->root());
157 visited << optimalPolicy_->root();
159
160 // ************************************************************************
161 // Main loop
162 while (!fifo.empty()) {
163 // Node to visit
164 NodeId currentNodeId = fifo.front();
165 fifo.pop();
166
167 // Checking if it is terminal
168 if (optimalPolicy_->isTerminalNode(currentNodeId)) {
169 // Get back the associated ActionSet
170 ActionSet ase = optimalPolicy_->nodeValue(currentNodeId);
171
172 // Creating a line for this node
173 terminalStream += std::format("{0}{1};{0}{1} [label=\"{1} - ", tab, currentNodeId);
174
175 // Enumerating and adding to the line the associated optimal actions
176 for (SequenceIteratorSafe< Idx > valIter = ase.beginSafe(); valIter != ase.endSafe();
177 ++valIter) {
178 terminalStream += fmdp_->actionName(*valIter);
179 terminalStream += ' ';
180 }
181
182 // Terminating line
183 terminalStream += "\"];\n";
184 continue;
185 }
186
187 // Either wise
188 {
189 // Geting back the associated internal node
190 const InternalNode* currentNode = optimalPolicy_->node(currentNodeId);
191
192 // Creating a line in internalnode stream for this node
193 nonTerminalStream += std::format("{0}{1};{0}{1} [label=\"{1} - {2}\"];\n",
194 tab,
195 currentNodeId,
196 currentNode->nodeVar()->name());
197
198 // Going through the sons and agregating them according the the sons Ids
200 for (Idx sonIter = 0; sonIter < currentNode->nbSons(); ++sonIter) {
201 if (!visited.exists(currentNode->son(sonIter))) {
202 fifo.push(currentNode->son(sonIter));
203 visited << currentNode->son(sonIter);
204 }
205 if (!sonMap.exists(currentNode->son(sonIter)))
206 sonMap.insert(currentNode->son(sonIter), new LinkedList< Idx >());
207 sonMap[currentNode->son(sonIter)]->addLink(sonIter);
208 }
209
210 // Adding to the arc stram
211 for (auto sonIter = sonMap.beginSafe(); sonIter != sonMap.endSafe(); ++sonIter) {
212 arcstream += std::format("{}{} -> {} [label=\" ", tab, currentNodeId, sonIter.key());
213 Link< Idx >* modaIter = sonIter.val()->list();
214 while (modaIter) {
215 arcstream += currentNode->nodeVar()->label(modaIter->element());
216 if (modaIter->nextLink()) arcstream += ", ";
217 modaIter = modaIter->nextLink();
218 }
219 arcstream += "\",color=\"#00ff00\"];\n";
220 delete sonIter.val();
222 }
223 }
224
225 // Terminating
226 output += terminalStream + '\n' + nonTerminalStream + '\n' + arcstream + "\n}\n";
227
228 return output;
229 }
230
231 /* **************************************************************************************************
232 * **/
233 /* ** **/
234 /* ** Planning Methods **/
235 /* ** **/
236 /* **************************************************************************************************
237 * **/
238
239 // ===========================================================================
240 // Initializes data structure needed for making the planning
241 // ===========================================================================
242 template < typename GUM_ELEMENT >
244 fmdp_ = fmdp;
245
246 // Determination of the threshold value
248
249 // Establishement of sequence of variable elemination
250 for (auto varIter = fmdp_->beginVariables(); varIter != fmdp_->endVariables(); ++varIter)
251 elVarSeq_ << fmdp_->main2prime(*varIter);
252
253 // Initialisation of the value function
254 vFunction_ = operator_->getFunctionInstance();
255 optimalPolicy_ = operator_->getAggregatorInstance();
257 }
258
259 // ===========================================================================
260 // Performs a value iteration
261 // ===========================================================================
262 template < typename GUM_ELEMENT >
264 if (_firstTime_) {
265 this->initVFunction_();
266 _firstTime_ = false;
267 }
268
269 // *****************************************************************************************
270 // Main loop
271 // *****************************************************************************************
272 Idx nbIte = 0;
273 GUM_ELEMENT gap = _threshold_ + 1;
274 while ((gap > _threshold_) && (nbIte < nbStep)) {
275 ++nbIte;
276
278
279 // *****************************************************************************************
280 // Then we compare new value function and the old one
281 MultiDimFunctionGraph< GUM_ELEMENT >* deltaV = operator_->subtract(newVFunction, vFunction_);
282 gap = 0;
283
284 for (deltaV->beginValues(); deltaV->hasValue(); deltaV->nextValue())
285 if (gap < fabs(deltaV->value())) gap = fabs(deltaV->value());
286 delete deltaV;
287
288 if (verbose_)
289 std::cout << " ------------------- Fin itération n° " << nbIte << std::endl
290 << " Gap : " << gap << " - " << _threshold_ << std::endl;
291
292 // *****************************************************************************************
293 // And eventually we update pointers for next loop
294 delete vFunction_;
295 vFunction_ = newVFunction;
296 }
297
298 // *****************************************************************************************
299 // Policy matching value function research
300 // *****************************************************************************************
301 this->evalPolicy_();
302 }
303
304 // ===========================================================================
305 // Performs a single step of value iteration
306 // ===========================================================================
307 template < typename GUM_ELEMENT >
311
312 /* **************************************************************************************************
313 * **/
314 /* ** **/
315 /* ** Value Iteration Methods **/
316 /* ** **/
317 /* **************************************************************************************************
318 * **/
319
320
321 // ===========================================================================
322 // Performs a single step of value iteration
323 // ===========================================================================
324 template < typename GUM_ELEMENT >
326 // *****************************************************************************************
327 // Loop reset
328 MultiDimFunctionGraph< GUM_ELEMENT >* newVFunction = operator_->getFunctionInstance();
329 newVFunction->copyAndReassign(*vFunction_, fmdp_->mapMainPrime());
330
331 // *****************************************************************************************
332 // For each action
333 std::vector< MultiDimFunctionGraph< GUM_ELEMENT >* > qActionsSet;
334 for (auto actionIter = fmdp_->beginActions(); actionIter != fmdp_->endActions(); ++actionIter) {
335 MultiDimFunctionGraph< GUM_ELEMENT >* qAction = this->evalQaction_(newVFunction, *actionIter);
336 qActionsSet.push_back(qAction);
337 }
338 delete newVFunction;
339
340 // *****************************************************************************************
341 // Next to evaluate main value function, we take maximise over all action
342 // value, ...
343 newVFunction = this->maximiseQactions_(qActionsSet);
344
345 // *******************************************************************************************
346 // Next, we eval the new function value
347 newVFunction = this->addReward_(newVFunction);
348
349 return newVFunction;
350 }
351
352 // ===========================================================================
353 // Evals the q function for current fmdp action
354 // ===========================================================================
355 template < typename GUM_ELEMENT >
358 Idx actionId) {
359 // ******************************************************************************
360 // Initialisation :
361 // Creating a copy of last Vfunction to deduce from the new Qaction
362 // And finding the first var to eleminate (the one at the end)
363
364 return operator_->regress(Vold, actionId, this->fmdp_, this->elVarSeq_);
365 }
366
367 // ===========================================================================
368 // Maximise the AAction to iobtain the vFunction
369 // ===========================================================================
370 template < typename GUM_ELEMENT >
372 std::vector< MultiDimFunctionGraph< GUM_ELEMENT >* >& qActionsSet) {
373 MultiDimFunctionGraph< GUM_ELEMENT >* newVFunction = qActionsSet.back();
374 qActionsSet.pop_back();
375
376 while (!qActionsSet.empty()) {
377 MultiDimFunctionGraph< GUM_ELEMENT >* qAction = qActionsSet.back();
378 qActionsSet.pop_back();
379 newVFunction = operator_->maximize(newVFunction, qAction);
380 }
381
382 return newVFunction;
383 }
384
385 // ===========================================================================
386 // Maximise the AAction to iobtain the vFunction
387 // ===========================================================================
388 template < typename GUM_ELEMENT >
390 std::vector< MultiDimFunctionGraph< GUM_ELEMENT >* >& qActionsSet) {
391 MultiDimFunctionGraph< GUM_ELEMENT >* newVFunction = qActionsSet.back();
392 qActionsSet.pop_back();
393
394 while (!qActionsSet.empty()) {
395 MultiDimFunctionGraph< GUM_ELEMENT >* qAction = qActionsSet.back();
396 qActionsSet.pop_back();
397 newVFunction = operator_->minimize(newVFunction, qAction);
398 }
399
400 return newVFunction;
401 }
402
403 // ===========================================================================
404 // Updates the value function by multiplying by discount and adding reward
405 // ===========================================================================
406 template < typename GUM_ELEMENT >
409 Idx actionId) {
410 // *****************************************************************************************
411 // ... we multiply the result by the discount factor, ...
412 MultiDimFunctionGraph< GUM_ELEMENT >* newVFunction = operator_->getFunctionInstance();
413 newVFunction->copyAndMultiplyByScalar(*Vold, this->discountFactor_);
414 delete Vold;
415
416 // *****************************************************************************************
417 // ... and finally add reward
418 newVFunction = operator_->add(newVFunction, RECAST(fmdp_->reward(actionId)));
419
420 return newVFunction;
421 }
422
423 /* **************************************************************************************************
424 * **/
425 /* ** **/
426 /* ** Optimal Policy Evaluation Methods **/
427 /* ** **/
428 /* **************************************************************************************************
429 * **/
430
431 // ===========================================================================
432 // Evals the policy corresponding to the given value function
433 // ===========================================================================
434 template < typename GUM_ELEMENT >
436 // *****************************************************************************************
437 // Loop reset
438 MultiDimFunctionGraph< GUM_ELEMENT >* newVFunction = operator_->getFunctionInstance();
439 newVFunction->copyAndReassign(*vFunction_, fmdp_->mapMainPrime());
440
441 std::vector< MultiDimFunctionGraph< ArgMaxSet< GUM_ELEMENT, Idx >, SetTerminalNodePolicy >* >
442 argMaxQActionsSet;
443 // *****************************************************************************************
444 // For each action
445 for (auto actionIter = fmdp_->beginActions(); actionIter != fmdp_->endActions(); ++actionIter) {
446 MultiDimFunctionGraph< GUM_ELEMENT >* qAction = this->evalQaction_(newVFunction, *actionIter);
447
448 qAction = this->addReward_(qAction);
449
450 argMaxQActionsSet.push_back(makeArgMax_(qAction, *actionIter));
451 }
452 delete newVFunction;
453
454
455 // *****************************************************************************************
456 // Next to evaluate main value function, we take maximise over all action
457 // value, ...
459 = argmaximiseQactions_(argMaxQActionsSet);
460
461 // *****************************************************************************************
462 // Next to evaluate main value function, we take maximise over all action
463 // value, ...
464 extractOptimalPolicy_(argMaxVFunction);
465 }
466
467 // ===========================================================================
468 // Creates a copy of given in parameter decision Graph and replaces leaves
469 // of that Graph by a pair containing value of the leaf and action to which
470 // is bind this Graph (given in parameter).
471 // ===========================================================================
472 template < typename GUM_ELEMENT >
476 Idx actionId) {
478 = operator_->getArgMaxFunctionInstance();
479
480 // Insertion des nouvelles variables
482 = qAction->variablesSequence().beginSafe();
483 varIter != qAction->variablesSequence().endSafe();
484 ++varIter)
485 amcpy->add(**varIter);
486
488 amcpy->manager()->setRootNode(
489 _recurArgMaxCopy_(qAction->root(), actionId, qAction, amcpy, src2dest));
490
491 delete qAction;
492 return amcpy;
493 }
494
495 // ==========================================================================
496 // Recursion part for the createArgMaxCopy
497 // ==========================================================================
498 template < typename GUM_ELEMENT >
500 NodeId currentNodeId,
501 Idx actionId,
504 HashTable< NodeId, NodeId >& visitedNodes) {
505 if (visitedNodes.exists(currentNodeId)) return visitedNodes[currentNodeId];
506
507 NodeId nody;
508 if (src->isTerminalNode(currentNodeId)) {
509 ArgMaxSet< GUM_ELEMENT, Idx > leaf(src->nodeValue(currentNodeId), actionId);
510 nody = argMaxCpy->manager()->addTerminalNode(leaf);
511 } else {
512 const InternalNode* currentNode = src->node(currentNodeId);
513 NodeId* sonsMap = static_cast< NodeId* >(
514 SOA_ALLOCATE(sizeof(NodeId) * currentNode->nodeVar()->domainSize()));
515 for (Idx moda = 0; moda < currentNode->nodeVar()->domainSize(); ++moda)
516 sonsMap[moda]
517 = _recurArgMaxCopy_(currentNode->son(moda), actionId, src, argMaxCpy, visitedNodes);
518 nody = argMaxCpy->manager()->addInternalNode(currentNode->nodeVar(), sonsMap);
519 }
520 visitedNodes.insert(currentNodeId, nody);
521 return nody;
522 }
523
524 // ===========================================================================
525 // Performs argmax_a Q(s,a)
526 // ===========================================================================
527 template < typename GUM_ELEMENT >
531 SetTerminalNodePolicy >* >& qActionsSet) {
533 = qActionsSet.back();
534 qActionsSet.pop_back();
535
536 while (!qActionsSet.empty()) {
538 = qActionsSet.back();
539 qActionsSet.pop_back();
540 newVFunction = operator_->argmaximize(newVFunction, qAction);
541 }
542
543 return newVFunction;
544 }
545
546 // ===========================================================================
547 // Creates a copy of given in parameter decision Graph and replaces leaves
548 // of that Graph by a pair containing value of the leaf and action to which
549 // is bind this Graph (given in parameter).
550 // ===========================================================================
551 template < typename GUM_ELEMENT >
554 argMaxOptimalValueFunction) {
555 optimalPolicy_->clear();
556
557 // Insertion des nouvelles variables
559 = argMaxOptimalValueFunction->variablesSequence().beginSafe();
560 varIter != argMaxOptimalValueFunction->variablesSequence().endSafe();
561 ++varIter)
562 optimalPolicy_->add(**varIter);
563
565 optimalPolicy_->manager()->setRootNode(_recurExtractOptPol_(argMaxOptimalValueFunction->root(),
566 argMaxOptimalValueFunction,
567 src2dest));
568
569 delete argMaxOptimalValueFunction;
570 }
571
572 // ==========================================================================
573 // Recursion part for the createArgMaxCopy
574 // ==========================================================================
575 template < typename GUM_ELEMENT >
577 NodeId currentNodeId,
579 argMaxOptVFunc,
580 HashTable< NodeId, NodeId >& visitedNodes) {
581 if (visitedNodes.exists(currentNodeId)) return visitedNodes[currentNodeId];
582
583 NodeId nody;
584 if (argMaxOptVFunc->isTerminalNode(currentNodeId)) {
585 ActionSet leaf;
586 _transferActionIds_(argMaxOptVFunc->nodeValue(currentNodeId), leaf);
587 nody = optimalPolicy_->manager()->addTerminalNode(leaf);
588 } else {
589 const InternalNode* currentNode = argMaxOptVFunc->node(currentNodeId);
590 NodeId* sonsMap = static_cast< NodeId* >(
591 SOA_ALLOCATE(sizeof(NodeId) * currentNode->nodeVar()->domainSize()));
592 for (Idx moda = 0; moda < currentNode->nodeVar()->domainSize(); ++moda)
593 sonsMap[moda] = _recurExtractOptPol_(currentNode->son(moda), argMaxOptVFunc, visitedNodes);
594 nody = optimalPolicy_->manager()->addInternalNode(currentNode->nodeVar(), sonsMap);
595 }
596 visitedNodes.insert(currentNodeId, nody);
597 return nody;
598 }
599
600 // ==========================================================================
601 // Extract from an ArgMaxSet the associated ActionSet
602 // ==========================================================================
603 template < typename GUM_ELEMENT >
604 void
606 ActionSet& dest) {
607 for (auto idi = src.beginSafe(); idi != src.endSafe(); ++idi)
608 dest += *idi;
609 }
610
611 template < typename GUM_ELEMENT >
614 GUM_ELEMENT epsilon,
615 bool verbose) {
617 discountFactor,
618 epsilon,
619 verbose);
620 }
621
622 template < typename GUM_ELEMENT >
625 GUM_ELEMENT epsilon,
626 bool verbose) {
628 discountFactor,
629 epsilon,
630 verbose);
631 }
632
633 template < typename GUM_ELEMENT >
637
638 template < typename GUM_ELEMENT >
642
643 template < typename GUM_ELEMENT >
645 return vFunction_ != nullptr ? vFunction_->realSize() : 0;
646 }
647
648 template < typename GUM_ELEMENT >
653
654 template < typename GUM_ELEMENT >
658
659} // end of namespace gum
A class to store the optimal actions.
Definition actionSet.h:98
SequenceIteratorSafe< Idx > beginSafe() const
Iterator beginning.
SequenceIteratorSafe< Idx > endSafe() const
Iterator end.
Class to handle efficiently argMaxSet.
Definition argMaxSet.h:78
SequenceIteratorSafe< GUM_SCALAR_SEQ > beginSafe() const
Iterator beginning.
SequenceIteratorSafe< GUM_SCALAR_SEQ > endSafe() const
Iterator end.
virtual Size domainSize() const =0
bool hasValue() const override
Indicates if constant safe iterator has reach end of terminal nodes list.
void nextValue() const override
Increments the constant safe iterator.
void beginValues() const override
Initializes the constant safe iterator on terminal nodes.
const GUM_ELEMENT & value() const override
Returns the value of the current terminal nodes pointed by the constant safe iterator.
This class is used to implement factored decision process.
Definition fmdp.h:75
The class for generic Hash Tables.
Definition hashTable.h:640
iterator_safe beginSafe()
Returns the safe 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_safe & endSafe() noexcept
Returns the safe iterator pointing to the end of the hashtable.
bool exists(const Key &key) const
Checks whether there exists an element with a given key in the hashtable.
<agrum/FMDP/SDyna/IOperatorStrategy.h>
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.
Chain list allocated using the SmallObjectAllocator.
Definition link.h:155
<agrum/FMDP/planning/mddOperatorStrategy.h>
Class implementingting a function graph.
void add(const DiscreteVariable &v) override
Adds a new var to the variables of the multidimensional matrix.
const NodeId & root() const
Returns the id of the root node from the diagram.
void copyAndMultiplyByScalar(const MultiDimFunctionGraph< GUM_ELEMENT, TerminalNodePolicy > &src, GUM_ELEMENT gamma)
Copies src diagrams and multiply every value by the given scalar.
bool isTerminalNode(const NodeId &node) const
Indicates if given node is terminal or not.
void copyAndReassign(const MultiDimFunctionGraph< GUM_ELEMENT, TerminalNodePolicy > &src, const Bijection< const DiscreteVariable *, const DiscreteVariable * > &reassign)
Copies src diagrams structure into this diagrams.
const GUM_ELEMENT & nodeValue(NodeId n) const
Returns value associated to given node.
const InternalNode * node(NodeId n) const
Returns internalNode structure associated to that nodeId.
MultiDimFunctionGraphManager< GUM_ELEMENT, TerminalNodePolicy > * manager()
Returns a const reference to the manager of this diagram.
const Sequence< const DiscreteVariable * > & variablesSequence() const override
Returns a const ref to the sequence of DiscreteVariable*.
Implementation of a Terminal Node Policy that maps nodeid to a set of value.
bool exists(const Key &k) const
Indicates whether a given elements belong to the set.
Definition set_tpl.h:504
<agrum/FMDP/planning/structuredPlaner.h>
virtual MultiDimFunctionGraph< ArgMaxSet< GUM_ELEMENT, Idx >, SetTerminalNodePolicy > * argmaximiseQactions_(std::vector< MultiDimFunctionGraph< ArgMaxSet< GUM_ELEMENT, Idx >, SetTerminalNodePolicy > * > &)
Performs argmax_a Q(s,a).
Size optimalPolicySize() override
Returns optimalPolicy computed so far current size.
const FMDP< GUM_ELEMENT > * fmdp()
Returns a const ptr on the Factored Markov Decision Process on which we're planning.
NodeId _recurExtractOptPol_(NodeId, const MultiDimFunctionGraph< ArgMaxSet< GUM_ELEMENT, Idx >, SetTerminalNodePolicy > *, HashTable< NodeId, NodeId > &)
Recursion part for the createArgMaxCopy.
gum::VariableSet elVarSeq_
A Set to eleminate primed variables.
void initialize(const FMDP< GUM_ELEMENT > *fmdp) override
Initializes data structure needed for making the planning.
GUM_ELEMENT discountFactor_
Discount Factor used for infinite horizon planning.
void _transferActionIds_(const ArgMaxSet< GUM_ELEMENT, Idx > &, ActionSet &)
Extract from an ArgMaxSet the associated ActionSet.
IOperatorStrategy< GUM_ELEMENT > * operator_
void extractOptimalPolicy_(const MultiDimFunctionGraph< ArgMaxSet< GUM_ELEMENT, Idx >, SetTerminalNodePolicy > *optimalValueFunction)
From V(s)* = argmax_a Q*(s,a), this function extract pi*(s) This function mainly consists in extracti...
void makePlanning(Idx nbStep=1000000) override
Performs a value iteration.
virtual MultiDimFunctionGraph< GUM_ELEMENT > * addReward_(MultiDimFunctionGraph< GUM_ELEMENT > *function, Idx actionId=0)
Perform the R(s) + gamma . function.
MultiDimFunctionGraph< ArgMaxSet< GUM_ELEMENT, Idx >, SetTerminalNodePolicy > * makeArgMax_(const MultiDimFunctionGraph< GUM_ELEMENT > *Qaction, Idx actionId)
Creates a copy of given Qaction that can be exploit by a Argmax.
std::string optimalPolicy2String() override
Provide a better toDot for the optimal policy where the leaves have the action name instead of its id...
const MultiDimFunctionGraph< GUM_ELEMENT > * vFunction()
Returns a const ptr on the value function computed so far.
MultiDimFunctionGraph< ActionSet, SetTerminalNodePolicy > * optimalPolicy() override
Returns the best policy obtained so far.
bool verbose_
Boolean used to indcates whether or not iteration informations should be displayed on terminal.
static StructuredPlaner< GUM_ELEMENT > * spumddInstance(GUM_ELEMENT discountFactor=0.9, GUM_ELEMENT epsilon=0.00001, bool verbose=true)
static StructuredPlaner< GUM_ELEMENT > * sviInstance(GUM_ELEMENT discountFactor=0.9, GUM_ELEMENT epsilon=0.00001, bool verbose=true)
virtual MultiDimFunctionGraph< GUM_ELEMENT > * minimiseFunctions_(std::vector< MultiDimFunctionGraph< GUM_ELEMENT > * > &)
Performs min_i F_i.
StructuredPlaner(IOperatorStrategy< GUM_ELEMENT > *opi, GUM_ELEMENT discountFactor, GUM_ELEMENT epsilon, bool verbose)
Default constructor.
Size vFunctionSize() override
Returns vFunction computed so far current size.
MultiDimFunctionGraph< ActionSet, SetTerminalNodePolicy > * optimalPolicy_
MultiDimFunctionGraph< double > * vFunction_
virtual MultiDimFunctionGraph< GUM_ELEMENT > * evalQaction_(const MultiDimFunctionGraph< GUM_ELEMENT > *, Idx)
Performs the P(s'|s,a).V^{t-1}(s') part of the value itération.
virtual void initVFunction_()
Performs a single step of value iteration.
virtual MultiDimFunctionGraph< GUM_ELEMENT > * maximiseQactions_(std::vector< MultiDimFunctionGraph< GUM_ELEMENT > * > &)
Performs max_a Q(s,a).
virtual MultiDimFunctionGraph< double > * valueIteration_()
NodeId _recurArgMaxCopy_(NodeId, Idx, const MultiDimFunctionGraph< GUM_ELEMENT > *, MultiDimFunctionGraph< ArgMaxSet< GUM_ELEMENT, Idx >, SetTerminalNodePolicy > *, HashTable< NodeId, NodeId > &)
Recursion part for the createArgMaxCopy.
~StructuredPlaner() override
Default destructor.
<agrum/FMDP/planning/treeOperatorStrategy.h>
const std::string & name() const
returns the name of the variable
This files contains several function objects that are not (yet) defined in the STL.
std::size_t Size
In aGrUM, hashed values are unsigned long int.
Definition types.h:74
Size Idx
Type for indexes.
Definition types.h:79
Size NodeId
Type for node ids.
Header files of gum::Instantiation.
Useful macros for maths.
#define RECAST(x)
For shorter line and hence more comprehensive code only.
Headers of MultiDimFunctionGraph.
gum is the global namespace for all aGrUM entities
Definition agrum.h:46
#define SOA_ALLOCATE(x)
Headers of the StructuredPlaner planer class.
Header of the Tensor class.