Scenario Generation

Scenario generation

To support you in creating scenarios and a scenario tree, AIMMS provides a system module which provides a customizable scenario generation framework. For each of the two basic methods for scenario generation discussed in Basic Concepts, the module contains a generic procedure to implement that method. To use these scenario generation procedures to generate scenarios and/or a scenario tree, you only have to implement some callback procedures to supply the necessary data for your specific stochastic model.

Importing the system module

To import the generation module into your model, select Install System Module… from the Settings menu, and select the Scenario Generation Module from the dialog box that appears. The module will be added at the end of the model tree of your model. By default, the module prefix of the Scenario Generation Module is ScenGen.

Distribution-based Scenario Generation

Distribution-based scenario generation

The basic procedure in the scenario generation module for distribution-based scenario generation is

  • CreateScenarioTree(Stages, Scenarios, ScenarioProbability, ScenarioTreeMapping).

Input arguments

The procedure has a single input argument:

  • the set of Stages in your stochastic model. This set must be a subset of the predefined set Integers.

Output arguments

The outputs of this procedure are:

  • the set of Scenarios (which must be a subset of AllStochasticScenarios) generated by the procedure,

  • the ScenarioProbability, a one-dimensional parameter indexed over the set Scenarios, and

  • the ScenarioTreeMapping, a two-dimensional element parameter defined over Scenarios\({}\times{}\)Stages to Scenarios, providing a mapping from every scenario during every stage to a single representative scenario for the scenario bundle in which the given scenario is contained during this stage.

Distribution-based callback functions

The contents of the outputs of the procedure CreateScenarioTree is completely based on the results of the problem-specific callbacks that you have to supply. The following callbacks are expected by CreateScenarioTree:

  • InitializeNewScenarioCallback(CurrentStage, Scenario, RepresentativeScenario),

  • InitializeStochasticDataCallback(CurrentStage, Scenario, ChildBranch, ChildBranchName), and

  • InitializeChildBranchesCallback(CurrentStage, Scenario, ChildBranches, ChildBranchNames).

Initializing a new scenario

When building up the scenario tree, AIMMS creates new scenarios on the fly. In order for you to refer to data from previous stages for this scenario, AIMMS will call the callback InitializeNewScenarioCallback for every Stage prior to the current stage, and supply the RepresentativeScenario from the scenario bundle for CurrentStage which also contains the newly created Scenario. By copying the stochastic data for this stage from this representative scenario, you make it available both to you and AIMMS. To properly generate the stochastic model, AIMMS needs the stochastic parameter values for every stage and every scenario.

Supplying stochastic event data

In the procedure InitializeStochasticDataCallback you can provide values to all stochastic parameter values for the ChildBranch during CurrentStage for the Scenario. Because AIMMS has called the InitializeNewScenarioCallback prior to calling InitializeStochasticDataCallback you also have access to the stochastic parameter values of this scenario prior to the current stage. Based on the value of ChildBranch and the prior stochastic parameter values, you should have sufficient information to generate new stochastic parameter values for the current stage. You should pass the relative weight of this branch compared to the other child branches through the return value of the callback. Note that the relative weights you return may, but need not, add up to one. After creating scenarios for all branches, AIMMS will scale the sum of the returned relative weights of all branches to one.

Generating new child branches

Finally, to extend the scenario tree to a next stage, AIMMS calls the callback InitializeChildBranchesCallback. In this callback, you should fill the Integer subset ChildBranches with integers \(1,2,\dots\) for every child branch that you want to add to Scenario at CurrentStage. Through the element parameter ChildBranchNames you should provide a short representative name for every child branch (for instance, "H" and "L" when child branches represent high and low demand). From the branch names you supply, AIMMS will generate the full names of the final element names of the scenarios generated by the scenario generation procedure (for instance '[H,L,H,H,L]' for a scenario with high, low, high, high, and low demand values during the successive stages of the scenario).

Setting the callbacks

The scenario generation module contains templates for each of the callbacks described above. Rather than changing these template callbacks in the module, you are advised to copy the template callbacks to your core model, and change the bodies of the copied callbacks. Finally, you should notify AIMMS of the names of your callback functions by, prior to calling the procedure CreateScenarioTree, assigning the names of your callback procedures to the element parameters

  • ScenGen::InitializeNewScenarioCallbackFunction,

  • ScenGen::InitializeStochasticDataCallbackFunction, and

  • ScenGen::InitializeChildBranchesCallbackFunction.

Example

The following callbacks will cause the procedure CreateScenarioTree to generate a tree with 2 branches "H" and "L" (for high and low demand) at every intermediate node, and initialize Demand.Stochastic for every period. The example assumes the existence of a mapping PeriodToStage(st,t).

Initializing a new scenario

To initialize a new scenario, we have to copy the stochastic demand data for the newly created Scenario during Stage from the scenario RepresentativeScenario. Thus, the body of the InitializeNewScenarioCallback would read

for ( t | PeriodToStage(CurrentStage,t) ) do
    Demand.Stochastic(Scenario,t) := Demand.Stochastic(RepresentativeScenario,t);
endfor;

Generating new child branches

To generate two child branches to any intermediate node in the scenario tree representing high ("H") and low ("L") demand, the implementation of the InitializeChildBackBranchesCallback should be

ChildBranches := { 1, 2 };
ChildBranchNames('1') := "H";
ChildBranchNames('2') := "L";

Initializing stochastic demand

