aGrUM 3.1.1
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-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 <cstdio>
54#include <iostream>
55//======================================================================
56#include <agrum/FMDP/fmdp.h>
57
58//======================================================================
59
60namespace gum {
61
62
63 /* **************************************************************************************************
64 * **/
65 /* ** **/
66 /* ** Constructors / Destructors **/
67 /* ** **/
68 /* **************************************************************************************************
69 * **/
70
71 // ===========================================================================
72 // Default constructor.
73 // ===========================================================================
74 template < typename GUM_ELEMENT >
75 FMDP< GUM_ELEMENT >::FMDP(bool onDestructionDeleteVar) {
76 GUM_CONSTRUCTOR(FMDP);
77 _onDestructionDeleteVars_ = onDestructionDeleteVar;
78
79 // Default Action initialisation
80 _actionMap_.insert(0, new std::string("DEFAULT"));
82 _actionCostTable_.insert(0, nullptr);
83 _actionRewardTable_.insert(0, nullptr);
84 }
85
86 // ===========================================================================
87 // Destructor.
88 // ===========================================================================
89 template < typename GUM_ELEMENT >
91 // Action Transition Graph deletion
92 for (auto iterA = _actionTransitionTable_.beginSafe();
93 iterA != _actionTransitionTable_.endSafe();
94 ++iterA) {
95 if (iterA.val()) {
96 for (auto iterH = (iterA.val())->beginSafe(); iterH != (iterA.val())->endSafe(); ++iterH)
97 if (iterH.val()) delete iterH.val();
98 delete iterA.val();
99 }
100 }
101
102 // Action cost graph deletion
103 for (auto iterA = _actionCostTable_.beginSafe(); iterA != _actionCostTable_.endSafe(); ++iterA)
104 if (iterA.val()) delete iterA.val();
105
106 // Action reward graph deletion
107 for (auto iterA = _actionRewardTable_.beginSafe(); iterA != _actionRewardTable_.endSafe();
108 ++iterA)
109 if (iterA.val()) delete iterA.val();
110
111 // Action Name deletion
112 for (auto iterId = _actionMap_.beginSafe(); iterId != _actionMap_.endSafe(); ++iterId)
113 delete iterId.second();
114
115 // Primed Variables deletion
116 for (auto varIter = _main2primed_.beginSafe(); varIter != _main2primed_.endSafe(); ++varIter) {
117 delete varIter.second();
118 if (_onDestructionDeleteVars_) delete varIter.first();
119 }
120
121 GUM_DESTRUCTOR(FMDP);
122 }
123
124 /* **************************************************************************************************
125 * **/
126 /* ** **/
127 /* ** Variable Handling Methods. **/
128 /* ** **/
129 /* **************************************************************************************************
130 * **/
131
132 // ===========================================================================
133 // Adds a variable to FMDP description
134 // @throw DuplicateElement if a similar variable already exists
135 // ===========================================================================
136 template < typename GUM_ELEMENT >
138 if (_varSeq_.exists(var))
140 " Variable " << var->name() << " has already been inserted in FMDP.");
141
142
143 _varSeq_.insert(var);
145 // Prime version creation
146 DiscreteVariable* primeVar = var->clone();
147 primeVar->setName(var->name() + "'");
148 _main2primed_.insert(var, primeVar);
150
151 /* **************************************************************************************************
152 * **/
153 /* ** **/
154 /* ** Variable Handling Methods. **/
155 /* ** **/
156 /* **************************************************************************************************
157 * **/
158
159 // ===========================================================================
160 // Adds an action to FMDP description
161 // @throw DuplicateElement if an action with same name already exists
162 // ===========================================================================
163 template < typename GUM_ELEMENT >
164 void FMDP< GUM_ELEMENT >::addAction(Idx actionId, std::string_view action) {
165 if (actionId == 0) GUM_ERROR(DuplicateElement, " Action Id 0 is reserved.")
166
168 actIter != _actionMap_.endSafe();
169 ++actIter)
170 if (*(actIter.second()) == action)
172 " Action " << action << " has already been inserted in FMDP with this name.");
174 if (_actionMap_.existsFirst(actionId))
176 " An action with same id (" << actionId << ") has already been inserted.");
177
178 _actionMap_.insert(actionId, new std::string(action));
179
181 _actionCostTable_.insert(actionId, nullptr);
182 _actionRewardTable_.insert(actionId, nullptr);
183
184 _actionSeq_.insert(actionId);
185 }
186
187 /* **************************************************************************************************
188 * **/
189 /* ** **/
190 /* ** Transition methods. **/
191 /* ** **/
192 /* **************************************************************************************************
193 * **/
195 // ===========================================================================
196 // Adds a variable transition table to specified action
197 // @throw NotFound if action or var does not exists
198 // @throw DuplicateElement if variable already has a transition for this
199 // action
200 // ===========================================================================
201 template < typename GUM_ELEMENT >
204 const DiscreteVariable* var,
206 if (!_varSeq_.exists(var))
207 GUM_ERROR(NotFound, " Variable " << var->name() << " has not been declared before.")
208
210 GUM_ERROR(NotFound, " Action " << actionName(actionId) << " has not been declared before.");
211
212 if (_actionTransitionTable_[actionId]->exists(var))
214 " Variable " << var->name() << " already has a transition table in " << actionId
215 << " table.");
216
219
220 // ===========================================================================
221 // Returns transition associated to given in parameter variable and given
222 // action
223 // ===========================================================================
224 template < typename GUM_ELEMENT >
228 GUM_ERROR(NotFound, " Action " << actionName(actionId) << " has not been declared before.");
230 if (_actionTransitionTable_[actionId]->exists(v))
231 return (*_actionTransitionTable_[actionId])[v];
232 else
233 return (*_actionTransitionTable_[0]).exists(v) ? (*_actionTransitionTable_[0])[v] : nullptr;
234 }
235
236 /* **************************************************************************************************
237 * **/
238 /* ** **/
239 /* ** Cost methods. **/
240 /* ** **/
241 /* **************************************************************************************************
242 * **/
243
244 // ===========================================================================
245 // Adds a cost table to specified action
246 // @throw NotFound if action does not exists
247 // @throw DuplicateElement if action already has a cost
248 // ===========================================================================
249 template < typename GUM_ELEMENT >
252 if (!_actionCostTable_.exists(actionId))
253 GUM_ERROR(NotFound, " Action " << actionName(actionId) << " has not been declared before.");
254
255 if (_actionCostTable_[actionId] != nullptr)
256 GUM_ERROR(DuplicateElement, " Action " << actionName(actionId) << " already has a cost table")
257
259 }
260
261 // ===========================================================================
262 // Returns transition associated to given in parameter variable and given
263 // action
264 // ===========================================================================
265 template < typename GUM_ELEMENT >
266 const MultiDimImplementation< GUM_ELEMENT >* FMDP< GUM_ELEMENT >::cost(Idx actionId) const {
268 GUM_ERROR(NotFound, " Action " << actionName(actionId) << " has not been declared before.");
269
271 return _actionCostTable_[0];
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_ELEMENT >
287 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_ELEMENT >
306 if (!_actionRewardTable_.exists(actionId))
307 GUM_ERROR(NotFound, " Action " << actionName(actionId) << " has not been declared before.");
308
310 return _actionRewardTable_[0];
311 }
312
313 /* **************************************************************************************************
314 * **/
315 /* ** **/
316 /* ** Miscelleanous methods. **/
317 /* ** **/
318 /* **************************************************************************************************
319 * **/
320
321 // ===========================================================================
322 // Returns name of action given in parameter
323 // ===========================================================================
324 template < typename GUM_ELEMENT >
325 const std::string& FMDP< GUM_ELEMENT >::actionName(Idx actionId) const {
326 if (!_actionMap_.existsFirst(actionId))
327 GUM_ERROR(NotFound, "No action with " << actionId << " as identifiant.")
328
329 return *(_actionMap_.second(actionId));
330 }
331
332 // ===========================================================================
333 // Returns action id
334 // ===========================================================================
335 template < typename GUM_ELEMENT >
336 Idx FMDP< GUM_ELEMENT >::actionId(std::string_view action) const {
338 actIter != _actionMap_.end();
339 ++actIter)
340 if (*(actIter.second()) == action) { return actIter.first(); }
341
342 GUM_ERROR(NotFound, " Action " << action << " has not been declared before.")
343 }
344
345 template < typename GUM_ELEMENT >
346 std::string FMDP< GUM_ELEMENT >::toString() const {
347 std::string fmdpCore;
348
349 for (auto actionIter = beginActions(); actionIter != endActions(); ++actionIter) {
350 for (auto varIter = beginVariables(); varIter != endVariables(); ++varIter)
351 if (this->transition(*actionIter, *varIter))
352 fmdpCore += static_cast< const MultiDimFunctionGraph< GUM_ELEMENT >* >(
353 this->transition(*actionIter, *varIter))
354 ->toDot()
355 + '\n';
356 if (this->reward(*actionIter))
357 fmdpCore
358 += static_cast< const MultiDimFunctionGraph< GUM_ELEMENT >* >(this->reward(*actionIter))
359 ->toDot()
360 + '\n';
361 }
362
363 for (auto varIter = beginVariables(); varIter != endVariables(); ++varIter)
364 if (this->transition(0, *varIter))
365 fmdpCore += static_cast< const MultiDimFunctionGraph< GUM_ELEMENT >* >(
366 this->transition(0, *varIter))
367 ->toDot()
368 + '\n';
369 if (this->reward())
370 fmdpCore
371 += static_cast< const MultiDimFunctionGraph< GUM_ELEMENT >* >(this->reward())->toDot()
372 + '\n';
373 return fmdpCore;
374 }
375
376 template < typename GUM_ELEMENT >
378 Size s = 0;
379 for (auto actionIter = beginActions(); actionIter != endActions(); ++actionIter) {
380 for (auto varIter = beginVariables(); varIter != endVariables(); ++varIter)
381 if (this->transition(*actionIter, *varIter))
382 s += this->transition(*actionIter, *varIter)->realSize();
383 if (this->reward(*actionIter)) s += this->reward(*actionIter)->realSize();
384 }
385
386 for (auto varIter = beginVariables(); varIter != endVariables(); ++varIter)
387 if (this->transition(0, *varIter)) s += this->transition(0, *varIter)->realSize();
388 if (this->reward()) s += this->reward()->realSize();
389 return s;
390 }
391
392 template < typename GUM_ELEMENT >
396
397 template < typename GUM_ELEMENT >
401
402 template < typename GUM_ELEMENT >
404 return _main2primed_.second(mainVar);
405 }
406
407 template < typename GUM_ELEMENT >
412
413 template < typename GUM_ELEMENT >
417
418 template < typename GUM_ELEMENT >
422
423 template < typename GUM_ELEMENT >
428
429 template < typename GUM_ELEMENT >
433
434 template < typename GUM_ELEMENT >
438
439 template < typename GUM_ELEMENT >
443
444 template < typename GUM_ELEMENT >
448
449 template < typename GUM_ELEMENT >
450 GUM_ELEMENT FMDP< GUM_ELEMENT >::discount() const {
451 return _discount_;
452 }
453
454} // namespace gum
Safe iterators for bijectionIterator.
Definition bijection.h:1240
Unsafe iterators for bijection.
Definition bijection.h:1440
Set of pairs of elements with fast search for both elements.
Definition bijection.h:1640
Base class for discrete random variable.
DiscreteVariable * clone() const override=0
Copy Factory.
Exception : a similar element already exists.
Bijection< Idx, const std::string * > _actionMap_
Bijection mapping an action name to its id.
Definition fmdp.h:286
HashTable< Idx, const MultiDimImplementation< GUM_ELEMENT > * > _actionRewardTable_
Table which give for each action reward table.
Definition fmdp.h:296
void addRewardForAction(Idx actionId, const MultiDimImplementation< GUM_ELEMENT > *reward)
Adds a default variable reward.
Definition fmdp_tpl.h:288
void addVariable(const DiscreteVariable *var)
Adds a variable to FMDP description.
Definition fmdp_tpl.h:137
Size size() const
Returns the map binding main variables and prime variables.
Definition fmdp_tpl.h:377
void addCost(const MultiDimImplementation< GUM_ELEMENT > *cost)
Adds a default variable cost.
Definition fmdp_tpl.h:430
HashTable< Idx, const MultiDimImplementation< GUM_ELEMENT > * > _actionCostTable_
Table which give for each action cost table.
Definition fmdp.h:293
void setDiscount(GUM_ELEMENT discount)
Sets the discount factor.
Definition fmdp_tpl.h:445
void addTransitionForAction(Idx actionId, const DiscreteVariable *var, const MultiDimImplementation< GUM_ELEMENT > *transition)
Adds a variable transition table to specified action.
Definition fmdp_tpl.h:202
SequenceIteratorSafe< Idx > beginActions() const
Returns an iterator reference to he beginning of the list of actions.
Definition fmdp_tpl.h:414
FMDP(bool onDestructionDeleteVar=false)
Default constructor.
Definition fmdp_tpl.h:75
void addAction(Idx actionId, std::string_view action)
Adds an action to FMDP description.
Definition fmdp_tpl.h:164
void addCostForAction(Idx actionId, const MultiDimImplementation< GUM_ELEMENT > *cost)
Adds a cost table to specified action.
Definition fmdp_tpl.h:250
void setDeleteVariablesOnDestruction(bool b)
Transfers ownership of variables to this FMDP (they will be deleted on destruction).
Definition fmdp_tpl.h:440
Sequence< const DiscreteVariable * > _varSeq_
Sequence de variables and its iterator.
Definition fmdp.h:278
const DiscreteVariable * main2prime(const DiscreteVariable *mainVar) const
Returns the primed variable associate to the given main variable.
Definition fmdp_tpl.h:403
SequenceIteratorSafe< const DiscreteVariable * > beginVariables() const
Returns an iterator reference to he beginning of the list of variables.
Definition fmdp_tpl.h:393
Idx actionId(std::string_view) const
Returns action id.
Definition fmdp_tpl.h:336
SequenceIteratorSafe< Idx > endActions() const
Returns an iterator reference to the end of the list of actions.
Definition fmdp_tpl.h:419
void addReward(const MultiDimImplementation< GUM_ELEMENT > *reward)
Adds a default variable reward.
Definition fmdp_tpl.h:435
bool _onDestructionDeleteVars_
Boolean indicates whether or not main variables should be deleted on destruction of this instance Usu...
Definition fmdp.h:301
const Bijection< const DiscreteVariable *, const DiscreteVariable * > & mapMainPrime() const
Returns the map binding main variables and prime variables.
Definition fmdp_tpl.h:409
HashTable< const DiscreteVariable *, const MultiDimImplementation< GUM_ELEMENT_O > * > VarTransitionTable
Definition fmdp.h:77
GUM_ELEMENT discount() const
Returns the discount factor.
Definition fmdp_tpl.h:450
Bijection< const DiscreteVariable *, const DiscreteVariable * > _main2primed_
Definition fmdp.h:283
void addTransition(const DiscreteVariable *var, const MultiDimImplementation< GUM_ELEMENT > *transition)
Adds a default variable transition.
Definition fmdp_tpl.h:424
~FMDP()
Default destructor.
Definition fmdp_tpl.h:90
Sequence< Idx > _actionSeq_
Definition fmdp.h:280
SequenceIteratorSafe< const DiscreteVariable * > endVariables() const
Returns an iterator reference to the end of the list of variables.
Definition fmdp_tpl.h:398
HashTable< Idx, VarTransitionTable< GUM_ELEMENT > * > _actionTransitionTable_
Table which give for each action a table containing variables transition cpt.
Definition fmdp.h:290
const MultiDimImplementation< double > * cost(Idx actionId=0) const
Definition fmdp_tpl.h:266
const MultiDimImplementation< double > * transition(Idx actionId, const DiscreteVariable *v) const
Definition fmdp_tpl.h:226
std::string toString() const
Displays the FMDP in a Dot format.
Definition fmdp_tpl.h:346
const std::string & actionName(Idx actionId) const
Definition fmdp_tpl.h:325
const MultiDimImplementation< GUM_ELEMENT > * reward(Idx actionId=0) const
Returns the reward table of mdp.
Definition fmdp_tpl.h:305
GUM_ELEMENT _discount_
Definition fmdp.h:303
Class implementingting a function graph.
<agrum/base/multidim/multiDimImplementation.h>
Exception : the element we looked for cannot be found.
Safe iterators for Sequence.
Definition sequence.h:1148
const std::string & name() const
returns the name of the variable
void setName(std::string_view theValue)
sets the name of the variable
#define GUM_ERROR(type, msg)
Definition exceptions.h:76
Class for implementation of factored markov decision process.
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