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), andInitializeChildBranchesCallback
(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
, andScenGen::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), andCompareScenariosCallback
(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
, andScenGen::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.