1"""An example of using output space exploration on the lake problem.
2
3The lake problem itself is adapted from the Rhodium example by Dave Hadka,
4see https://gist.github.com/dhadka/a8d7095c98130d8f73bc
5
6"""
7
8from lake_models import lake_problem_intertemporal
9
10from ema_workbench import (
11 Constant,
12 Model,
13 MultiprocessingEvaluator,
14 RealParameter,
15 Sample,
16 ScalarOutcome,
17 ema_logging,
18)
19from ema_workbench.em_framework.outputspace_exploration import (
20 OutputSpaceExplorationAlgorithm,
21)
22
23if __name__ == "__main__":
24 ema_logging.log_to_stderr(ema_logging.INFO)
25
26 # instantiate the model
27 lake_model = Model("lakeproblem", function=lake_problem_intertemporal)
28 lake_model.time_horizon = 100
29
30 # specify uncertainties
31 lake_model.uncertainties = [
32 RealParameter("b", 0.1, 0.45),
33 RealParameter("q", 2.0, 4.5),
34 RealParameter("mean", 0.01, 0.05),
35 RealParameter("stdev", 0.001, 0.005),
36 RealParameter("delta", 0.93, 0.99),
37 ]
38
39 # set levers, one for each time step
40 lake_model.levers = [
41 RealParameter(f"l{i}", 0, 0.1) for i in range(lake_model.time_horizon)
42 ]
43
44 # specify outcomes
45 # note that outcomes of kind INFO will be ignored
46 lake_model.outcomes = [
47 ScalarOutcome("max_P", kind=ScalarOutcome.MAXIMIZE),
48 ScalarOutcome("utility", kind=ScalarOutcome.MAXIMIZE),
49 ScalarOutcome("inertia", kind=ScalarOutcome.MAXIMIZE),
50 ScalarOutcome("reliability", kind=ScalarOutcome.MAXIMIZE),
51 ]
52
53 # override some of the defaults of the model
54 lake_model.constants = [Constant("alpha", 0.41), Constant("n_samples", 150)]
55
56 # generate a reference policy
57 reference = Sample(
58 "no_policy", **{l.name: 0.02 for l in lake_model.levers} # noqa: E741
59 )
60
61 # we are doing output space exploration given a reference
62 # policy, so we are exploring the output space over the uncertainties
63 # grid spec specifies the grid structure imposed on the output space
64 # each tuple is associated with an outcome. It gives the minimum
65 # maximum, and epsilon value.
66 with MultiprocessingEvaluator(lake_model) as evaluator:
67 res, convergence_info = evaluator.optimize(
68 algorithm=OutputSpaceExplorationAlgorithm,
69 grid_spec=[
70 (0, 12, 0.5),
71 (0, 1, 0.05),
72 (0, 1, 0.1),
73 (0, 1, 0.1),
74 ],
75 nfe=1000,
76 searchover="uncertainties",
77 reference=reference,
78 filename="lake_model_output_space_exploration.tar.gz",
79 directory="./data",
80 rng=42,
81 )