Building distributions#

Besides the standard Gym environments, Bauwerk also provides distributions over buildings.


For this purpose Bauwerk follows a simplified version of the API of the widely used Meta-RL library MetaWorld.

build_dist_b = bauwerk.benchmarks.BuildDistB()

training_envs = []
for task in build_dist_b.train_tasks:
    env = build_dist_b.make_env()

for env in training_envs:
    act = env.action_space.sample()

Further, Benchmark also support the full MetaWorld API. Note that this is for compatibility reasons, and in many use-cases unnecessarily complex as all Bauwerk Benchmarks only have a single environment class.

# Construct the benchmark, sampling tasks
build_dist_b = bauwerk.benchmarks.BuildDistB()

training_envs = []
for name, env_cls in build_dist_b.train_classes.items():
    env = env_cls()
    task = random.choice(
        [task for task in build_dist_b.train_tasks if task.env_name == name]

for env in training_envs:
    act = env.action_space.sample()

Each Bauwerk building distribution implements (and accept arguments of) the following class:

class bauwerk.benchmarks.BuildDist(cfg_dist, seed=None, num_train_tasks=20, num_test_tasks=10, episode_len=None, dtype=None, env_kwargs=None)[source]#

Building distribution.

  • cfg_dist (CfgDist) – distribution over bauwerk env configs.

  • seed (int, optional) – Random seed. Defaults to None.

  • num_train_tasks (int, optional) – Number of training tasks. Defaults to 20.

  • num_test_tasks (int, optional) – Number of test tasks. Defaults to 10.

  • episode_len (Optional[int]) – (int, optional): Length of episode in distribution environments. If not set, defaults to distribution configuration.

  • dtype (Union[str, np.dtype], optional) – data type to be returned and received by envs. Defaults to None, which leads to the general default of np.float32.

  • env_kwargs (dict, optional) – parameters to pass when creating environment. This should not be used when evaluating on pre-defined benchmark. Defaults to None.

Available distributions#

Bauwerk provides a number of building distributions, each with increasing technical difficulty. The first and easiest distribution, A, always samples the same identical building. The next distribution, B, samples houses with different battery sizes, but keeps the house otherwise identical. The other distributions follow a similar pattern, each adding a bit more complexity to the problem. See the descriptions below for more details on each distribution.


Illustration of Bauwerk distributions A, B, C and D in building parameter space. Each adds one dimension of variability. Distribution A samples always the same home, B samples from a line (of varying battery sizes), and so on.#


Bauwerk is at an early stage of development and the specific configurations of these distributions may change. Always mention the Bauwerk version when reporting results on Bauwerk benchmarks.

class bauwerk.benchmarks.BuildDistA(**kwargs)[source]#

Bauwerk building distribution A:

Identical houses, no variation.

class bauwerk.benchmarks.BuildDistB(**kwargs)[source]#

Bauwerk building distribution B:

Houses with varying battery size (0.5kWh to 20kWh).

class bauwerk.benchmarks.BuildDistC(**kwargs)[source]#

Bauwerk building distribution C.

Houses with varying solar (multiplier: 0.5 to 5) and battery sizes (0.5 to 20kWh).

class bauwerk.benchmarks.BuildDistD(**kwargs)[source]#

Bauwerk building distribution D.

Houses with varying battery (0.5 to 20kWh), load (multiplier: 0.5 to 5) and solar sizes (multiplier: 0.5 to 5). This distribution is effectively like differently sized houses.

class bauwerk.benchmarks.BuildDistE(**kwargs)[source]#

Bauwerk building distribution E.

Same as Bauwerk building distribution D, other than adding irreducible noise.

Custom distributions#

It is also possible to create custom distributions in Bauwerk. See the definition of BuildDistB below as an example:

class BuildDistB(BuildDist):
    """Bauwerk building distribution B:"""

    def __init__(self, **kwargs):
        """Bauwerk building distribution B:

        Houses with varying battery size (0.5kWh to 20kWh)."""
        cfg_dist = CfgDist(
            episode_len=24 * 30,
        super().__init__(**kwargs, cfg_dist=cfg_dist)

The main thing is that we need to set a distribution over configurations CfgDist in the __init__ method. This distribution is very similar to the bauwerk.EnvConfig configuration class, other than that it also allows you to set parameters as distributions. In the code example above, the battery_size is set to be continuous parameter distribution bauwerk.benchmarks.ContParamDist. See how this distribution class is set up below:

class ContParamDist(ParamDist):
    """Distribution over single cfg param."""

    low: float  # lower bound of distribution
    high: float  # higher bound of distribution

    def sample(self):
        return self.fn(low=self.low, high=self.high)
class ParamDist:
    fn: Any  # function to draw from