For each newly added child branches, the following implementation of InitializeStochasticDataCallback assigns a high (20) or low (10) stochastic demand value to the Scenario during the CurrentStage

for ( t | PeriodToStage(CurrentStage,t) ) do
    Demand.Stochastic(Scenario,t) := if ( ChildBranch = 1 ) then 20 else 10 endif;
endfor;

return 1;

By returning 1 for all branches, we just indicate that every branch has equal relative weight. For two branches, this will result in a relative probability for each branch of 0.5.

Scenario-based Tree Generation

Scenario-based tree generation

The basic procedure in the scenario generation module for scenario-based tree generation is

  • CreateScenarioData(Stages, Scenarios, ScenarioProbability, ScenarioTreeMapping).

Input arguments

The procedure has a single input argument:

  • the set of Stages in your stochastic model. This set must be a subset of the predefined set Integers.

Output arguments

The outputs of the procedure are:

  • the set of Scenarios for which you have provided stochastic parameter values,

  • the ScenarioProbability, a one-dimensional parameter indexed over the set Scenarios, and

  • the ScenarioTreeMapping, a two-dimensional element parameter defined over Scenarios\({}\times{}\)Stages to Scenarios, providing a mapping from every scenario during every stage to a single representative scenario for the scenario bundle in which the given scenario is contained during this stage.

Algorithm outline

The procedure CreateScenarioData will help you construct a scenario tree as follows:

  • initially, AIMMS will request you to generate a set of scenarios with their relative weights,

  • next, AIMMS will ask you, to divide a given group of scenarios at the current stage into a number of subgroups of equal or similar scenarios at the next stage,

  • AIMMS will request you to reassign a single unique value to each stochastic event parameter for all scenarios in a scenario group (e.g. the mean over all scenarios in the group), and

  • finally, AIMMS will remove scenarios which you identify as identical.

Scenario-based callbacks

For each of the steps outlined in the previous paragraph, you must supply a callback procedure:

  • InitializeStochasticScenarioDataCallback(Scenario, Scenarios),

  • DetermineScenarioGroupsCallback(CurrentStage, ScenarioGroup, ScenarioGroupOrder),

  • AssignStochasticDataForScenarioGroupCallback(CurrentStage, ScenarioGroup), and

  • CompareScenariosCallback(Scenario1, Scenario2, Stages, FirstDifferentStage)

Initializing scenarios

Through the InitializeStochasticScenarioDataCallback you must supply the stochastic event data during all stages for a Scenario generated by AIMMS. The function should return the relative weight of the scenario compared to all other scenarios you supply. If you are done adding scenarios, the callback should return the value 0.

Dealing with existing scenario data

If you have already read scenario data from a database, for instance, you can overwrite the generated value of Scenario argument with an existing scenario name read from the database. In that case, if you have read the stochastic data directly into the .Stochastic suffix of the stochastic parameters in your model, you only have to return the relative weight.

Supplying new scenario data

If you do not have existing scenario data, you should generate stochastic data for the Scenario element generated by AIMMS for all stochastic parameters in your model. If you want to change the name of the generated Scenario, you can do so using the function SetElementRename.

Creating scenario subgroups

In the DetermineScenarioGroupsCallback, you must divide the scenarios in ScenarioGroup created during a previous stage (or the group of all scenarios to start with during the first stage) into subgroups, based on the equality or similarity of the stochastic event values associated with the scenarios during CurrentStage. You must specify the subgroups by assigning a ScenarioGroupOrder to every scenario in the ScenarioGroup, where scenarios with the same assigned order form a subgroup during the current stage.

Assigning stochastic event values

If the stochastic event parameters in ScenarioGroup during CurrentStage are similar, but not equal, you must make sure to assign identical event parameter values to every scenario when AIMMS calls the AssignStochasticDataForScenarioGroupCallback. Failure to do so may result in infeasible stochastic models generated by AIMMS.

Removing identical scenarios

Finally, AIMMS will probe for identical scenarios through the CompareScenarioCallback, remove duplicate scenarios when encountered, and adjust the scenario probabilities accordingly. When the stochastic event values of Scenario1 and Scenario2 are identical during Stages, the callback should return 0. If the scenarios are not identical the callback should have a nonzero return value, and set the output argument FirstDifferentStage equal to the first stage during which the event parameters differ for both scenarios.

Setting the callbacks

The scenario generation module contains templates for each of the callbacks described above. Rather than changing these template callbacks in the module, you are advised to copy the template callbacks to your core model, and change the bodies of the copied callbacks. Finally, you should notify AIMMS of the names of your callback functions by, prior to calling the procedure CreateScenarioData, assigning the names of your callback procedures to the element parameters

  • ScenGen::InitializeStochasticScenarioDataCallbackFunction,

  • ScenGen::DetermineScenarioGroupsCallbackFunction,

  • ScenGen::AssignStochasticDataForScenarioGroupCallbackFunction, and

  • ScenGen::CompareScenariosCallbackFunction.

Example

The callbacks for scenario-based tree generation, are usually more problem-specific, and hence less instructive, than the callbacks for the tree-based scenario generation scheme. Therefore, rather than including a lengthy example here, we refer to the example models for stochastic programming that come with your AIMMS system.

Scenario generation can be modified

The scenario generation module is completely implemented in the AIMMS language itself, and contains basic implementations of both scenario generation methods, which will provide a good starting point for most stochastic models. If neither of these implementations fits your needs, you can copy the module to your project directory, replace the system module with the copy, and make the algorithms in the copied module more advanced to better fit the needs of your stochastic model.