Skip to content

Commit aab7e5e

Browse files
authored
Merge pull request #218 from ds4dm/release_0.7.2
Release 0.7.2
2 parents bfddb5f + aed579b commit aab7e5e

File tree

3 files changed

+40
-22
lines changed

3 files changed

+40
-22
lines changed

libecole/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@ find_or_download_package(
125125
-D FMT_DOC=OFF
126126
-D FMT_INSTALL=ON
127127
-D CMAKE_BUILD_TYPE=Release
128+
-D BUILD_SHARED_LIBS=OFF
128129
-D CMAKE_POSITION_INDEPENDENT_CODE=${CMAKE_POSITION_INDEPENDENT_CODE}
129130
)
130131
find_or_download_package(

libecole/include/ecole/environment/environment.hpp

Lines changed: 29 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
#include "ecole/scip/type.hpp"
1616
#include "ecole/traits.hpp"
1717

18-
#include <iostream>
18+
#include <optional>
1919

2020
template <typename T> struct is_optional : std::false_type {};
2121
template <typename T> struct is_optional<std::optional<T>> : std::true_type {};
@@ -67,8 +67,8 @@ class Environment {
6767
std::map<std::string, scip::Param> scip_params = {},
6868
Args&&... args) :
6969
the_dynamics(std::forward<Args>(args)...),
70-
the_observation_function(data::parse(std::move(observation_function))),
7170
the_reward_function(data::parse(std::move(reward_function))),
71+
the_observation_function(data::parse(std::move(observation_function))),
7272
the_information_function(data::parse(std::move(information_function))),
7373
the_scip_params(std::move(scip_params)),
7474
the_random_engine(spawn_random_engine()) {}
@@ -112,22 +112,23 @@ class Environment {
112112
dynamics().set_dynamics_random_state(model(), random_engine());
113113

114114
// Reset data extraction function and bring model to initial state.
115-
observation_function().before_reset(model());
116115
reward_function().before_reset(model());
116+
observation_function().before_reset(model());
117117
information_function().before_reset(model());
118-
auto const [done, action_set] = dynamics().reset_dynamics(model(), std::forward<Args>(args)...);
118+
119+
// Place the environment in its initial state
120+
auto [done, action_set] = dynamics().reset_dynamics(model(), std::forward<Args>(args)...);
119121
can_transition = !done;
120122

121-
auto observation = OptionalObservation{};
122-
if (!done) {
123-
observation = observation_function().extract(model(), done);
124-
}
123+
// Extract additional information to be returned by reset
124+
auto [reward, observation, information] = extract_reward_observation_information(done);
125+
125126
return {
126127
std::move(observation),
127128
std::move(action_set),
128-
reward_function().extract(model(), done),
129+
std::move(reward),
129130
done,
130-
information_function().extract(model(), done),
131+
std::move(information),
131132
};
132133
} catch (std::exception const&) {
133134
can_transition = false;
@@ -170,19 +171,19 @@ class Environment {
170171
throw Exception("Environment need to be reset.");
171172
}
172173
try {
173-
auto const [done, action_set] = dynamics().step_dynamics(model(), action, std::forward<Args>(args)...);
174+
// Transition the environment to the next state
175+
auto [done, action_set] = dynamics().step_dynamics(model(), action, std::forward<Args>(args)...);
174176
can_transition = !done;
175177

176-
auto observation = OptionalObservation{};
177-
if (!done) {
178-
observation = observation_function().extract(model(), done);
179-
}
178+
// Extract additional information to be returned by step
179+
auto [reward, observation, information] = extract_reward_observation_information(done);
180+
180181
return {
181182
std::move(observation),
182183
std::move(action_set),
183-
reward_function().extract(model(), done),
184+
std::move(reward),
184185
done,
185-
information_function().extract(model(), done),
186+
std::move(information),
186187
};
187188
} catch (std::exception const&) {
188189
can_transition = false;
@@ -201,12 +202,22 @@ class Environment {
201202
private:
202203
Dynamics the_dynamics;
203204
scip::Model the_model;
204-
ObservationFunction the_observation_function;
205205
RewardFunction the_reward_function;
206+
ObservationFunction the_observation_function;
206207
InformationFunction the_information_function;
207208
std::map<std::string, scip::Param> the_scip_params;
208209
RandomEngine the_random_engine;
209210
bool can_transition = false;
211+
212+
// extract reward, observation and information (in that order)
213+
auto extract_reward_observation_information(bool done) -> std::tuple<Reward, OptionalObservation, InformationMap> {
214+
auto reward = reward_function().extract(model(), done);
215+
// Don't extract observations in final states
216+
auto observation = done ? OptionalObservation{} : observation_function().extract(model(), done);
217+
auto information = information_function().extract(model(), done);
218+
219+
return {std::move(reward), std::move(observation), std::move(information)};
220+
}
210221
};
211222

212223
} // namespace ecole::environment

python/src/ecole/environment.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -109,19 +109,23 @@ def reset(self, instance, *dynamics_args, **dynamics_kwargs):
109109

110110
self.dynamics.set_dynamics_random_state(self.model, self.random_engine)
111111

112+
# Reset data extraction functions
112113
self.reward_function.before_reset(self.model)
113114
self.observation_function.before_reset(self.model)
114115
self.information_function.before_reset(self.model)
116+
117+
# Place the environment in its initial state
115118
done, action_set = self.dynamics.reset_dynamics(
116119
self.model, *dynamics_args, **dynamics_kwargs
117120
)
121+
self.can_transition = not done
118122

123+
# Extract additional information to be returned by reset
124+
reward_offset = self.reward_function.extract(self.model, done)
119125
if not done:
120126
observation = self.observation_function.extract(self.model, done)
121127
else:
122128
observation = None
123-
reward_offset = self.reward_function.extract(self.model, done)
124-
observation = self.observation_function.extract(self.model, done)
125129
information = self.information_function.extract(self.model, done)
126130

127131
return observation, action_set, reward_offset, done, information
@@ -172,16 +176,18 @@ def step(self, action, *dynamics_args, **dynamics_kwargs):
172176
raise ecole.core.environment.Exception("Environment need to be reset.")
173177

174178
try:
179+
# Transition the environment to the next state
175180
done, action_set = self.dynamics.step_dynamics(
176181
self.model, action, *dynamics_args, **dynamics_kwargs
177182
)
183+
self.can_transition = not done
178184

185+
# Extract additional information to be returned by step
186+
reward = self.reward_function.extract(self.model, done)
179187
if not done:
180188
observation = self.observation_function.extract(self.model, done)
181189
else:
182190
observation = None
183-
reward = self.reward_function.extract(self.model, done)
184-
observation = self.observation_function.extract(self.model, done)
185191
information = self.information_function.extract(self.model, done)
186192

187193
return observation, action_set, reward, done, information

0 commit comments

Comments
 (0)