smif.decision package¶
Submodules¶
smif.decision.decision module¶
The decision module handles the three planning levels
Currently, only pre-specified planning is implemented.
The choices made in the three planning levels influence the set of interventions and assets available within a model run.
The interventions available in a model run are stored in a dict keyed by name.
- class smif.decision.decision.DecisionManager(store: Store, timesteps: List[int], modelrun_name: str, sos_model, decision: int = 0)[source]¶
Bases:
objectA DecisionManager is initialised with one or more model run strategies that refer to DecisionModules such as pre-specified planning, a rule-based models or multi-objective optimisation. These implementations influence the combination and ordering of decision iterations and model timesteps that need to be performed by the model runner.
The DecisionManager presents a simple decision loop interface to the model runner, in the form of a generator which allows the model runner to iterate over the collection of independent simulations required at each step.
The DecisionManager collates the output of the decision algorithms and writes the post-decision state through a ResultsHandle. This allows Models to access a given decision state (identified uniquely by timestep and decision iteration id).
The
get_decisions()method passes a ResultsHandle down to a DecisionModule, allowing the DecisionModule to access model results from previous timesteps and decision iterations when making decisions- Parameters:
store (smif.data_layer.store.Store)
- property available_interventions: Dict[str, Dict]¶
Returns a register of available interventions, i.e. those not planned
- buildable(build_year, timestep) bool[source]¶
Interventions are deemed available if build_year is less than next timestep
For example, if a is built in 2011 and timesteps are [2005, 2010, 2015, 2020] then buildable returns True for timesteps 2010, 2015 and 2020 and False for 2005.
- decision_loop()[source]¶
Generate bundles of simulation steps to run
Each call to this method returns a dict:
- {
‘decision_iterations’: list of decision iterations (int), ‘timesteps’: list of timesteps (int), ‘decision_links’: (optional) dict of {
decision iteration in current bundle: decision iteration of previous bundle
}
}
A bundle is composed differently according to the implementation of the contained DecisionModule. For example:
With only pre-specified planning, there is a single step in the loop, with a single decision iteration with timesteps covering the entire model horizon.
With a rule based approach, there might be many steps in the loop, each with a single decision iteration and single timestep, moving on once some threshold is satisfied.
With a genetic algorithm, there might be a configurable number of steps in the loop, each with multiple decision iterations (one for each member of the algorithm’s population) and timesteps covering the entire model horizon.
Implicitly, if the bundle returned in an iteration contains multiple decision iterations, they can be performed in parallel. If each decision iteration contains multiple timesteps, they can also be parallelised, so long as there are no temporal dependencies.
Decision links are only required if the bundle timesteps do not start from the first timestep of the model horizon.
- get_and_save_decisions(iteration, timestep)[source]¶
Retrieves decisions for given timestep and decision iteration from each decision module and writes them to the store as state.
Calls each contained DecisionModule for the given timestep and decision iteration in the data_handle, retrieving a list of decision dicts (keyed by intervention name and build year).
These decisions are then written to a state file using the data store.
Notes
State contains all intervention names which are present in the system at the given
timestepfor the currentiteration. This must include planned interventions from a previous timestep that are still within their lifetime, and interventions picked by a decision module in the previous timesteps.After loading all historical interventions, and screening them to remove interventions from the previous timestep that have reached the end of their lifetime, new decisions are added to the list of current interventions.
Finally, the new state is written to the store.
- class smif.decision.decision.DecisionModule(timesteps: List[int], register: MappingProxyType)[source]¶
Bases:
objectAbstract class which provides the interface to user defined decision modules.
These mechanisms could include a Rule-based Approach or Multi-objective Optimisation.
This class provides two main methods,
__next__which is normally called implicitly as a call to the class as an iterator, andget_decision()which takes as arguments a smif.data_layer.data_handle.ResultsHandle object.- Parameters:
- available_interventions(state: List[Dict]) List[source]¶
Return the collection of available interventions
Available interventions are the subset of interventions that have not been implemented in a prior iteration or timestep
- Return type:
List
- abstractmethod get_decision(results_handle: ResultsHandle) List[Dict][source]¶
Return decisions for a given timestep and decision iteration
- Parameters:
results_handle (smif.data_layer.data_handle.ResultsHandle)
- Return type:
Examples
>>> register = {'intervention_a': {'capital_cost': {'value': 1234}}} >>> dm = DecisionModule([2010, 2015], register) >>> dm.get_decision(results_handle) [{'name': 'intervention_a', 'build_year': 2010}])
- abstractmethod get_previous_state(results_handle: ResultsHandle) List[Dict][source]¶
Return the state of the previous timestep
- class smif.decision.decision.RuleBased(timesteps, register)[source]¶
Bases:
DecisionModuleRule-base decision modules
- get_decision(results_handle) List[Dict][source]¶
Return decisions for a given timestep and decision iteration
- Parameters:
results_handle (smif.data_layer.data_handle.ResultsHandle)
- Return type:
Examples
>>> register = {'intervention_a': {'capital_cost': {'value': 1234}}} >>> dm = DecisionModule([2010, 2015], register) >>> dm.get_decision(results_handle) [{'name': 'intervention_a', 'build_year': 2010}])
- get_previous_iteration_timestep() Tuple[int, int] | None[source]¶
Returns the timestep, iteration pair that describes the previous iteration
- Returns:
Contains (timestep, iteration)
- Return type:
- get_previous_state(results_handle: ResultsHandle) List[Dict][source]¶
Return the state of the previous timestep
- property next_timestep¶
- property previous_timestep¶