aGrUM 2.3.2
a C++ library for (probabilistic) graphical models
fmdp_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-2025 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-2025 *
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#pragma once
41
42
50
51//======================================================================
52#include <cstdio>
53#include <iostream>
54//======================================================================
55#include <agrum/FMDP/fmdp.h>
56//======================================================================
57#define RECAST(x) reinterpret_cast< const MultiDimFunctionGraph< GUM_SCALAR >* >(x)
58
59namespace gum {
60
61
62 /* **************************************************************************************************
63 * **/
64 /* ** **/
65 /* ** Constructors / Destructors **/
66 /* ** **/
67 /* **************************************************************************************************
68 * **/
69
70 // ===========================================================================
71 // Default constructor.
72 // ===========================================================================
73 template < typename GUM_SCALAR >
74 INLINE FMDP< GUM_SCALAR >::FMDP(bool onDestructionDeleteVar) {
75 GUM_CONSTRUCTOR(FMDP);
76 _onDestructionDeleteVars_ = onDestructionDeleteVar;
77
78 // Default Action initialisation
79 _actionMap_.insert(0, new std::string("DEFAULT"));
81 _actionCostTable_.insert(0, nullptr);
82 _actionRewardTable_.insert(0, nullptr);
83 }
84
85 // ===========================================================================
86 // Destructor.
87 // ===========================================================================
88 template < typename GUM_SCALAR >
90 // Action Transition Graph deletion
91 for (auto iterA = _actionTransitionTable_.beginSafe();
92 iterA != _actionTransitionTable_.endSafe();
93 ++iterA) {
94 if (iterA.val()) {
95 for (auto iterH = (iterA.val())->beginSafe(); iterH != (iterA.val())->endSafe(); ++iterH)
96 if (iterH.val()) delete iterH.val();
97 delete iterA.val();
98 }
99 }
100
101 // Action cost graph deletion
102 for (auto iterA = _actionCostTable_.beginSafe(); iterA != _actionCostTable_.endSafe(); ++iterA)
103 if (iterA.val()) delete iterA.val();
105 // Action reward graph deletion
106 for (auto iterA = _actionRewardTable_.beginSafe(); iterA != _actionRewardTable_.endSafe();
107 ++iterA)
108 if (iterA.val()) delete iterA.val();
109
110 // Action Name deletion
111 for (auto iterId = _actionMap_.beginSafe(); iterId != _actionMap_.endSafe(); ++iterId)
112 delete iterId.second();
113
114 // Primed Variables deletion
115 for (auto varIter = _main2primed_.beginSafe(); varIter != _main2primed_.endSafe(); ++varIter) {
116 delete varIter.second();
117 if (_onDestructionDeleteVars_) delete varIter.first();
118 }
119
120 GUM_DESTRUCTOR(FMDP);
121 }
122
123 /* **************************************************************************************************
124 * **/
125 /* ** **/
126 /* ** Variable Handling Methods. **/
127 /* ** **/
128 /* **************************************************************************************************
129 * **/
130
131 // ===========================================================================
132 // Adds a variable to FMDP description
133 // @throw DuplicateElement if a similar variable already exists
134 // ===========================================================================
135 template < typename GUM_SCALAR >
137 if (_varSeq_.exists(var))
139 " Variable " << var->name() << " has already been inserted in FMDP.");
140
141
142 _varSeq_.insert(var);
143
144 // Prime version creation
145 DiscreteVariable* primeVar = var->clone();
146 primeVar->setName(var->name() + "'");
147 _main2primed_.insert(var, primeVar);
148 }
149
150 /* **************************************************************************************************
151 * **/
152 /* ** **/
153 /* ** Variable Handling Methods. **/
154 /* ** **/
155 /* **************************************************************************************************
156 * **/
157
158 // ===========================================================================
159 // Adds an action to FMDP description
160 // @throw DuplicateElement if an action with same name already exists
161 // ===========================================================================
162 template < typename GUM_SCALAR >
163 INLINE void FMDP< GUM_SCALAR >::addAction(Idx actionId, const std::string& action) {
164 if (actionId == 0) GUM_ERROR(DuplicateElement, " Action Id 0 is reserved.")
165
167 actIter != _actionMap_.endSafe();
168 ++actIter)
169 if (*(actIter.second()) == action)
171 " Action " << action << " has already been inserted in FMDP with this name.");
172
173 if (_actionMap_.existsFirst(actionId))
175 " An action with same id (" << actionId << ") has already been inserted.");
176
177 _actionMap_.insert(actionId, new std::string(action));
178
180 _actionCostTable_.insert(actionId, nullptr);
181 _actionRewardTable_.insert(actionId, nullptr);
182
183 _actionSeq_.insert(actionId);
184 }
185
186 /* **************************************************************************************************
187 * **/
188 /* ** **/
189 /* ** Transition methods. **/
190 /* ** **/
191 /* **************************************************************************************************
192 * **/
193
194 // ===========================================================================
195 // Adds a variable transition table to specified action
196 // @throw NotFound if action or var does not exists
197 // @throw DuplicateElement if variable already has a transition for this
198 // action
199 // ===========================================================================
200 template < typename GUM_SCALAR >
205 if (!_varSeq_.exists(var))
206 GUM_ERROR(NotFound, " Variable " << var->name() << " has not been declared before.")
207
209 GUM_ERROR(NotFound, " Action " << actionName(actionId) << " has not been declared before.");
210
211 if (_actionTransitionTable_[actionId]->exists(var))
213 " Variable " << var->name() << " already has a transition table in " << actionId
214 << " table.");
215
217 }
218
219 // ===========================================================================
220 // Returns transition associated to given in parameter variable and given
221 // action
222 // ===========================================================================
223 template < typename GUM_SCALAR >
227 GUM_ERROR(NotFound, " Action " << actionName(actionId) << " has not been declared before.");
228
230 return (*_actionTransitionTable_[actionId])[v];
231 else
232 return (*_actionTransitionTable_[0]).exists(v) ? (*_actionTransitionTable_[0])[v] : nullptr;
233 }
234
235 /* **************************************************************************************************
236 * **/
237 /* ** **/
238 /* ** Cost methods. **/
239 /* ** **/
240 /* **************************************************************************************************
241 * **/
243 // ===========================================================================
244 // Adds a cost table to specified action
245 // @throw NotFound if action does not exists
246 // @throw DuplicateElement if action already has a cost
247 // ===========================================================================
248 template < typename GUM_SCALAR >
249 INLINE void
252 if (!_actionCostTable_.exists(actionId))
253 GUM_ERROR(NotFound, " Action " << actionName(actionId) << " has not been declared before.");
255 if (_actionCostTable_[actionId] != nullptr)
256 GUM_ERROR(DuplicateElement, " Action " << actionName(actionId) << " already has a cost table")
257
260
261 // ===========================================================================
262 // Returns transition associated to given in parameter variable and given
263 // action
264 // ===========================================================================
265 template < typename GUM_SCALAR >
266 INLINE const MultiDimImplementation< GUM_SCALAR >* FMDP< GUM_SCALAR >::cost(Idx actionId) const {
267 if (!_actionCostTable_.exists(actionId))
268 GUM_ERROR(NotFound, " Action " << actionName(actionId) << " has not been declared before.");
271 return _actionCostTable_[0];
272 }
273
274 /* **************************************************************************************************
275 * **/
276 /* ** **/
277 /* ** Cost methods. **/
278 /* ** **/
279 /* **************************************************************************************************
280 * **/
281
282 // ===========================================================================
283 // Adds a default variable reward
284 // @throw DuplicateElement if a default reward exists already
285 // ===========================================================================
286 template < typename GUM_SCALAR >
287 INLINE void
290 if (!_actionRewardTable_.exists(actionId))
291 GUM_ERROR(NotFound, " Action " << actionName(actionId) << " has not been declared before.");
292
293 if (_actionRewardTable_[actionId] != nullptr)
295 " Action " << actionName(actionId) << " already has a reward table");
296
298 }
299
300 // ===========================================================================
301 // Returns transition associated to given in parameter variable and given
302 // action
303 // ===========================================================================
304 template < typename GUM_SCALAR >
307 if (!_actionRewardTable_.exists(actionId))
308 GUM_ERROR(NotFound, " Action " << actionName(actionId) << " has not been declared before.");
309
311 return _actionRewardTable_[0];
312 }
313
314 /* **************************************************************************************************
315 * **/
316 /* ** **/
317 /* ** Miscelleanous methods. **/
318 /* ** **/
319 /* **************************************************************************************************
320 * **/
321
322 // ===========================================================================
323 // Returns name of action given in parameter
324 // ===========================================================================
325 template < typename GUM_SCALAR >
326 INLINE const std::string& FMDP< GUM_SCALAR >::actionName(Idx actionId) const {
327 if (!_actionMap_.existsFirst(actionId))
328 GUM_ERROR(NotFound, "No action with " << actionId << " as identifiant.")
329
330 return *(_actionMap_.second(actionId));
331 }
332
333 // ===========================================================================
334 // Returns action id
335 // ===========================================================================
336 template < typename GUM_SCALAR >
337 INLINE Idx FMDP< GUM_SCALAR >::actionId(const std::string& action) const {
339 actIter != _actionMap_.end();
340 ++actIter)
341 if (*(actIter.second()) == action) { return actIter.first(); }
342
343 GUM_ERROR(NotFound, " Action " << action << " has not been declared before.")
344 }
345
346 template < typename GUM_SCALAR >
347 INLINE std::string FMDP< GUM_SCALAR >::toString() const {
348 std::stringstream fmdpCore;
349
350 for (auto actionIter = beginActions(); actionIter != endActions(); ++actionIter) {
351 for (auto varIter = beginVariables(); varIter != endVariables(); ++varIter)
352 if (this->transition(*actionIter, *varIter))
353 fmdpCore << RECAST(this->transition(*actionIter, *varIter))->toDot() << std::endl;
354 if (this->reward(*actionIter))
355 fmdpCore << RECAST(this->reward(*actionIter))->toDot() << std::endl;
356 }
357
358 for (auto varIter = beginVariables(); varIter != endVariables(); ++varIter)
359 if (this->transition(0, *varIter))
360 fmdpCore << RECAST(this->transition(0, *varIter))->toDot() << std::endl;
361 if (this->reward()) fmdpCore << RECAST(this->reward())->toDot() << std::endl;
362 return fmdpCore.str();
363 }
364
365 template < typename GUM_SCALAR >
367 Size s = 0;
368 for (auto actionIter = beginActions(); actionIter != endActions(); ++actionIter) {
369 for (auto varIter = beginVariables(); varIter != endVariables(); ++varIter)
370 if (this->transition(*actionIter, *varIter))
371 s += this->transition(*actionIter, *varIter)->realSize();
372 if (this->reward(*actionIter)) s += this->reward(*actionIter)->realSize();
373 }
374
375 for (auto varIter = beginVariables(); varIter != endVariables(); ++varIter)
376 if (this->transition(0, *varIter)) s += this->transition(0, *varIter)->realSize();
377 if (this->reward()) s += this->reward()->realSize();
378 return s;
379 }
380} // namespace gum
Safe iterators for bijectionIterator.
Definition bijection.h:1194
Unsafe iterators for bijection.
Definition bijection.h:1394
Base class for discrete random variable.
DiscreteVariable * clone() const override=0
Copy Factory.
Exception : a similar element already exists.
This class is used to implement factored decision process.
Definition fmdp.h:73
bool _onDestructionDeleteVars_
Boolean indicates whether or not main variables should be deleted on destruction of this instance Usu...
Definition fmdp.h:299
const std::string & actionName(Idx actionId) const
Definition fmdp_tpl.h:326
Sequence< Idx > _actionSeq_
Definition fmdp.h:278
Sequence< const DiscreteVariable * > _varSeq_
Sequence de variables and its iterator.
Definition fmdp.h:276
HashTable< Idx, VarTransitionTable< GUM_SCALAR > * > _actionTransitionTable_
Table which give for each action a table containing variables transition cpt.
Definition fmdp.h:288
void addCostForAction(Idx actionId, const MultiDimImplementation< GUM_SCALAR > *cost)
Adds a cost table to specified action.
Definition fmdp_tpl.h:250
const MultiDimImplementation< double > * transition(Idx actionId, const DiscreteVariable *v) const
Definition fmdp_tpl.h:225
Idx actionId(const std::string &) const
Returns action id.
Definition fmdp_tpl.h:337
HashTable< Idx, const MultiDimImplementation< GUM_SCALAR > * > _actionRewardTable_
Table which give for each action reward table.
Definition fmdp.h:294
HashTable< Idx, const MultiDimImplementation< GUM_SCALAR > * > _actionCostTable_
Table which give for each action cost table.
Definition fmdp.h:291
const MultiDimImplementation< GUM_SCALAR > * cost(Idx actionId=0) const
Returns the reward table of mdp.
Definition fmdp_tpl.h:266
SequenceIteratorSafe< const DiscreteVariable * > endVariables() const
Returns an iterator reference to the end of the list of variables.
Definition fmdp.h:116
SequenceIteratorSafe< Idx > beginActions() const
Returns an iterator reference to he beginning of the list of actions.
Definition fmdp.h:151
const MultiDimImplementation< GUM_SCALAR > * reward(Idx actionId=0) const
Returns the reward table of mdp.
Definition fmdp_tpl.h:306
SequenceIteratorSafe< const DiscreteVariable * > beginVariables() const
Returns an iterator reference to he beginning of the list of variables.
Definition fmdp.h:109
FMDP(bool onDestructionDeleteVar=false)
Default constructor.
Definition fmdp_tpl.h:74
Bijection< Idx, const std::string * > _actionMap_
Bijection mapping an action name to its id.
Definition fmdp.h:284
~FMDP()
Default destructor.
Definition fmdp_tpl.h:89
void addTransitionForAction(Idx actionId, const DiscreteVariable *var, const MultiDimImplementation< GUM_SCALAR > *transition)
Adds a variable transition table to specified action.
Definition fmdp_tpl.h:201
Bijection< const DiscreteVariable *, const DiscreteVariable * > _main2primed_
Definition fmdp.h:281
std::string toString() const
Displays the FMDP in a Dot format.
Definition fmdp_tpl.h:347
Size size() const
Returns the map binding main variables and prime variables.
Definition fmdp_tpl.h:366
void addAction(Idx actionId, const std::string &action)
Adds an action to FMDP description.
Definition fmdp_tpl.h:163
SequenceIteratorSafe< Idx > endActions() const
Returns an iterator reference to the end of the list of actions.
Definition fmdp.h:156
HashTable< const DiscreteVariable *, const MultiDimImplementation< GUM_SCALAR_O > * > VarTransitionTable
Definition fmdp.h:75
void addVariable(const DiscreteVariable *var)
Adds a variable to FMDP description.
Definition fmdp_tpl.h:136
void addRewardForAction(Idx actionId, const MultiDimImplementation< GUM_SCALAR > *reward)
Adds a default variable reward.
Definition fmdp_tpl.h:288
<agrum/base/multidim/multiDimImplementation.h>
virtual Size realSize() const =0
Returns the real number of parameters used for this table.
Exception : the element we looked for cannot be found.
void setName(const std::string &theValue)
sets the name of the variable
const std::string & name() const
returns the name of the variable
#define GUM_ERROR(type, msg)
Definition exceptions.h:72
Class for implementation of factored markov decision process.
#define RECAST(x)
Definition fmdp_tpl.h:57
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
gum is the global namespace for all aGrUM entities
Definition agrum.h:46