Use Observation Functions¶
Using any environment, the observation 1 recieved by the user to take the
next action can be customized changing the ObservationFunction
used by the solver.
The environment is not extracting data directly but delegates that responsibility to an
ObservationFunction
object.
The object has complete access to the solver and extract the data it needs.
Using a different observation function is as easy as passing it as a parameter when
creating an environment.
For instance with the Branching
environment:
>>> env = ecole.environment.Branching(observation_function=ecole.observation.Nothing())
>>> env.observation_function
ecole.observation.Nothing()
>>> obs, _, _, _, _ = env.reset("path/to/problem")
>>> obs is None
True
Environments have an observation function set as default parameter for convenience.
>>> env = ecole.environment.Branching()
>>> env.observation_function
ecole.observation.NodeBipartite()
>>> obs, _, _, _, _ = env.reset("path/to/problem")
>>> obs
ecole.observation.NodeBipartiteObs(...)
See the reference for the list of available observation function, as well as the documention for explanation on how to create one.
No Observation Function¶
To not use any observation function, for instance for a learning with a bandit algorithm,
explicitly pass None
to the environment constructor.
>>> env = ecole.environment.Branching(observation_function=None)
>>> env.observation_function
ecole.observation.nothing()
>>> obs, _, _, _, _= env.reset("path/to/problem")
>>> obs is None
True
Multiple Observation Functions¶
To use multiple observation functions, wrap them in a list
or dict
.
>>> obs_func = {
... "some_name": ecole.observation.NodeBipartite(),
... "other_name": ecole.observation.Nothing(),
... }
>>> env = ecole.environment.Branching(observation_function=obs_func)
>>> obs, _, _, _, _ = env.reset("path/to/problem")
>>> obs
{'some_name': ecole.observation.NodeBipartiteObs(), 'other_name': None}
Similarily with a tuple
>>> obs_func = (
... ecole.observation.NodeBipartite(), ecole.observation.Nothing()
... )
>>> env = ecole.environment.Branching(observation_function=obs_func)
>>> obs, _, _, _, _ = env.reset("path/to/problem")
>>> obs
[ecole.observation.NodeBipartiteObs(), None]
- 1
We chose to use observation, according to the Partially Observable Markov Decision Process, because the state is really the whole state of the solver.