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(); iterH != (iterA.val())->endSafe(); ++iterH)
75 if (iterH.val())
delete iterH.val();
81 for (
auto iterA = _actionCostTable_.beginSafe(); iterA != _actionCostTable_.endSafe(); ++iterA)
82 if (iterA.val())
delete iterA.val();
85 for (
auto iterA = _actionRewardTable_.beginSafe(); iterA != _actionRewardTable_.endSafe();
87 if (iterA.val())
delete iterA.val();
90 for (
auto iterId = _actionMap_.beginSafe(); iterId != _actionMap_.endSafe(); ++iterId)
91 delete iterId.second();
94 for (
auto varIter = _main2primed_.beginSafe(); varIter != _main2primed_.endSafe(); ++varIter) {
95 delete varIter.second();
96 if (_onDestructionDeleteVars_)
delete varIter.first();
115 template <
typename GUM_SCALAR >
116 INLINE
void FMDP< GUM_SCALAR >::addVariable(
const DiscreteVariable* var) {
117 if (_varSeq_.exists(var))
118 GUM_ERROR(DuplicateElement,
119 " Variable " << var->name() <<
" has already been inserted in FMDP.");
122 _varSeq_.insert(var);
125 DiscreteVariable* primeVar = var->clone();
126 primeVar->setName(var->name() +
"'");
127 _main2primed_.insert(var, primeVar);
143 template <
typename GUM_SCALAR >
144 INLINE
void FMDP< GUM_SCALAR >::addAction(Idx actionId,
const std::string& action) {
145 if (actionId == 0) GUM_ERROR(DuplicateElement,
" Action Id 0 is reserved.")
147 for (BijectionIteratorSafe< Idx,
const std::string* > actIter = _actionMap_.beginSafe();
148 actIter != _actionMap_.endSafe();
150 if (*(actIter.second()) == action)
151 GUM_ERROR(DuplicateElement,
152 " Action " << action <<
" has already been inserted in FMDP with this name.");
154 if (_actionMap_.existsFirst(actionId))
155 GUM_ERROR(DuplicateElement,
156 " An action with same id (" << actionId <<
") has already been inserted.");
158 _actionMap_.insert(actionId,
new std::string(action));
160 _actionTransitionTable_.insert(actionId,
new VarTransitionTable< GUM_SCALAR >());
161 _actionCostTable_.insert(actionId,
nullptr);
162 _actionRewardTable_.insert(actionId,
nullptr);
164 _actionSeq_.insert(actionId);
182 template <
typename GUM_SCALAR >
183 INLINE
void FMDP< GUM_SCALAR >::addTransitionForAction(
185 const DiscreteVariable* var,
186 const MultiDimImplementation< GUM_SCALAR >* transition) {
187 if (!_varSeq_.exists(var))
188 GUM_ERROR(NotFound,
" Variable " << var->name() <<
" has not been declared before.")
190 if (!_actionTransitionTable_.exists(actionId))
191 GUM_ERROR(NotFound,
" Action " << actionName(actionId) <<
" has not been declared before.");
193 if (_actionTransitionTable_[actionId]->exists(var))
194 GUM_ERROR(DuplicateElement,
195 " Variable " << var->name() <<
" already has a transition table in " << actionId
198 _actionTransitionTable_[actionId]->insert(var, transition);
206 template <
typename GUM_SCALAR >
207 INLINE
const MultiDimImplementation< GUM_SCALAR >*
208 FMDP< GUM_SCALAR >::transition(Idx actionId,
const DiscreteVariable* v)
const {
209 if (!_actionTransitionTable_.exists(actionId))
210 GUM_ERROR(NotFound,
" Action " << actionName(actionId) <<
" has not been declared before.");
212 if (_actionTransitionTable_[actionId]->exists(v))
213 return (*_actionTransitionTable_[actionId])[v];
215 return (*_actionTransitionTable_[0]).exists(v) ? (*_actionTransitionTable_[0])[v] :
nullptr;
232 template <
typename GUM_SCALAR >
234 FMDP< GUM_SCALAR >::addCostForAction(Idx actionId,
235 const MultiDimImplementation< GUM_SCALAR >* cost) {
236 if (!_actionCostTable_.exists(actionId))
237 GUM_ERROR(NotFound,
" Action " << actionName(actionId) <<
" has not been declared before.");
239 if (_actionCostTable_[actionId] !=
nullptr)
240 GUM_ERROR(DuplicateElement,
" Action " << actionName(actionId) <<
" already has a cost table")
242 _actionCostTable_[actionId] = cost;
250 template <
typename GUM_SCALAR >
251 INLINE
const MultiDimImplementation< GUM_SCALAR >* FMDP< GUM_SCALAR >::cost(Idx actionId)
const {
252 if (!_actionCostTable_.exists(actionId))
253 GUM_ERROR(NotFound,
" Action " << actionName(actionId) <<
" has not been declared before.");
255 if (_actionCostTable_[actionId])
return _actionCostTable_[actionId];
256 return _actionCostTable_[0];
272 template <
typename GUM_SCALAR >
274 FMDP< GUM_SCALAR >::addRewardForAction(Idx actionId,
275 const MultiDimImplementation< GUM_SCALAR >* reward) {
276 if (!_actionRewardTable_.exists(actionId))
277 GUM_ERROR(NotFound,
" Action " << actionName(actionId) <<
" has not been declared before.");
279 if (_actionRewardTable_[actionId] !=
nullptr)
280 GUM_ERROR(DuplicateElement,
281 " Action " << actionName(actionId) <<
" already has a reward table");
283 _actionRewardTable_[actionId] = reward;
291 template <
typename GUM_SCALAR >
292 INLINE
const MultiDimImplementation< GUM_SCALAR >*
293 FMDP< GUM_SCALAR >::reward(Idx actionId)
const {
294 if (!_actionRewardTable_.exists(actionId))
295 GUM_ERROR(NotFound,
" Action " << actionName(actionId) <<
" has not been declared before.");
297 if (_actionRewardTable_[actionId])
return _actionRewardTable_[actionId];
298 return _actionRewardTable_[0];
313 template <
typename GUM_SCALAR >
314 INLINE
const std::string& FMDP< GUM_SCALAR >::actionName(Idx actionId)
const {
315 if (!_actionMap_.existsFirst(actionId))
316 GUM_ERROR(NotFound,
"No action with " << actionId <<
" as identifiant.")
318 return *(_actionMap_.second(actionId));
324 template <
typename GUM_SCALAR >
325 INLINE Idx FMDP< GUM_SCALAR >::actionId(
const std::string& action)
const {
326 for (BijectionIterator< Idx,
const std::string* > actIter = _actionMap_.begin();
327 actIter != _actionMap_.end();
329 if (*(actIter.second()) == action) {
return actIter.first(); }
331 GUM_ERROR(NotFound,
" Action " << action <<
" has not been declared before.")
335 template <
typename GUM_SCALAR >
336 INLINE std::string FMDP< GUM_SCALAR >::toString()
const {
337 std::stringstream fmdpCore;
339 for (
auto actionIter = beginActions(); actionIter != endActions(); ++actionIter) {
340 for (
auto varIter = beginVariables(); varIter != endVariables(); ++varIter)
341 if (
this->transition(*actionIter, *varIter))
342 fmdpCore <<
RECAST(
this->transition(*actionIter, *varIter))->toDot() << std::endl;
343 if (
this->reward(*actionIter))
344 fmdpCore <<
RECAST(
this->reward(*actionIter))->toDot() << std::endl;
347 for (
auto varIter = beginVariables(); varIter != endVariables(); ++varIter)
348 if (
this->transition(0, *varIter))
349 fmdpCore <<
RECAST(
this->transition(0, *varIter))->toDot() << std::endl;
350 if (
this->reward()) fmdpCore <<
RECAST(
this->reward())->toDot() << std::endl;
351 return fmdpCore.str();
355 template <
typename GUM_SCALAR >
356 INLINE Size FMDP< GUM_SCALAR >::size()
const {
358 for (
auto actionIter = beginActions(); actionIter != endActions(); ++actionIter) {
359 for (
auto varIter = beginVariables(); varIter != endVariables(); ++varIter)
360 if (
this->transition(*actionIter, *varIter))
361 s +=
this->transition(*actionIter, *varIter)->realSize();
362 if (
this->reward(*actionIter)) s +=
this->reward(*actionIter)->realSize();
365 for (
auto varIter = beginVariables(); varIter != endVariables(); ++varIter)
366 if (
this->transition(0, *varIter)) s +=
this->transition(0, *varIter)->realSize();
367 if (
this->reward()) s +=
this->reward()->realSize();