34 #include <agrum/FMDP/fmdp.h> 36 #define RECAST(x) reinterpret_cast< const MultiDimFunctionGraph< GUM_SCALAR >* >(x) 52 template <
typename GUM_SCALAR >
53 INLINE FMDP< GUM_SCALAR >::FMDP(
bool onDestructionDeleteVar) {
54 GUM_CONSTRUCTOR(FMDP);
55 onDestructionDeleteVars__ = onDestructionDeleteVar;
58 actionMap__.insert(0,
new std::string(
"DEFAULT"));
59 actionTransitionTable__.insert(0,
new VarTransitionTable< GUM_SCALAR >());
60 actionCostTable__.insert(0,
nullptr);
61 actionRewardTable__.insert(0,
nullptr);
67 template <
typename GUM_SCALAR >
68 FMDP< GUM_SCALAR >::~FMDP() {
70 for (
auto iterA = actionTransitionTable__.beginSafe();
71 iterA != actionTransitionTable__.endSafe();
74 for (
auto iterH = (iterA.val())->beginSafe();
75 iterH != (iterA.val())->endSafe();
77 if (iterH.val())
delete iterH.val();
83 for (
auto iterA = actionCostTable__.beginSafe();
84 iterA != actionCostTable__.endSafe();
86 if (iterA.val())
delete iterA.val();
89 for (
auto iterA = actionRewardTable__.beginSafe();
90 iterA != actionRewardTable__.endSafe();
92 if (iterA.val())
delete iterA.val();
95 for (
auto iterId = actionMap__.beginSafe(); iterId != actionMap__.endSafe();
97 delete iterId.second();
100 for (
auto varIter = main2primed__.beginSafe();
101 varIter != main2primed__.endSafe();
103 delete varIter.second();
104 if (onDestructionDeleteVars__)
delete varIter.first();
107 GUM_DESTRUCTOR(FMDP);
123 template <
typename GUM_SCALAR >
124 INLINE
void FMDP< GUM_SCALAR >::addVariable(
const DiscreteVariable* var) {
125 if (varSeq__.exists(var))
126 GUM_ERROR(DuplicateElement,
127 " Variable " << var->name()
128 <<
" has already been inserted in FMDP.");
131 varSeq__.insert(var);
134 DiscreteVariable* primeVar = var->clone();
135 primeVar->setName(var->name() +
"'");
136 main2primed__.insert(var, primeVar);
152 template <
typename GUM_SCALAR >
153 INLINE
void FMDP< GUM_SCALAR >::addAction(Idx actionId,
154 const std::string& action) {
155 if (actionId == 0) GUM_ERROR(DuplicateElement,
" Action Id 0 is reserved.");
157 for (BijectionIteratorSafe< Idx,
const std::string* > actIter
158 = actionMap__.beginSafe();
159 actIter != actionMap__.endSafe();
161 if (*(actIter.second()) == action)
162 GUM_ERROR(DuplicateElement,
165 <<
" has already been inserted in FMDP with this name.");
167 if (actionMap__.existsFirst(actionId))
168 GUM_ERROR(DuplicateElement,
169 " An action with same id (" << actionId
170 <<
") has already been inserted.");
172 actionMap__.insert(actionId,
new std::string(action));
174 actionTransitionTable__.insert(actionId,
175 new VarTransitionTable< GUM_SCALAR >());
176 actionCostTable__.insert(actionId,
nullptr);
177 actionRewardTable__.insert(actionId,
nullptr);
179 actionSeq__.insert(actionId);
197 template <
typename GUM_SCALAR >
198 INLINE
void FMDP< GUM_SCALAR >::addTransitionForAction(
200 const DiscreteVariable* var,
201 const MultiDimImplementation< GUM_SCALAR >* transition) {
202 if (!varSeq__.exists(var))
204 " Variable " << var->name() <<
" has not been declared before.");
206 if (!actionTransitionTable__.exists(actionId))
208 " Action " << actionName(actionId)
209 <<
" has not been declared before.");
211 if (actionTransitionTable__[actionId]->exists(var))
212 GUM_ERROR(DuplicateElement,
213 " Variable " << var->name()
214 <<
" already has a transition table in " << actionId
217 actionTransitionTable__[actionId]->insert(var, transition);
225 template <
typename GUM_SCALAR >
226 INLINE
const MultiDimImplementation< GUM_SCALAR >*
227 FMDP< GUM_SCALAR >::transition(Idx actionId,
228 const DiscreteVariable* v)
const {
229 if (!actionTransitionTable__.exists(actionId))
231 " Action " << actionName(actionId)
232 <<
" has not been declared before.");
234 if (actionTransitionTable__[actionId]->exists(v))
235 return (*actionTransitionTable__[actionId])[v];
237 return (*actionTransitionTable__[0]).exists(v)
238 ? (*actionTransitionTable__[0])[v]
256 template <
typename GUM_SCALAR >
257 INLINE
void FMDP< GUM_SCALAR >::addCostForAction(
259 const MultiDimImplementation< GUM_SCALAR >* cost) {
260 if (!actionCostTable__.exists(actionId))
262 " Action " << actionName(actionId)
263 <<
" has not been declared before.");
265 if (actionCostTable__[actionId] !=
nullptr)
266 GUM_ERROR(DuplicateElement,
267 " Action " << actionName(actionId) <<
" already has a cost table");
269 actionCostTable__[actionId] = cost;
277 template <
typename GUM_SCALAR >
278 INLINE
const MultiDimImplementation< GUM_SCALAR >*
279 FMDP< GUM_SCALAR >::cost(Idx actionId)
const {
280 if (!actionCostTable__.exists(actionId))
282 " Action " << actionName(actionId)
283 <<
" has not been declared before.");
285 if (actionCostTable__[actionId])
return actionCostTable__[actionId];
286 return actionCostTable__[0];
302 template <
typename GUM_SCALAR >
303 INLINE
void FMDP< GUM_SCALAR >::addRewardForAction(
305 const MultiDimImplementation< GUM_SCALAR >* reward) {
306 if (!actionRewardTable__.exists(actionId))
308 " Action " << actionName(actionId)
309 <<
" has not been declared before.");
311 if (actionRewardTable__[actionId] !=
nullptr)
312 GUM_ERROR(DuplicateElement,
313 " Action " << actionName(actionId)
314 <<
" already has a reward table");
316 actionRewardTable__[actionId] = reward;
324 template <
typename GUM_SCALAR >
325 INLINE
const MultiDimImplementation< GUM_SCALAR >*
326 FMDP< GUM_SCALAR >::reward(Idx actionId)
const {
327 if (!actionRewardTable__.exists(actionId))
329 " Action " << actionName(actionId)
330 <<
" has not been declared before.");
332 if (actionRewardTable__[actionId])
return actionRewardTable__[actionId];
333 return actionRewardTable__[0];
348 template <
typename GUM_SCALAR >
349 INLINE
const std::string& FMDP< GUM_SCALAR >::actionName(Idx actionId)
const {
350 if (!actionMap__.existsFirst(actionId))
351 GUM_ERROR(NotFound,
"No action with " << actionId <<
" as identifiant.");
353 return *(actionMap__.second(actionId));
359 template <
typename GUM_SCALAR >
360 INLINE Idx FMDP< GUM_SCALAR >::actionId(
const std::string& action)
const {
361 for (BijectionIterator< Idx,
const std::string* > actIter
362 = actionMap__.begin();
363 actIter != actionMap__.end();
365 if (*(actIter.second()) == action) {
return actIter.first(); }
367 GUM_ERROR(NotFound,
" Action " << action <<
" has not been declared before.");
371 template <
typename GUM_SCALAR >
372 INLINE std::string FMDP< GUM_SCALAR >::toString()
const {
373 std::stringstream fmdpCore;
375 for (
auto actionIter = beginActions(); actionIter != endActions();
377 for (
auto varIter = beginVariables(); varIter != endVariables(); ++varIter)
378 if (
this->transition(*actionIter, *varIter))
379 fmdpCore <<
RECAST(
this->transition(*actionIter, *varIter))->toDot()
381 if (
this->reward(*actionIter))
382 fmdpCore <<
RECAST(
this->reward(*actionIter))->toDot() << std::endl;
385 for (
auto varIter = beginVariables(); varIter != endVariables(); ++varIter)
386 if (
this->transition(0, *varIter))
387 fmdpCore <<
RECAST(
this->transition(0, *varIter))->toDot() << std::endl;
388 if (
this->reward()) fmdpCore <<
RECAST(
this->reward())->toDot() << std::endl;
389 return fmdpCore.str();
393 template <
typename GUM_SCALAR >
394 INLINE Size FMDP< GUM_SCALAR >::size()
const {
396 for (
auto actionIter = beginActions(); actionIter != endActions();
398 for (
auto varIter = beginVariables(); varIter != endVariables(); ++varIter)
399 if (
this->transition(*actionIter, *varIter))
400 s +=
this->transition(*actionIter, *varIter)->realSize();
401 if (
this->reward(*actionIter)) s +=
this->reward(*actionIter)->realSize();
404 for (
auto varIter = beginVariables(); varIter != endVariables(); ++varIter)
405 if (
this->transition(0, *varIter))
406 s +=
this->transition(0, *varIter)->realSize();
407 if (
this->reward()) s +=
this->reward()->realSize();