Seeding

Ecole empowers researchers to learn reliable machine learning models, and that means not overfitting on insignificant behaviours of the solver. One such aspect is the solver randomness, which is controlled by its random seed.

This means that, by default, Ecole environment will generate different episodes (and in particular different initial states) after each new call to reset(). To do so, the environment keeps a RandomEngine (random state) between episodes, and start a new episode by calling set_dynamics_random_state() on the underlying Dynamics. The latter set random elements of the state including, but not necessary limited to, the Model random seed, by consuming random numbers from the RandomEngine. That way, the EnvironmentComposer can avoid generating identical episodes while letting Dynamics decide what random parameters need to be set.

The seed() method really belongs to the the environment, because it seeds the RandomEngine., not direclty the episode for the Dynamics.

When not explicitly seeded, environment use a RandomEngine derived from Ecole’s global source of randomness. By default this source is truly random, but it can be controlled with ecole.seed().

In short we provide the following snippets.

Reproducible program

Running this program again will give the same outcome.

import ecole

ecole.seed(754)

environment = ecole.environment.Branching()

for _ in range(10):
    observation, action_set, reward_offset, done = env.reset("path/to/problem")
    while not done:
        obs, action_set, reward, done, info = env.step(action_set[0])

Reproducible environments

Creating this envionment with same seed anywhere else will give the same outcome.

import ecole

env = ecole.environment.Branching()
env.seed(8462)

for _ in range(10):
    observation, action_set, reward_offset, done = env.reset("path/to/problem")
    while not done:
        obs, action_set, reward, done, info = env.step(action_set[0])

Reproducible episode

All episodes run in this snippet are identical.

import ecole

env = ecole.environment.Branching()

for _ in range(10):
    env.seed(81)
    observation, action_set, reward_offset, done = env.reset("path/to/problem")
    while not done:
        obs, action_set, reward, done, info = env.step(action_set[0])