aGrUM 3.1.1
a C++ library for (probabilistic) graphical models
sdyna.cpp
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
49
50
51// =========================================================================
52#include <cstdlib>
53// =========================================================================
55
56#ifdef GUM_NO_INLINE
58#endif // GUM_NO_INLINE
59
60// =========================================================================
61
62namespace gum {
63
64 // ==========================================================================
65 // Constructor & destructor.
66 // ==========================================================================
67
68 // ###################################################################
69 /*
70 * Constructor
71 *
72 * @param observationPhaseLenght : the number of observation done before a
73 * replanning is launch. If equals 0, a planning is done after each structural
74 * change.
75 * @param nbValueIterationStep : the number of value iteration done during
76 * one planning
77 * @return an instance of SDyna architecture
78 */
79 // ###################################################################
80
83 IDecisionStrategy* decider,
84 Idx observationPhaseLenght,
85 Idx nbValueIterationStep,
86 bool actionReward,
87 bool verbose) :
88 _learner_(learner), _planer_(planer), _decider_(decider),
89 _observationPhaseLenght_(observationPhaseLenght),
90 _nbValueIterationStep_(nbValueIterationStep), _actionReward_(actionReward),
91 verbose_(verbose) {
92 GUM_CONSTRUCTOR(SDYNA);
93
94 fmdp_ = new FMDP< double >();
95
97 }
98
99 // ###################################################################
100 // Destructor
101 // ###################################################################
103 delete _decider_;
104
105 delete _learner_;
106
107 delete _planer_;
108
109 for (auto obsIter = _bin_.beginSafe(); obsIter != _bin_.endSafe(); ++obsIter)
110 delete *obsIter;
111
112 delete fmdp_;
113
114 GUM_DESTRUCTOR(SDYNA);
115 }
116
117 // ==========================================================================
118 // Initialization
119 // ==========================================================================
120
122 _learner_->initialize(fmdp_);
123 _planer_->initialize(fmdp_);
124 _decider_->initialize(fmdp_);
125 }
126
127 // ###################################################################
128 /*
129 * Initializes the Sdyna instance.
130 * @param initialState : the state of the studied system from which we will
131 * begin the explore, learn and exploit process
132 */
133 // ###################################################################
134 void SDYNA::initialize(const Instantiation& initialState) {
135 initialize();
136 setCurrentState(initialState);
137 }
138
139 // ==========================================================================
141 // ==========================================================================
142
143 // ###################################################################
144 /*
145 * Performs a feedback on the last transition.
146 * In extenso, learn from the transition.
147 * @param originalState : the state we were in before the transition
148 * @param reachedState : the state we reached after
149 * @param performedAction : the action we performed
150 * @param obtainedReward : the reward we obtained
151 */
152 // ###################################################################
153 void SDYNA::feedback(const Instantiation& curState,
154 const Instantiation& prevState,
155 Idx lastAction,
156 double reward) {
157 _lastAction_ = lastAction;
158 lastState_ = prevState;
159 feedback(curState, reward);
160 }
161
162 // ###################################################################
163 /*
164 * Performs a feedback on the last transition.
165 * In extenso, learn from the transition.
166 * @param reachedState : the state reached after the transition
167 * @param obtainedReward : the reward obtained during the transition
168 * @warning Uses the _originalState_ and _performedAction_ stored in cache
169 * If you want to specify the original state and the performed action, see
170 * below
171 */
172 // ###################################################################
173 void SDYNA::feedback(const Instantiation& newState, double reward) {
174 Observation* obs = new Observation();
175
176 for (auto varIter = lastState_.variablesSequence().beginSafe();
177 varIter != lastState_.variablesSequence().endSafe();
178 ++varIter)
179 obs->setModality(*varIter, lastState_.val(**varIter));
180
181 for (auto varIter = newState.variablesSequence().beginSafe();
182 varIter != newState.variablesSequence().endSafe();
183 ++varIter) {
184 obs->setModality(fmdp_->main2prime(*varIter), newState.val(**varIter));
185
186 if (this->_actionReward_) obs->setRModality(*varIter, lastState_.val(**varIter));
187 else obs->setRModality(*varIter, newState.val(**varIter));
188 }
189
190 obs->setReward(reward);
191
192 _learner_->addObservation(_lastAction_, obs);
193 _bin_.insert(obs);
194
195 setCurrentState(newState);
196 _decider_->checkState(lastState_, _lastAction_);
197
199
201 }
202
203 // ###################################################################
204 /*
205 * Starts a new planning
206 * @param Idx : the maximal number of value iteration performed in this
207 * planning
208 */
209 // ###################################################################
210 void SDYNA::makePlanning(Idx nbValueIterationStep) {
211 if (verbose_) std::cout << "Updating decision trees ..." << std::endl;
212 _learner_->updateFMDP();
213 // std::cout << << "Done" << std::endl;
214
215 if (verbose_) std::cout << "Planning ..." << std::endl;
216 _planer_->makePlanning(nbValueIterationStep);
217 // std::cout << << "Done" << std::endl;
218
219 _decider_->setOptimalStrategy(_planer_->optimalPolicy());
220 }
221
222 // ##################################################################
223 /*
224 * @return the id of the action the SDyna instance wish to be performed
225 * @param the state in which we currently are
226 */
227 // ###################################################################
229 lastState_ = curState;
230 return takeAction();
231 }
232
233 // ###################################################################
234 /*
235 * @return the id of the action the SDyna instance wish to be performed
236 */
237 // ###################################################################
239 ActionSet actionSet = _decider_->stateOptimalPolicy(lastState_);
240 if (actionSet.size() == 1) {
241 _lastAction_ = actionSet[0];
242 } else {
243 Idx randy = randomValue(actionSet.size());
244 _lastAction_ = actionSet[randy == actionSet.size() ? 0 : randy];
245 }
246 return _lastAction_;
247 }
248
249 // ###################################################################
250 //
251 // ###################################################################
252 std::string SDYNA::toString() {
253 return fmdp_->toString() + '\n' + _planer_->optimalPolicy2String() + '\n';
254 }
255
256} // End of namespace gum
A class to store the optimal actions.
Definition actionSet.h:98
Size size() const
Gives the size.
<agrum/FMDP/SDyna/IDecisionStrategy.h>
<agrum/FMDP/SDyna/ILearningStrategy.h>
Class for assigning/browsing values to tuples of discrete variables.
const Sequence< const DiscreteVariable * > & variablesSequence() const final
Returns the sequence of DiscreteVariable of this instantiation.
Idx val(Idx i) const
Returns the current value of the variable at position i.
void setReward(double reward)
Returns the modality assumed by the given variable in this observation.
void setRModality(const DiscreteVariable *var, Idx modality)
Returns the modality assumed by the given variable in this observation.
void setModality(const DiscreteVariable *var, Idx modality)
Sets the modality assumed by the given variable in this observation.
void initialize()
Initializes the Sdyna instance.
Definition sdyna.cpp:121
ILearningStrategy * _learner_
The learner used to learn the FMDP.
Definition sdyna.h:368
Idx _lastAction_
The last performed action.
Definition sdyna.h:387
Idx _nbValueIterationStep_
The number of Value Iteration step we perform.
Definition sdyna.h:384
Instantiation lastState_
The state in which the system is before we perform a new action.
Definition sdyna.h:364
void setCurrentState(const Instantiation &currentState)
Sets last state visited to the given state.
Definition sdyna_inl.h:150
~SDYNA()
Destructor.
Definition sdyna.cpp:102
Idx takeAction()
Definition sdyna.cpp:238
IPlanningStrategy< double > * _planer_
The planer used to plan an optimal strategy.
Definition sdyna.h:371
FMDP< double > * fmdp_
The learnt Markovian Decision Process.
Definition sdyna.h:361
Set< Observation * > _bin_
Since SDYNA made these observation, it has to delete them on quitting.
Definition sdyna.h:390
Idx _nbObservation_
The total number of observation made so far.
Definition sdyna.h:381
bool _actionReward_
Definition sdyna.h:392
IDecisionStrategy * _decider_
The decider.
Definition sdyna.h:374
bool verbose_
Definition sdyna.h:394
std::string toString()
Returns.
Definition sdyna.cpp:252
void feedback(const Instantiation &originalState, const Instantiation &reachedState, Idx performedAction, double obtainedReward)
Performs a feedback on the last transition.
Definition sdyna.cpp:153
void makePlanning(Idx nbStep)
Starts a new planning.
Definition sdyna.cpp:210
Idx _observationPhaseLenght_
The number of observation we make before using again the planer.
Definition sdyna.h:378
SDYNA(ILearningStrategy *learner, IPlanningStrategy< double > *planer, IDecisionStrategy *decider, Idx observationPhaseLenght, Idx nbValueIterationStep, bool actionReward, bool verbose=true)
Constructor.
Definition sdyna.cpp:81
Size Idx
Type for indexes.
Definition types.h:79
Idx randomValue(const Size max=2)
Returns a random Idx between 0 and max-1 included.
gum is the global namespace for all aGrUM entities
Definition agrum.h:46
Headers of the SDyna abstract class.