Professional Documents
Culture Documents
Application to Hydropower
Production Scheduling
Bachelors Thesis
Yves C. Albers
June, 2011
Academic Supervisor:
Professor Thomas F. Rutherford, ETH Zurich
Centre for Energy Policy and Economics
Department of Management, Technology, and Economics
Abstract
iii
Contents
Contents v
1 Introduction 1
1.1 The Grande-Dixence Hydroelectric Dam . . . . . . . . . . . . 2
1.2 Liberalized Electricity Market - an Overview . . . . . . . . . . 4
1.3 Hydropower Release Scheduling . . . . . . . . . . . . . . . . . 6
1.4 GAMS - The General Algebraic Modeling System . . . . . . . 8
1.5 Deterministic Release Scheduling . . . . . . . . . . . . . . . . . 9
2 Stochastic Programming 17
2.1 Two-Stage Pump Storage Example . . . . . . . . . . . . . . . . 18
2.2 Multi-Stage Problems . . . . . . . . . . . . . . . . . . . . . . . . 22
2.3 Clear Lake Dam Example . . . . . . . . . . . . . . . . . . . . . 24
2.3.1 Node-Based Notation . . . . . . . . . . . . . . . . . . . 26
2.3.2 Scenario-Based Notation . . . . . . . . . . . . . . . . . . 30
3 Implementation 37
3.1 Dynamic Set Assignments . . . . . . . . . . . . . . . . . . . . . 39
3.2 GAMS Limitations . . . . . . . . . . . . . . . . . . . . . . . . . 42
3.3 Treegeneration tool . . . . . . . . . . . . . . . . . . . . . . . . . 43
3.3.1 Node-Based Treegeneration . . . . . . . . . . . . . . . . 43
3.3.2 Scenario-Based Treegeneration . . . . . . . . . . . . . . 44
3.3.3 Performance of Treegeneration tool . . . . . . . . . . . 46
3.4 Scenario-Reduction . . . . . . . . . . . . . . . . . . . . . . . . . 47
3.4.1 Performance of SCENRED . . . . . . . . . . . . . . . . 50
3.5 Computational Framework and Model Specification . . . . . . 51
4 Release Model 53
4.1 Risk aversion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
4.2 GAMS Implementation . . . . . . . . . . . . . . . . . . . . . . . 60
v
Contents
A Appendix 69
A.1 GAMS Code Clear Lake Node-Based Dynamic Set Assignment 70
A.2 GAMS Code Clear Lake Node-Based with treegen.exe . . . . . 72
A.3 GAMS Code Clear Lake Scenario-Based with treegen.exe . . . 74
A.4 GAMS Code Clear Lake Node-Based with SCENRED . . . . . 76
A.5 GAMS Code Release model . . . . . . . . . . . . . . . . . . . . 78
A.6 C++ Code Treegeneration tool . . . . . . . . . . . . . . . . . . 82
Bibliography 93
vi
Chapter 1
Introduction
1
1. Introduction
2
1. Introduction
4
1.2. Liberalized Electricity Market - an Overview
future date. Each futures contract has its specific runtime and delivery vol-
ume, which is usually 1 MW. The party that agrees to buy the electricity
has the long position. The other party, which agrees to deliver the electric-
ity, enters the short position. The EEX offers standardized futures products,
which mature on a weekly, monthly, quarterly and yearly basis. An impor-
tant feature of the financial market is that it allows participants to settle their
contracts not only on a physical level but also on a purely financial level. If
the participants opt for physical delivery, the underlying energy of the fu-
tures contracts must be fed into the grid. On the other hand, a financial
futures contract does not involve any physical electricity flows between the
two parties.
A financially settled contract requires the parties to exchange cash flows in
order to compensate each other for the difference between the agreed deliv-
ery price and the actual spot market price during the contractual runtime.
Most electricity exchanges also allow the trading of standardized option con-
tracts. A buyer of a European call option has the right, but not the obligation
to buy a certain amount of electricity at a predetermined date and strike
price. Conversely, a buyer of a European put option has the right, but not the
obligation, to buy a certain amount of electricity at a predetermined date
and strike price. The buyer of an option must always pay a risk-premium to
the seller.
Finally, the operator can sell his production directly to his clients on a bi-
lateral basis. The OTC market2 allows for tailor-made delivery contracts be-
tween the supplier and his customers, including full requirement contracts
and swing-options.3 Compared to the financial market, the increased flexi-
bility of the OTC market involves an increased counterparty and liquidity
risk.
5
1. Introduction
6
1.3. Hydropower Release Scheduling
7
1. Introduction
8
1.5. Deterministic Release Scheduling
Given the optimal release schedule for 2008, it can be compared to the ac-
tually performed schedule in order to find out how much more could have
gained if we had had perfect information about the future.
Table 1.1 shows the spot market prices and reservoir inflows of each month
during 2008. The example is limited to a single-reservoir (Lake Dix) without
pumping facilities. All the reservoir inflows are natural. Furthermore, the
reservoir is assumed to be connected to just one power plant (Bieudron).
The order of magnitude of the given data roughly corresponds to the actual
data of Grande-Dixence.
Maximize
Rt Prt (1.1)
t
9
1. Introduction
Subject to
Lt = Lt1 + It Rt St (1.2)
Ldec2007 = Lstart (1.3)
Lmin Lt Lmax (1.4)
0 Rt Rmax (1.5)
0 St (1.6)
Note that no target-reservoir level Lend has been specified for the end of the
model horizon. With respect to the definition of the profit function, this will
lead the solution of our optimization to release the whole reservoir by the
end of the year. In reality, however, this may be undesirable because the
operational horizon never really ends. It would be unwise to fully release
the reservoir by the end of the year if high prices were expected for the
subsequent year.
In a more practical setting, in order to avoid so-called end-horizon effects, it
would make sense to constrain the end-horizon level Lend or to extend the
10
1.5. Deterministic Release Scheduling
profit function with a term V ( Lend ) that accounts for the potential future
value of water at the end of the model horizon.
Furthermore, note that the profit function, as well as the reservoir balance
and the constraints, are all modeled in a linear way. In reality, the rate at
which water can be converted to electricity is not constant, but depends on
the head given by the height of the water column above the turbine. There-
fore, power generation is generally a nonlinear function of the reservoir
discharge q and the reservoir head h(q), which depends on the discharge.
The exact relationship is given by:
P = g h(q) q (1.7)
P: Power [Watts]
: turbine efficiency
: density of water [kg/m3 ]
g: acceleration of gravity [9.81m2 /s]
h: head: height of water above turbine [m]
q: Water stream [m3 /s]
To keep the model simple, we assume a constant head, which makes the
power generation directly proportional to the water flow through the tur-
bine. The example uses the energy equivalent value to represent the mean
value of energy produced per amount of water assuming a constant head.
Therefore, in the case of the power plant Bieudron (with an average head of
1883 m), the is given by:
g h q t
EV =
q t
0.9 1000kg/m3 9.81m/s2 1883m 75m3 /s 1h (1.8)
=
75m3 /s 3600s
3
= 4.618KWh/m
The next page illustrates an implementation of the above model with GAMS.
The logic closely follows the mathematical notation from equations 1.1-1.6.
The linear model assumption enables the use of the method of linear pro-
gramming (LP) to solve the equations. Note that GAMS allows for explana-
tory remarks at various parts within the source code, which makes it easy
to read.
11
1. Introduction
12
1.5. Deterministic Release Scheduling
Sets
Declare a set named t and assign the set elements {dec2007, jan, f eb, ...}. The
declaration is followed by a description of the set (here, Months). The set
baset(t) is a subset of set t and contains one element, namely dec2007, which
represents December of the previous year. The set base(t) is used later to
define the initial reservoir level at the beginning of the optimization horizon.
Parameters
Declare an inflow parameter i (t), which depends on set t. Add values to the
inflow parameter. Declare a price parameter pr (t), which depends on set t.
Add values to the price parameter. These declarations correspond to Table
1.1.
Variables
Declare the decision variables L(t), R(t) and S(t) for each member of the
set t. Declare an objective variable OBJ without any index. L.lo (t) = l min
and L.up(t) = l max define a minimum/maximum value for the decision
variable L(t) for all elements of the set t. L. f x (baset) = l start assigns a
fix start value to the decision variable L(0 dec20070 ), which was previously
declared in the set baset(t).
13
1. Introduction
Equations
Names are given to the objective function objde f and the balance equation
level (t). GAMS creates the balance equations for all elements of the set t
according to equation 1.2, except for the base month dec2007. The objective
function OBJ is declared according to the profit function described in equa-
tion 1.1. R.lo (t) = 0 and R.up(t) = r max ensure that the variable R(t) is
positive and below the maximum constraint. S.lo (t) = 0 guarantees that the
spill over S(t) is always positive.
Solve Statement
14
1.5. Deterministic Release Scheduling
160
140
120
Release in mio m^3
100
Actual Release:
80
Optimal Release:
60
40
20
0
Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
The output report of GAMS includes details on all model variables, such as
the evolution of the reservoirs water content or the spill-over. At this point,
however, the focus is only on the optimal release schedule and the objective
value.
The deterministic optimization shows that the operator could have gener-
ated 259, 334, 319 CHF if he had perfectly anticipated the reservoir inflows
and the spot market prices at the beginning of 2008. Figure 1.3 compares the
schedule that was actually performed with the deterministically optimized
schedule. According to the objective function 1.1, the actually performed
schedule resulted in profits of 181, 351, 590 CHF, which is approximately 30
percent less (or, in absolute numbers, 77, 982, 729 CHF) than the optimal
value.
15
Chapter 2
Stochastic Programming
A two-stage recourse problem contains a first stage decision before and a re-
course decision after that we observe the future events. On the other hand,
a multi-stage recourse problem involves decision making across several time
periods.
17
2. Stochastic Programming
18
2.1. Two-Stage Pump Storage Example
Scenarios
Low Normal High
Probability Ps : 0.25 0.5 0.25
Demand ds [MWh]: 80 100 120
Table 2.1: Demand Scenarios for the Next Day
Theoretically, the demand could take on any continuous value from zero
to infinity. However, in order to keep the model size within reach, it is
necessary to develop a finite and discrete set of possible future scenarios.
The mathematical formulation for maximizing the expected profit is given
below:
Maximize
Ps (X2s pE + pR (X1 X2s ) X1 pW ) (2.1)
sS
Subject to
X1 X Max (2.2)
X2s Ds (2.3)
X2s X1 (2.4)
0 X1 , X2s (2.5)
Equation 2.1 sums up the profits for each demand scenario, weighted with
the particular scenario probability Ps . The constraints 2.2-2.5 represent the
problem-specific boundary conditions. Table 2.2 provides details.
19
2. Stochastic Programming
. 40000.000 60000.000 .
---- VAR X2
X2 Second stage decision: How much water to release
LOWER LEVEL UPPER MARGINAL
20
2.1. Two-Stage Pump Storage Example
Of course, the recourse decision in the above example is trivial. The fixed
electricity price means that the operator will release as much water as pos-
sible with respect to the electricity demand. The operator will be always
better off producing electricity than by reselling the water back to the local
beverage company.
However, the recourse decision would become more complex in a model
in which not only the demand but also the electricity price or the reselling
price of the water were described with stochastic coefficients.
The following code shows a possible GAMS implementation for the two-
stage pump storage problem.
1 *-------------------------------------------------------------------------------
2 $title Stochastic Optimization, Two-Stage Pump Storage Model
3 set s scenarios /low, normal, high /;
4 *-------------------------------------------------------------------------------
5 parameters p(s) Probability of each scenario
6 / low 0.25
7 normal 0.5
8 high 0.25 /
9
10 d(s) Demand under each scenario [KWh]
11 / low 80000
12 normal 100000
13 high 120000 /
14
15 x_max Maximum amount of water that can be pumped per night [m^3] /60000/,
16 pe Electricity price per KWh in CHF /0.1/,
17 pw Price to pump up water per m^3 in CHF /0.075/,
18 pr Price per m^3 when sold back to locale beverage company /0.01/,
19 e Electricity [KWh] generated per m^3 of water /2.5/;
20 *-------------------------------------------------------------------------------
21 POSITIVE VARIABLES X1 First stage decision: How much water to pump,
22 X2(s) Second stage decision: How much water to release;
23
24 X1.up = x_max;
25
26 VARIABLES Profit(s) Profit under each scenario,
27 Exp_Profit Expected Profit of the whole day;
28 *-------------------------------------------------------------------------------
29 EQUATIONS Constraint1(s),Constraint2(s),
30 Eq_Profit(s),
31 Eq_Exp_Profit;
32
33 Constraint1(s) .. X2(s) =L= X1;
34 Constraint2(s) .. e*X2(s) =L= d(s);
35
36 Eq_Profit(s) .. Profit(s) =E= X2(s)*e*pe + (X1-X2(s))*pr - X1*pw;
37 Eq_Exp_Profit .. Exp_Profit =E= sum(s, p(s)*Profit(s));
38 *-------------------------------------------------------------------------------
39 model two_stage /ALL/;
40 solve two_stage using lp maximizing Exp_Profit;
21
2. Stochastic Programming
As in the two-stage case, the expectations for the future are captured by a
finite and discrete set of possible scenarios S = {s1, s2, ..., s N }. In contrast
to the two-stage problem, however, the final scenarios may develop over
several time periods. Scenario trees are used to illustrate the evolution of
different realizations.
t=1
Stage 1:
t=2
Stage 2:
t=3
Stage 3:
s1 s2 s3 s4
22
2.2. Multi-Stage Problems
23
2. Stochastic Programming
24
2.3. Clear Lake Dam Example
Note that the inflow expectations are the same for each month, independent
of one another. Table 2.4 describes the physical constraints of the Clear Lake
Dam.
25
2. Stochastic Programming
n40 s27
Realizations: n13 n39 s26
1: low n38 s25
n37
...
2: normal n4 n12 n36
3: high n35
n34
n11 n33
n32
n31
n10 n30
n29
n28
n1 n3 n9 n27
n26
n25
n8 n24
n23
n22
n7 n21
n20
n19
n2 n6 n18
...
n17
n16 s3
n5 n15 s2
n14 s1
Stages: 1. 2. 3. 4.
Stages and Time Periods T: Each stage represents a discrete point in time,
which stands at the end of a particular time period t. The model hori-
zon involves T = 4 time periods, whereas the first interval dec has
already elapsed.
26
2.3. Clear Lake Dam Example
Subject to
27
2. Stochastic Programming
1 *-------------------------------------------------------------------------------
2 $title Stochastic, Multi-Stage Reservoir Release model, Node-Based Notation
3 $ontext
4 Designed in the style of the Clear Lake Dam example found in the GAMS model
5 library
6 $offtext
7 *-------------------------------------------------------------------------------
8 *Sets are defined
9
10 sets r Stochastic realizations (precipitation) /low, normal, high/
11 t Time periods /dec,jan,feb,mar/
12 n Nodes: Decision points or states in scenario tree /n1*n40/,
13 base_t(t) First period /dec/,
14 root(n) The root node: /n1/;
15
16 * The alias command allows to define sets that act in
17 * the same way as an already defined set:
18
19 alias (n,child,parent);
20
21
22 set anc(child,parent) Set which maps each node to predecessor node
23
24 /(n2,n3,n4).n1, (n5,n6,n7).n2, (n8,n9,n10).n3, (n11,n12,n13).n4,
25 (n14,n15,n16).n5, (n17,n18,n19).n6,(n20,n21,n22).n7, (n23,n24,n25).n8,
26 (n26,n27,n28).n9, (n29,n30,n31).n10,(n32,n33,n34).n11,(n35,n36,n37).n12,
27 (n38,n39,n40).n13/;
28
29 * This is an ancillary set that is needed below to formulate the equations:
30
31 set nt(n,t) Association of nodes with time periods
32
33
34 /n1.dec,
35 (n2,n3,n4).jan,
36 (n5,n6,n7,n8,n9,n10,n11,n12,n13).feb,
37 (n14,n15,n16,n17,n18,n19,n20,n21,n22,n23,n24,n25,n26,n27,n28,n29,n30,
38 n31,n32,n33,n34,n35,n36,n37,n38,n39,n40).mar/;
39
40 * This is an ancillary set that is needed below to assign the node
41 * specific inflows and probabilities:
42
43 set nr(n,r) Association of nodes and realizations
44
45 /(n2,n5,n8,n11,n14,n17,n20,n23,n26,n29,n32,n35,n38).low,
46 (n3,n6,n9,n12,n15,n18,n21,n24,n27,n30,n33,n36,n39).normal,
47 (n4,n7,n10,n13,n16,n19,n22,n25,n28,n31,n34,n37,n40).high/;
48 *-------------------------------------------------------------------------------
49 *Parameters are specified
50
51 parameter pr(r) Probability distribution over realizations
52 /low 0.25,
53 normal 0.50
54 high 0.25 /,
28
2.3. Clear Lake Dam Example
55
56 inflow(r) Inflow under realization r
57 /low 50,
58 normal 150,
59 high 350 /,
60
61 floodcost Flooding penalty cost thousand CHF/mm /10/,
62 lowcost Water importation cost thousand CHF/mm /5/,
63 l_start Initial water level (mm) /100/,
64 l_max Maximum reservoir level (mm) /250/,
65 r_max Maximum normal release in any period /200/;
66
67 * Here we assign the node specific inflows:
68
69 parameter n_inflow(n) Water inflow at each node;
70 n_inflow(n)$[not root(n)] = sum{(nr(n,r)),inflow(r)};
71
72 * The probability to arrive at a specific node is calculated for
73 * each node, syntax is explained in Chapter three:
74
75 parameter n_prob(n) Probability of being at any node;
76 n_prob(root) = 1;
77 loop {anc(child,parent),
78 n_prob(child) = sum {nr(child,r), pr(r)}*n_prob(parent);};
79 *-------------------------------------------------------------------------------
80 * Model logic:
81
82 variable EC Expected costs;
83
84 positive variable L(n,t) Reservoir water level -- EOP
85 Release(n,t) Normal release of water (mm)
86 F(n,t) Floodwater released (mm)
87 Z(n,t) Water imports (mm);
88
89 equations ecdef, ldef;
90
91 ecdef..
92 EC =e= sum {nt(n,t),n_prob(n)*[floodcost*F(n,t)+lowcost*Z(n,t)]};
93
94 ldef(nt(n,t))$[not root(n)]..
95 L(n,t) =e= sum{anc(n,parent),l(parent,t-1)}+n_inflow(n)+Z(n,t)-Release(n,t)-F(n,t);
96
97 Release.up(n,t) = r_max;
98 L.up(n,t) = l_max;
99 L.fx(n,base_t) = l_start;
100 *-------------------------------------------------------------------------------
101 model mincost / ecdef, ldef /;
102 solve mincost using LP minimizing EC;
103 *-------------------------------------------------------------------------------
29
2. Stochastic Programming
In the example below, the corresponding scenario was chosen to be the result
of consistently following the low realizations (red lines). The leaf nodes at
the last period have already been uniquely identified as they belong only
to one scenario path. Note that, as in the node-based description, each arc
represents a different inflow realization.
n27.mar
s25.feb n26.mar
n25.mar
n24.mar
s19.jan s22.feb n23.mar
n22.mar
n21.mar
s19.feb s20.mar
s19.mar
s18.mar
s16.feb s17.mar
s16.mar
s15.mar
s1.dec s10.jan s13.feb s14.mar
s13.mar
s12.mar
s10.feb s11.mar
s10.mar
s9. mar
s7.feb s8. mar
s7. mar
s6. mar
s1.jan s4.feb s5. mar
s4. mar
s3. mar
s1.feb s2. mar
s1. mar
Stages: 1. 2. 3. 4.
30
2.3. Clear Lake Dam Example
Apart from notational differences, the mathematical model stays the same,
regardless of whether a scenario-based description or a node-based tree de-
scription is used. However, in terms of the GAMS implementation, a differ-
ent concept is used in order to keep track of the relationships between the
decision points.
Equilibrium Set eq(s,t): As described above, each decision point or state
in the tree is uniquely identified with its time period and a particular
scenario path. The set eq(s, t) = {s1.dec, s1.jan, ..., s27.mar } contains all
combinations of the sets time and scenario, which, together, identify a
particular decision point.
Offset Pointer o(s,t): The offset pointer is the equivalent to the parent
function parent(n) in the node-based case. It is used to map each
decision point to its predecessor in order to formulate the reservoir
balance equation. Due to the specific assignment rule that was used to
define the equilibrium set eq(s,t), two adjacent equilibrium points may
be labeled by different scenarios even though they are both part of the
same scenario path. Therefore, a method is needed to keep track of
the relation between the scenario of a specific equilibrium point eq(s,t)
and the scenario of its predecessor point.
The calculation of the offset pointer o(s,t) is based on an ordered scenario
set. Each of the 27 scenarios in the example has a specific position number,
as Table 2.4 shows. The offset pointer o(s,t) is given by the number that
represents the offset of scenario s in time period t. By definition, the offset
pointers for equilibrium points at the last stage are always equal to zero.
Table 2.5 (together with Figure 2.3) illustrates the calculation of the offset
pointer.
Element: s1 s2 s3 s4 s5 s6 s7 s8 s9 s10 s11 s12 s13 s14 s15 s16 s17 s18 s19 ...
Position Nr: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 ...
31
2. Stochastic Programming
This is very similar to the node-based representation, except that the rela-
tionship between the decision points and the predecessor points is specified
differently:
*-------------------------------------------------------------------------------
L(n,t)=e=sum{anc(n,parent),l(parent,t-1)}+n_inflow(n)+Z(n,t)-Release(n,t)-F(n,t);
*-------------------------------------------------------------------------------
32
2.3. Clear Lake Dam Example
The generation of the same output with a node-based tree structure is more
cumbersome as it is necessary to first determine the particular nodes that
are part of a given scenario. The main drawback of the node-based represen-
tation is that the nodes themselves have no palpable meaning because they
are assigned to the decision points by pure sequential numbering.
The next chapter provides a more detailed discussion on implementational
questions.
The full scenario-based implementation of the Clear Lake model with GAMS
is given below:
33
2. Stochastic Programming
1 *-------------------------------------------------------------------------------
2 $title Stochastic, Multi-Stage Reservoir Release model, Scenario-Based Notation
3 $ontext
4 Designed in the style of the Clear Lake Dam example found in the GAMS model
5 library
6 $offtext
7 *-------------------------------------------------------------------------------
8 *Sets are defined
9 set
10 r Stochastic realizations (precipitation) /low,normal,high/,
11 t Time periods /dec,jan,feb,mar/,
12 s Scenarios /s1*s27/,
13 base_s(s) First scenario /s1/
14 base_t(t) First period /dec/;
15
16 set eq(s,t) Equilibrium points
17 /s1.dec, (s1,s10,s19).jan,
18 (s1,s4,s7,s10,s13,s16,s19,s22,s25).feb,
19 (s1,s2,s3,s4,s5,s6,s7,s8,s9,s10,s11,s12,s13,s14,s15,
20 s16,s17,s18,s19,s20,s21,s22,s23,s24,s25,s26,s27).mar/;
21
22 set root(s,t) Root equilibrium point /s1.dec/;
23
24 * This is an ancillary set, which is needed below to assign the
25 * equilibrium point specific inflows and probabilities:
26
27 set str(s,t,r) Maps equilibrium points to realizations:
28 /(s1.jan,s1.feb,s10.feb,s19.feb,s1.mar,s4.mar,s7.mar,s10.mar,
29 s13.mar,s16.mar,s19.mar,s22.mar,s25.mar).low,
30 (s10.jan,s4.feb,s13.feb,s22.feb,s2.mar,s5.mar,s8.mar,s11.mar,
31 s14.mar,s17.mar,s20.mar,s23.mar,s26.mar).normal
32 (s19.jan,s7.feb,s16.feb,s25.feb,s3.mar,s6.mar,s9.mar,s12.mar,
33 s15.mar,s18.mar,s21.mar,s24.mar,s27.mar).high/;
34 *-------------------------------------------------------------------------------
35 *Parameters are specified including the offset pointer: An automatic procedure
36 *to assign the offset pointers is given in Chapter three.
37 parameter o(s,t) Offset pointer
38
39 /(s1,s4,s7,s10,s13,s16,s19,s22,s25).feb 0,
40 (s2,s5,s8,s11,s14,s17,s20,s23,s26).feb -1,
41 (s3,s6,s9,s12,s15,s18,s21,s24,s27).feb -2,
42
43 s1,s10,s19).jan 0, (s2,s11,s20).jan -1,
44 (s3,s12,s21).jan -2, (s4,s13,s22).jan -3,
45 (s5,s14,s23).jan -4, (s6,s15,s24).jan -5,
46 (s7,s16,s25).jan -6, (s8,s17,s26).jan -7,
47 (s9,s18,s27).jan -8,
48
49 s1.dec 0, s2.dec -1, s3.dec -2, s4.dec -3, s5.dec -4,
50 s6.dec -5, s7.dec -6, s8.dec -7, s9.dec -8, s10.dec -9,
51 s11.dec -10, s12.dec -11, s13.dec -12, s14.dec -13, s15.dec -14,
52 s16.dec -15, s17.dec -16, s18.dec -17, s19.dec -18, s20.dec -19,
53 s21.dec -20, s22.dec -21, s23.dec -22, s24.dec -23,
54 s25.dec -24, s26.dec -25, s27.dec -26/;
34
2.3. Clear Lake Dam Example
35
Chapter 3
Implementation
When dealing with multi-stage stochastic models, a crucial issue is the expo-
nential growth of the scenario tree for each additional time period, t, which
is added to the model horizon. This again results in the exponentially grow-
ing computation time it takes GAMS to solve the model. As shown in the
solution report below, the Clear Lake model from the previous chapter (in-
cluding 27 scenarios) was solved in roughly te = 0.1 seconds.
*-------------------------------------------------------------------------------
--- Starting compilation
--- multi.gms(105) 3 Mb
--- Starting execution: elapsed 0:00:00.004
--- ...
--- Executing CPLEX: elapsed 0:00:00.009
--- multi.gms(101) 4 Mb:00:00.086
--- ...
--- Executing after solve: elapsed 0:00:00.113
*** Status: Normal completion
--- Job multi.gms Stop 05/03/11 15:05:40 elapsed 0:00:00.114
*-------------------------------------------------------------------------------
However, as shown in Figure 3.1 on the next page, the execution time rapidly
increases if the model horizon is extended. Figure 3.1 also shows that the
exponential growth is intensified if the number of possible stochastic realiza-
tions R is increased at each decision node.
This chapter introduces measures to mitigate the exponentially growing ex-
ecution time of stochastic multi-stage problems, focusing on the implemen-
tation with GAMS.
37
3. Implementation
Figure 3.1: GAMS execution time for the Clear Lake model: T=6 time peri-
ods.
Figure 3.2: GAMS execution time for the Clear Lake model: R=6 realizations.
38
3.1. Dynamic Set Assignments
set_name(domain_name)$[condition] = yes | no
Where n is the node number as defined in Figure 2.2 and R is the total
number of stochastic realizations per decision point. Note that the first node
n1 has no predecessor node.
Example:
As shown in Figure 2.2 (R = 3), the predecessor of node n12 is n4, which is
given by:
(12 + 3 2)
parent(12) = =4 (3.2)
3
Note that the brackets b x c map the argument x to the largest previous inte-
ger, for example, b3.56c = 3 .
39
3. Implementation
r ( n ) = ( n + R 2) (mod R) + 1 (3.3)
33 1 33
= 4.5 11 < = 13.5 (3.6)
31 31
40
3.1. Dynamic Set Assignments
*------------------------------------------------------------------------------
alias (n,child,parent);
set anc(child,parent) Association of each node with corresponding parent node;
anc(child,parent)$[floor((ord(child)+card(r)-2)/card(r)) eq ord(parent)] = yes;
*------------------------------------------------------------------------------
set nr(n,r) Association of each node with corresponding realization;
nr(n,r)$[mod(ord(n)+card(r)-2,card(r))+1 eq ord(r)] = yes;
*------------------------------------------------------------------------------
set nt(n,t) Association of each node with corresponding time period;
loop{t,
nt(n,t)$[power(card(r),ord(t)-1)/(card(r)-1) le ord(n)
and ord(n) lt power(card(r),ord(t))/(card(r)-1)] = yes;
};
*------------------------------------------------------------------------------
By comparison, the following GAMS syntax was used to formulate the as-
signment rules:
card(set name): The cardinality operator gives back the number of
elements of a specific set. In the case of the Clear Lake example,
card(s) = 27, which means that the scenario set contains 27 elements.
ord(set name): The ordinality operator returns the specific position
number of a set element. It can only be used together with an or-
dered, one-dimensional set. Example: The statements below will as-
sign the following values to the parameter position: position(low) = 1,
position(normal) = 2 and position(high) = 3.
set s scenarios /low, normal, high/;
parameter position(s);
position(s) = ord(s);
41
3. Implementation
To speed up the model generation time (that is, the membership allocation
of the involved sets) a treegeneration tool was introduced to generate the
scenario tree structure that was implemented in the programming language
C++.
The tool can be used for both the node-based and the scenario-based tree
notation. In the scenario-based case, the tool generates the offset parameter
o(s,t).
The tool can also be used to generate the nodal probabilities (the parameters
n prob(n) in the node-based and eq prob(s, t) in the scenario-based notation),
which again speeds up the model generation time.
42
3.3. Treegeneration tool
*-------------------------------------------------------------------------------
$gdxout cl_in.gdx
$unload t=time_set r=realization_set pr=prob
$gdxout
*-------------------------------------------------------------------------------
The second step is to call the treegeneration tool to create the sets. This is
done with the GAMS statement $call, which allows the command line to be
accessed through GAMS. The correct syntax to start the tree generation is:
*-------------------------------------------------------------------------------
$call treegen.exe cl_in.gdx cl_out.gdx "%gams.sysdir%\"
*-------------------------------------------------------------------------------
The first parameter specifies the input file that contains the time set, the
realization set, and the probabilities (cl in.gdx in our example). The second
parameter denotes the output file in which the treegeneration tool will save
the tree structure. The last parameter is used to pass the path of the GAMS
directory to the program.
The third step is to advise GAMS to import the generated sets from the GDX
output file cl out.gdx. This can be done using the following syntax:
1 API stands for stands for Application Programming Interface. An API code is a software
interface between different programs that allows them to communicate with each other. API
examples for GAMS can be found in the directory /API files in the GAMS home directory.
2 The file is saved in the GAMS working directory.
43
3. Implementation
*-------------------------------------------------------------------------------
$gdxin cl_out.gdx
set n Nodes set;
$load n=n
set anc(n,n) Predecessor-mapping for node set;
$load anc=anc
set nr(n,r) Node-realization-mapping;
$load nr=nr
set nt(n,t) Node-time-mapping;
$load nt=nt
parameter n_prob(n) Nodal probabilities;
$load n_prob=n_prob
$gdxin
*-------------------------------------------------------------------------------
The definition of the model variables and the equations stays exactly the
same as in the case without the treegeneration tool. A full implementation of
the node-based Clear Lake model with the treegeneration tool can be found
in Appendix A.3.
*-------------------------------------------------------------------------------
$gdxout cl_in.gdx
$unload t=time_set r=realization_set pr=prob
$gdxout
*-------------------------------------------------------------------------------
$call treegen.exe cl_in.gdx cl_out.gdx "%gams.sysdir%\"
*-------------------------------------------------------------------------------
$gdxin cl_out.gdx
set s Scenarios - Leaves in the event tree;
$load s=s
set eq(s,t) Equilibrium points - Equivalent to nodes;
$load eq=eq
set str(s,t,r) Association of scenarios with realizations;
$load str=str
parameter o(s,t) Offset pointer;
$load o=offset
parameter eq_prob(s,t) Probability to reach equilibrium point eq;
$load eq_prob=eq_prob
$gdxin
*-------------------------------------------------------------------------------
The rest of the GAMS model (that is, the definition of the model variables
and the equations) is exactly the same as in the model without the treegen-
44
3.3. Treegeneration tool
C:\models\scenario-based>gdxviewer cl_out.gdx
45
3. Implementation
Execution Time
Time to solve Clear Lake model for R=3 realizations
90
80
70
Time in Seconds
Figure 3.4 also shows that as the number of time periods T is increased, the
share of the total execution time made up of the model solution time eventu-
ally becomes bigger in relation to the model generation time. This is contrary
to the case without the treegeneration tool, where the model generation time
accounted for the bulk of the total execution time.
Note that the treegeneration tool only speeds up the GAMS model generation.
The model solution time (time to execute CPLEX) stays the same in both cases.
46
3.4. Scenario-Reduction
3.4 Scenario-Reduction
One approach to speeding up the solving (model solution time) of multi-stage
recourse problems, which are based on large scenario trees, is to make use
of a tree reduction tool. The idea is to compress the problem size by reduc-
ing the number of scenarios involved. Of course, the reduction follows a
systematic approach based on statistic principles. The challenge is to reduce
the number of involved scenarios in such a way that the solution of the
reduced problem resembles the solution of the original problem to a high
degree.
An interesting scenario reduction tool that can be easily linked to a nodal
problem description is the SCENRED tool, which is part of the GAMS utility
library. SCENRED reduces the original problem with the help of one of three
reduction algorithms. The reduced problem can then be solved normally
with a GAMS solver. A detailed discussion on SCENRED is provided in [8].
SCENRED usage is straight-forward and can be implemented easily within
the Clear Lake example. The first step is to create additional sets and pa-
rameters in which the new tree structure will be saved after the scenario
reduction.
*-------------------------------------------------------------------------------
set r_n(n) Nodes in reduced tree
r_anc(child,parent) Predecessor mapping for reduced tree
parameter r_n_prob(n) Probabilities for reduced tree;
*-------------------------------------------------------------------------------
47
3. Implementation
*-------------------------------------------------------------------------------
*Unload the scenario reduction parameters, the node set n, the predecessor
* mapping set anc, the node probabilities n_prob and the inflows at each
* node n_inflow into the GDX file lakein.gdx
r_n(n)$[r_n_prob(n)]= yes;
*-------------------------------------------------------------------------------
The reduced sets and probabilities can now be used to formulate the equa-
tions for the reduced tree. All that is required is to replace the sets that
48
3.4. Scenario-Reduction
describe the initial tree with the sets that describe the reduced tree. The
node set n is replaced by r n, the ancestor set anc(n, parent) is replaced by
r anc(r n, parent) and the probabilities n prob(r n) are replaced by r n prob(r n).
*-------------------------------------------------------------------------------
equations ecdef, ldef;
ecdef..
EC =e= sum {nt(r_n,t),r_n_prob(r_n)*[floodcost*F(r_n,t)+lowcost*Z(r_n,t)]};
ldef(nt(r_n,t))$[not root(r_n)]..
L(r_n,t)=e=sum{r_anc(r_n,parent),l(parent,t-1)}+n_inflow(r_n)+Z(r_n,t)-
Release(r_n,t)-F(r_n,t);
Release.UP(r_n,t) = 200;
L.UP(r_n,t) = 250;
L.FX(r_n,base_t) = 100;
*-------------------------------------------------------------------------------
49
3. Implementation
The fact that the expected costs (EC) diverge by an average of approximately
11 percent represents a relatively robust result of the scenario reduction
method (for a tree reduction of 30 percent). However, with regard to the
computational efficiency of the SCENRED tool, it is important to note that
the run-times needed to perform the reduction steps are much bigger than
the actual time gain that results from the reduced tree size.
Table 3.1 illustrated that the GAMS model solution time ts for the Clear Lake
model (R=3 realizations, T=7 time periods resulting in 1093 nodes) is given
by roughly 0.2 seconds (without SCENRED). It takes SCENRED approxi-
mately 56 seconds to perform the scenario reductions for the same model
size (without the time used to generate and solve the model). The time
needed to reduce the scenario tree is too long in relation to the model solu-
tion time for it to have a positive effect on the overall performance, especially
due to the fact that the SCENRED reduction time also increases in an expo-
nential manner with each additional time period.
Therefore, it may be concluded that the SCENRED tool is not a practical
way of improving the model solution time of large models. The figures below
graphically illustrate the reduction of a scenario tree.
50
3.5. Computational Framework and Model Specification
51
3. Implementation
52
Chapter 4
Release Model
This chapter illustrates the use of stochastic programming to solve the hydro
scheduling problem in a more realistic setting. The following model deter-
mines an optimal production schedule for the next day, taking into account
our expectations about future reservoir inflows and electricity prices. It is
assumed that the operator plans to sell his production on the day-ahead spot
market. The basic idea is to find a one-day production plan that balances
current profits with expected future profits [3].
By observing the current spot market price for physical delivery on the next
day, the operator must decide how much electricity he is willing to sell, in
consideration of possible future price and inflow developments. The model
aims to evaluate the opportunity to sell electricity at the current spot market
price against the possibility to sell the production in a future period.
The model includes T = 6 = six time periods (six stages), comprising a total
time span of roughly one year. The time periods vary in length: the first
period t1 is a single day, the second and the third period t2 and t3 are single
weeks, the fourth and fifth periods t4 and t5 are 10 weeks each and the last
period t6 is 30 weeks.
t1 t2 t3 t4 t5 t6
The first-stage decision represents the one-day production plan for the fol-
lowing day. The first time period is assumed to be deterministic as the spot
market prices for delivery on the next day has already been observed. Fur-
53
4. Release Model
thermore, the reservoir inflows for the first period are assumed to be certain.
However, because reservoir inflows and electricity prices during the remain-
ing five periods are uncertain, they are described with stochastic quantities.
The decisions subsequent to the first-stage are believed to evaluate the con-
sequences of the one-day production plan on the future production [3].
Note that, in contrast to the Clear Lake example which only included one
stochastic variable (namely in f low), a second stochastic variable price has
now be added to the model. The uncertainty of price and inflow is described
with a joint discrete distribution and represented with the help of a scenario
tree.
At each decision point, there are assumed to be R = 3 possible realizations
for the stochastic variables. Therefore, the total number of scenarios s is
given by R T 1 = 35 = 243. The total number of nodes n in the tree is given
by:
T 1 5
Ri = 3i = 364 (4.1)
i =0 i =0
Each node n represents a decision point or state that stands for a particular
realization of inflows and prices up to the period of state n, denoted with
t(n) [2]. The decisions at node n are assumed to be taken after the realization
of the stochastic inflow and spot market price are observed for the particular
period t(n).
Figure 4.2 shows the first four time periods of a possible scenario tree de-
scribing our inflow and price expectations. Each node has a particular con-
ditional probability, an assigned inflow, and an average spot market price
for its particular period t(n).
54
n40, 0.25, 80, 45
n13, 0.25,
18, 60 n39, 0.50, 50, 50
n38, 0.25, 22, 80
n37, 0.25, 80, 45
n4, 0.25, n12, 0.5
10, 75 n36, 0.50, 50, 50
15, 70 n35, 0.25, 22, 80
n34, 0.25, 80, 45
n11, 0.25,
3, 120 n33, 0.50, 50, 50
n32, 0.25, 22, 80
n31, 0.25, 80, 45
n10, 0.25,
18, 60 n30, 0.50, 50, 50
n29, 0.25, 22, 80
n28, 0.25, 80, 45
n1,1.0, n3, 0.5, n9, 0.5,
1.5, 100 7, 90 10, 75 n27, 0.50, 50, 50
n26, 0.25, 22, 80
n25, 0.25, 80, 45
n8, 0.25, n24, 0.50, 50, 50
3, 120 n23, 0.25, 22, 80
n22, 0.25, 80, 45
n7, 0.25, n21, 0.50, 50, 50
18, 60 n20, 0.25, 22, 80
n19, 0.25, 80, 45
n2, 0.25, n6, 0.5, n18, 0.50, 50, 50
5, 110 10, 75 n17, 0.25, 22, 80
n16, 0.25, 80, 45
n5, 0.25, n15, 0.50, 50, 50
3, 120 n14, 0.25, 22, 80
Figure 4.2: Scenario Tree: Only the first 4 stages are shown. The first number
after the node index is the conditional node probability, the second number
represents the reservoir inflows in million m3 , and the third number repre-
sents the average spot market price in CHF for the period t(n). Note that
the periods have different lengths.
Decision Variables
55
4. Release Model
Subject to
The profit function 4.2 represents the expected profit by summing up the
nodal profits weighted by their particular node probabilities Pn . There are no
direct variable costs of production. However, spill-over costs in each node
are represented through the term cs Sn in the profit function. Furthermore,
56
each cash flow is adapted with the help of the discount interest rate d to dis-
count all cash flows to the present value (PV). The interest rate d is adapted
for periods of unequal lengths [2].
The initial reservoir level is given by LStart . Equation 4.3 represents the physi-
cal reservoir balance for the deterministic first stage. Equation 4.4 represents
the physical reservoir balance for the other nodes, whereas the function Par-
ent(n) describes the mapping of each node to its predecessor node.
To avoid end-horizon effects, a target reservoir level, Lend , was specified for
all the nodes, n, at the end of the model horizon. The numerical values of
the constraints correspond approximately to the Grande-Dixence reservoir,
assuming that only the power plant Bieudron is used for electricity genera-
tion and that pumping facilities are ignored.
Constraints: Value:
Lmax : 400 million m3
Lmin : 40 million m3
Lend : 0.5Lmax = 200 million m3
: 4618 MWh per million m3
Table 4.1: Physical Constraints
The maximum release capacity, Rmax , of the power plant Bieudron is given
by 6.48 million m3 /s. Hence the maximum release capacity per time period
Rmax,t is given by d Rmax , whereas d is the duration of time period t.
In reality, the model would be applied dynamically meaning that the oper-
ator just uses the first stage decision and then reruns the model based on
new market information. In other words, it is necessary to generate a new
scenario tree each day, such as the one described in Figure 4.2, which serves
as input data for the model. This guarantees that decisions are always taken
based on the latest price and inflow expectations [2].
57
4. Release Model
1 1
(
1 , if is unequal to 1
u( ) = (4.9)
ln , if is equal to 1
58
4.1. Risk aversion
Whereas
59
4. Release Model
60
4.3. Results and Discussion
61
4. Release Model
pected to be very high at one stage and the reservoir inflows have also been
high up to this stage, the model will risk a spill-over (depending on the spill-
over costs) at prior stages in order to profit from the interplay between high
prices and a fully charged reservoir.
Expected profit in relation to maximum release capacity:
The simulations show that the expected profit increases if the models daily
maximum release capacity Rmax is changed. This seems reasonable given
that the bigger the release capacity, the more flexibility is available to store
the water in the hope of more favorable future prices without risking a spill
over. Figure 4.4 illustrates the exact relationship between the expected profit
and the daily maximum release capacity Rmax . If the maximum release capacity
is equal to zero, the expected profit will be negative, as the entire reservoir
content must be spilled over, which incurs spill-over costs. As Rmax increases,
the expected profit increases as well. However, at a certain release capacity,
the expected profit reaches a maximum because there is no more additional
benefit for an increased flexibility. The reservoir operator already has the
optimal release capacity (Bieudron can release up to 6.48 million m3 per day).
The averaged expected profit was calculated on the basis of five different
scenario trees.
300000000
200000000
100000000
0
0 0.5 1 1.5 2 2.5 3 3.5 4 4.5 5 5.5 6 6.5 7 7.5 8
-100000000
-200000000
-300000000
-400000000
Maximum Release Capacity in million m^3
Figure 4.4: Relationship between expected profit and maximum release ca-
pacity.
62
4.3. Results and Discussion
215000000
Expected Profit
210000000
205000000
200000000
195000000
190000000
200 250 300 350 400 450 500 550
Maximum Reservoir Height [m]
63
4. Release Model
240000000
235000000
Expected Profit
230000000
225000000
220000000
0 0.5 1 1.5 2 2.5 3 3.5 4 4.5
Risk Aversion: Gamma
Figure 4.6: Relationship between expected profit and risk aversion factor .
profit in relation to the degree of risk aversion . Taking the NSD as an in-
tuitive risk indicator, the risk (normalized standard deviation) decreases for
risk-averse preferences ( > 0), which is consistent with our expectations.
However, the NSD in our simulations is rather small, so the relative reduc-
tion from the risk-neutral case ( = 0 where the NSD is approximately 2
percent) to the risk-averse case ( = 4.5 where the NSD is approximately
1.65 percent) seems to be of minor relevance. The small standard deviations
are probably due to the underlying scenario trees used in our simulations.
It would be interesting to run our model based on a representative number
of realistic scenario trees to further investigate the effect of the risk aversion
factor on the expected profit and the standard deviation. However, sub-
stantial modeling of future electricity market prices and reservoir inflows is
beyond the scope of this thesis. Figure 4.7 shows the average results for five
different scenario trees.
64
4.3. Results and Discussion
2
1.95
1.9
1.85
1.8
1.75
1.7
1.65
1.6
1.55
1.5
0 0.5 1 1.5 2 2.5 3 3.5 4 4.5
Risk Aversion: Gamma
2 Nend is the set of nodes n that is in the last stage at the end of the model horizon.
65
4. Release Model
Conclusion (Summary)
This thesis has provided step-by-step instructions for using the framework
of stochastic programming to approach hydropower production scheduling.
The paper focused especially on the practical implementation with the alge-
braic modeling language GAMS. As shows the first chapter, there is usually
a significant gap between the actual profit generated by a hydropower op-
erator and the theoretical maximum profit the operator could have gained
if he had perfect information about reservoir inflows and electricity prices
at the beginning of the year. This generates the need to develop effective
production scheduling models.
The second chapter showed how to use stochastic recourse models to solve
an optimization problem that involves decision making under uncertainty.
The basic example provided was an adapted version of the Clear Lake model,
which is part of the GAMS model library. Based on our future expectations
about the evolution of the reservoir inflows, we illustrated two different ap-
proaches to describe a stochastic scenario tree: namely a node-based notation
and a scenario-based notation. Each approache offers specific advantages. A
node-based model can be solved slightly faster than a scenario-based model,
while the solution report of a scenario-based model may be interpreted in a
straight-forward manner.
The third chapter discussed computational issues concerning stochastic pro-
gramming and showed how the model execution time rises exponentially
with each additional time step added to the model horizon. We showed
how the performance of GAMS is limited in creating large scenario trees
by assigning memberships to dynamic sets. Therefore, the thesis introduces
a treegeneration tool written in the programming language C++, which sig-
nificantly speeds up the GAMS model generation phase. By outsourcing the
generation of the scenario tree to the treegeneration tool, we were able to use
much larger stochastic multi-stage models than would have been possible
by creating the scenario tree structure within GAMS.
This chapter also showed how to use the scenario reduction tool SCENRED
from the GAMS standard model library, which scales down the size of a
node-based multi-stage model, thereby attempting to reduce the model solu-
tion time. However, we conclude that SCENRED fails to speed up the total
solution time of large multi-stage models, as the reduction time is greater
than the time gain that results from the reduced scenario tree.
Finally, the fourth chapter extended the Clear Lake example to a more re-
alistic release model (Release Model) that determines the optimal reservoir
release decision for the following production day with respect to future in-
flow and price expectations.
The analysis showed that the Release Model produces reasonable outputs for
66
4.3. Results and Discussion
a range of different input parameters and is suitable for quantifying the in-
fluence of these parameters on the expected profit and the first-stage release
decision. Furthermore, the Release Model can be used to analyze the effect
of different risk attitudes on the production schedule. Based on five differ-
ent scenario trees as input data, the analysis showed that both the expected
profit and the normalized standard deviation of the expected profit were
reduced if risk-aversion was incorporated into the model.
However, some aspects remain to be developed if the Release Model is to
become more realistic. For example, the model could be expanded to a
multi-reservoir system that includes pumping facilities, or it could take into
account the nonlinear relationship between water release and power gener-
ation that was discussed in the first chapter. Furthermore, the Release Model
presented in this paper included six time periods, resulting in 243 different
stochastic scenarios: this allowed for three stochastic realizations per deci-
sion node. Depending on the available price and inflow forecasts, it would
be interesting to compare the relative performance among models that have
different model lives, including different numbers of stochastic realizations
per decision node.
Moreover, the thesis did not evaluate the actual performance of our Release
Model (which would result from the actual yearly profit generated by apply-
ing the model for production scheduling). Such computations would have
to be based on daily generated scenario trees describing the latest inflow
and price expectations. This would be beyond the scope of this thesis.
67
Appendix A
Appendix
All models used in this thesis and the treegeneration tool can be downloaded
under:
http://dl.dropbox.com/u/24263007/Treegen.zip
69
A. Appendix
/low 0.25,
normal 0.50,
high 0.25/
/low 50,
normal 150,
high 350/
70
A.1. GAMS Code Clear Lake Node-Based Dynamic Set Assignment
*-------------------------------------------------------------------------------
* Calculate water inflows at each node:
ecdef..
EC =e= sum {nt(n,t),n_prob(n)*[floodcost*F(n,t)+lowcost*Z(n,t)]};
ldef(nt(n,t))$[not root(n)]..
L(n,t) =e= sum{anc(n,parent),l(parent,t-1)}+n_inflow(n)+Z(n,t)-Release(n,t)-F(n,t);
Release.up(n,t) = r_max;
L.up(n,t) = l_max;
L.fx(n,base_t) = l_start;
*-------------------------------------------------------------------------------
model mincost / ecdef, ldef /;
solve mincost using LP minimizing EC;
*-------------------------------------------------------------------------------
71
A. Appendix
/low 0.25,
normal 0.50,
high 0.25/
/low 50,
normal 150,
high 350/
$gdxout cl_in.gdx
$unload t=time_set r=realization_set pr=prob
$gdxout
$call treegen.exe cl_in.gdx cl_out.gdx "%gams.sysdir%\"
*-------------------------------------------------------------------------------
* Read data structures describing the node-based tree:
$gdxin cl_out.gdx
set n Nodes set;
$load n=n
set anc(n,n) Predecessor-mapping for node set;
$load anc=anc
set nr(n,r) Node-realization-mapping;
$load nr=nr
set nt(n,t) Node-time-mapping;
$load nt=nt
parameter n_prob(n) Nodal probabilities;
72
A.2. GAMS Code Clear Lake Node-Based with treegen.exe
$load n_prob=n_prob
$gdxin
*-------------------------------------------------------------------------------
alias (n, child, parent)
set base_t(t) Define set containing first time period;
base_t(t) = yes$(ord(t) =1);
set root(n) Define set containing first node;
root(n) = yes$(ord(n) = 1);
*-------------------------------------------------------------------------------
* Calculate water inflows at each node:
ecdef..
EC =e= sum {nt(n,t),n_prob(n)*[floodcost*F(n,t)+lowcost*Z(n,t)]};
ldef(nt(n,t))$[not root(n)]..
L(n,t)=e=sum{anc(n,parent),l(parent,t-1)}+n_inflow(n)+Z(n,t)-Release(n,t)-F(n,t);
Release.up(n,t) = r_max;
L.up(n,t) = l_max;
L.fx(n,base_t) = l_start;
*-------------------------------------------------------------------------------
model mincost / ecdef, ldef /;
solve mincost using LP minimizing EC;
*-------------------------------------------------------------------------------
73
A. Appendix
/low 0.25,
normal 0.50,
high 0.25/
/low 50,
normal 150,
high 350/
$gdxout cl_in.gdx
$unload t=time_set r=realization_set pr=prob
$gdxout
$call treegen.exe cl_in.gdx cl_out.gdx "%gams.sysdir%\"
*-------------------------------------------------------------------------------
* Read data structures describing the scenario-based tree:
$gdxin cl_out.gdx
set s Scenarios - Leaves in the event tree;
$load s=s
set eq(s,t) Equilibrium points - Equivalent to nodes;
$load eq=eq
set str(s,t,r) Association of scenarios with realizations;
$load str=str
parameter o(s,t) Offset pointer;
$load o=offset
parameter eq_prob(s,t) Probability to reach equilibrium point eq;
74
A.3. GAMS Code Clear Lake Scenario-Based with treegen.exe
$load eq_prob=eq_prob
$gdxin
*-------------------------------------------------------------------------------
set root(s,t) Define the first equilibrium point;
root(s,t) = yes$(ord(t) = 1 and ord(s) =1);
*-------------------------------------------------------------------------------
* Calculate water inflows at each equilibrium point:
ecdef..
EC =e= sum(eq(s,t),eq_prob(s,t)*(floodcost*F(s,t)+lowcost*Z(s,t)));
ldef(eq(s,t))$[not root(s,t)]..
L(s,t)=e=L(s+o(s,t-1),t-1)+eq_inflow(s,t)+Z(s,t)-Release(s,t)-F(s,t);
Release.up(s,t) = r_max;
L.up(eq(s,t)) = l_max;
L.fx(root(s,t)) = l_start;
*-------------------------------------------------------------------------------
model mincost / ecdef, ldef /;
solve mincost using LP minimizing EC;
*-------------------------------------------------------------------------------
75
A. Appendix
*-------------------------------------------------------------------------------
* Unload the time and realization sets "t", "r" and the realization specific
* probabilities "pr" into a GDX file and start treegeneration tool:
$gdxout cl_in.gdx
$unload t=time_set r=realization_set pr=prob
$gdxout
$call treegen.exe cl_in.gdx cl_out.gdx "%gams.sysdir%\"
*-------------------------------------------------------------------------------
* Read data structures describing the node-based tree:
$gdxin cl_out.gdx
set n Nodes set;
$load n=n
set anc(n,n) Predecessor-mapping for node set;
$load anc=anc
set nr(n,r) Node-realization-mapping;
$load nr=nr
set nt(n,t) Node-time-mapping;
$load nt=nt
parameter n_prob(n) Nodal probabilities;
$load n_prob=n_prob
$gdxin
*-------------------------------------------------------------------------------
alias (n,child,parent)
set base_t(t) Define set containing first time period;
base_t(t) = yes$(ord(t) =1);
set root(n) Define set containing first node;
root(n) = yes$(ord(n) = 1);
76
A.4. GAMS Code Clear Lake Node-Based with SCENRED
*-------------------------------------------------------------------------------
parameter n_inflow(n) Water inflow at each node;
n_inflow(n)$[root(n)] = 0;
n_inflow(n)$[not root(n)] = sum{(nr(n,r)),inflow(r)};
*-------------------------------------------------------------------------------
variable EC Expected value of cost;
ScenRedParms(num_leaves) = card(r)**(card(t)-1);
ScenRedParms(num_random) = 1;
ScenRedParms(num_nodes) = card(n);
ScenRedParms(num_time_steps) = card(t);
ScenRedParms(red_percentage) = 0.3;
ecdef..
EC =e= sum {nt(r_n,t),r_n_prob(r_n)*[floodcost*F(r_n,t)+lowcost*Z(r_n,t)]};
ldef(nt(r_n,t))$[not root(r_n)]..
L(r_n,t)=e=sum{r_anc(r_n,parent),l(parent,t-1)}+n_inflow(r_n)+Z(r_n,t)-
Release(r_n,t)-F(r_n,t);
Release.UP(r_n,t) = 200;
L.UP(r_n,t) = 250;
L.FX(r_n,base_t) = 100;
*-------------------------------------------------------------------------------
model mincost / ecdef, ldef /;
solve mincost using LP minimizing EC;
*-------------------------------------------------------------------------------
77
A. Appendix
$gdxout cl_in.gdx
$unload t=time_set r=realization_set pr=prob
$gdxout
$call treegen.exe cl_in.gdx cl_out.gdx "%gams.sysdir%\"
*-------------------------------------------------------------------------------
* Read data structures describing the node-based tree:
$gdxin cl_out.gdx
set n Nodes set;
$load n=n
set anc(n,n) Predecessor-mapping for node set;
$load anc=anc
set nr(n,r) Node-realization-mapping;
$load nr=nr
set nt(n,t) Node-time-mapping;
$load nt=nt
parameter n_prob(n) Nodal probabilities;
$load n_prob=n_prob
$gdxin
*-------------------------------------------------------------------------------
set base_t(t) First period;
base_t(t)$(ord(t)=1) = yes;
set last_period(t) Last time period;
last_period(t)$(ord(t) =card(t)) = yes;
set root(n) First decision node;
root(n)$(ord(n)=1)=yes;
alias (n,child,parent);
set s scenarios /s1*s243/;
*-------------------------------------------------------------------------------
set last_stage(n,t) Set containing decision nodes at the last stage;
scalar tmp1;
tmp1 = sum(t,power(card(r),ord(t)-1)) - power(card(r),card(t)-1);
last_stage(n,t)$[ord(n) gt tmp1 and (ord(t) eq card(t))] = yes;
*-------------------------------------------------------------------------------
set sn(n,s) linking of each scenario to its final node;
scalar tmp1;
tmp1 = sum(t,power(card(r),ord(t)-1)) - power(card(r),card(t)-1);
78
A.5. GAMS Code Release model
79
A. Appendix
*Profit function for all the other nodes: Total profit up to node n time t:
n_profit_2(nt(n,t))$[not root(n)]..
profit(n,t) =e= sum{anc(n,parent),profit(parent,t-1)}+piscale*discount(t)*
[Release(n,t)*e*n_price(n)-F(n,t)*floodcost] ;
*Expected Utility
utility..
U =e= sum(last_stage(n,t), n_prob(n)*[(profit(n,t)**(1-gamma)-1)/(1-gamma)]);
80
A.5. GAMS Code Release model
81
A. Appendix
#include "gclgms.h"
#include "gamsxco.hpp"
#include "gdxco.hpp"
#include "optco.hpp"
#include <vector>
#include <stdio.h>
#include <cstring>
#include <string>
#include <cassert>
#include <iostream>
#include <Windows.h>
#include <time.h>
/*----------------------------------------------------------------------------*/
/* In this section we define functions which are used to describe the
/* relationship between the tree nodes and certain tree characteristics.
/*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*/
/* The following function calculates the total number of nodes in the tree:
/* Input: number of periods, number of realizations
/* Output: Total number of nodes
/*----------------------------------------------------------------------------*/
int sum=0;
82
A.6. C++ Code Treegeneration tool
int temp1=0;
for(int x=0; x<time_steps; ++x)
{
temp1 = pow(realizations,x);
sum = sum+temp1;
}
return(sum);
}
/*----------------------------------------------------------------------------*/
/* The following function links each node to its corresponding time period
/* Input: node number, number of periods, number of realizations,
/* Output: time period of that node
/*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*/
/* The following function links each node to its parent node
/* Input: node number, number of realizations, Output: number of parent node
/*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*/
/* The following function maps each node to its corresponding realization
/* Input: node number, number of realizations,
/* Output: realization number of node
/*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*/
/* This function converts an integer into a string
83
A. Appendix
/*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*/
/* Input: GDX output file, number of time periods, number of realizations,
/* time period vector, realization vector and probability vector.
/* The function writes the required sets and parameters which are used
/* to describe a node-based and a scenario-based scenario tree into the gdx
/* file given by the argument fngdxfile.
/*----------------------------------------------------------------------------*/
nr_periods = t;
nr_realizations = r;
nr_scenarios = pow(nr_realizations,nr_periods-1);
/*----------------------------------------------------------------------------*/
/* Create two string vectors which contain (i) the nodes,
/* and (ii) the scenarios
/*----------------------------------------------------------------------------*/
char temp1[15];
IntToString(i+1, temp1);
char temp2[20]="n";
strcat(temp2,temp1);
node_vector[i] = temp2;
}
char temp1[15];
IntToString(i+1, temp1);
char temp2[20]="s";
strcat(temp2,temp1);
scenario_vector[i] = temp2;
84
A.6. C++ Code Treegeneration tool
/*----------------------------------------------------------------------------*/
/* Create a vector that contains the nodal probabilities
/*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*/
/* Begin to write GDX file
/*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*/
/* Write node vector as a set into GDX file:
/*----------------------------------------------------------------------------*/
if (0==gdx.DataWriteDone())
gdxerror(gdx.GetLastError(), "gdxDataWriteDone");
/*----------------------------------------------------------------------------*/
/* Write scenario vector as a set into GDX file:
/*----------------------------------------------------------------------------*/
if (0==gdx.DataWriteStrStart("s", "scenarios",1,GMS_DT_SET,0))
gdxerror(gdx.GetLastError(), "gdxDataWriteStrStart");
if (0==gdx.DataWriteDone())
gdxerror(gdx.GetLastError(), "gdxDataWriteDone");
/*----------------------------------------------------------------------------*/
85
A. Appendix
if (0==gdx.DataWriteStrStart("anc", "Predecessor-Mapping",2,GMS_DT_SET,0))
gdxerror(gdx.GetLastError(), "gdxDataWriteStrStart");
if (0==gdx.DataWriteDone())
gdxerror(gdx.GetLastError(), "gdxDataWriteDone");
/*----------------------------------------------------------------------------*/
/* Write nodal probabilities as a parameter into GDX file for node-based tree
/*----------------------------------------------------------------------------*/
if (0==gdx.DataWriteDone())
gdxerror(gdx.GetLastError(), "gdxDataWriteDone");
/*----------------------------------------------------------------------------*/
/* Write equilibrium point probabilities eq_prob as a parameter into GDX file
/* for scenario-based tree notatio
/*----------------------------------------------------------------------------*/
86
A.6. C++ Code Treegeneration tool
if (0==gdx.DataWriteDone())
gdxerror(gdx.GetLastError(), "gdxDataWriteDone");
/*----------------------------------------------------------------------------*/
/* Write node-time mapping as a two-dimensional set into GDX file
/* for node-based tree
/*----------------------------------------------------------------------------*/
if (0==gdx.DataWriteDone())
gdxerror(gdx.GetLastError(), "gdxDataWriteDone");
/*----------------------------------------------------------------------------*/
/* Write node-realization mapping as a two-dimensional set into GDX file for
/* node-based tree
/*----------------------------------------------------------------------------*/
if (0==gdx.DataWriteDone())
gdxerror(gdx.GetLastError(), "gdxDataWriteDone");
/*----------------------------------------------------------------------------*/
/* Write equilibrium points eq as a two-dimensional set into GDX file for
/* scenario-based tree notatio
/*----------------------------------------------------------------------------*/
87
A. Appendix
int g=1;
for(int e=1; e<= pow(nr_realizations,h); ++e) {
set[0] = scenario_vector[j-1];
set[1] = period_vector[h];
gdx.DataWriteStr(set, parameter);
j = j + pow(r,nr_periods-h-1);}
}
if (0==gdx.DataWriteDone())
gdxerror(gdx.GetLastError(), "gdxDataWriteDone");
/*----------------------------------------------------------------------------*/
/* Write offset pointers o(s,t) as a parameter for scenario-based
/* tree notation
/*----------------------------------------------------------------------------*/
if (0==gdx.DataWriteDone())
gdxerror(gdx.GetLastError(), "gdxDataWriteDone");
/*----------------------------------------------------------------------------*/
/* Write equilibrium-realization mapping str as a three-dimensional set
/* into GDX file for scenario-based tree notation
/*----------------------------------------------------------------------------*/
if (0==gdx.DataWriteStrStart("str","scenario-time-realization",3,GMS_DT_SET,0))
gdxerror(gdx.GetLastError(), "gdxDataWriteStrStart");
88
A.6. C++ Code Treegeneration tool
if (0==gdx.DataWriteDone())
gdxerror(gdx.GetLastError(), "gdxDataWriteDone");
/*----------------------------------------------------------------------------*/
if (gdx.Close())
gdxerror(gdx.GetLastError(), "gdxClose");
return 0;
}
/*----------------------------------------------------------------------------*/
/* The main function: Here we read in the time periods and realizations from
/* the gdx file and then call the function WriteTree to generate the
/* tree structure
/*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*/
// Here we specify the input parameters of the routine
if(argc == 4) {
gdxfile_input=argv[1];
gdxfile_output=argv[2];
temp_sysdir = argv[3];
cout << endl;
cout << "............................................" << endl;
cout << "Your Input file is: " << gdxfile_input << endl;
cout << "Your Output file is: " << gdxfile_output << endl;
cout << "Your GAMS working directory is: " << temp_sysdir << endl;
89
A. Appendix
if (str2[i] == \\)
{str2.insert(i, 1, \\);
i++;}
}
gdxfile_output = str2;
else {
cout << "Parameter specification incorrect" << endl;
exit(1);
}
/*----------------------------------------------------------------------------*/
// Create GAMS api objects
if (! gamsx.Init(sysdir, msg)) {
cout << "Could not create gamsx object: " << msg << endl;
return 1;}
if (! gdx.Init(sysdir, msg)) {
cout << "Could not create gdx object: " << msg << endl;
return 1;}
if (! opt.Init(sysdir, msg)) {
cout << "Could not create opt object: " << msg << endl;
return 1;}
/*----------------------------------------------------------------------------*/
/* Open the GDX input file and save the time periods, the realizations and
/* the probabilities in a vectors:
/*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*/
/* Read in the time_set from the GDX input file and save the time periods
/* in a vector called vector time_periods[]
/*----------------------------------------------------------------------------*/
90
A.6. C++ Code Treegeneration tool
VarName = "time_set";
if (0==gdx.FindSymbol(VarName, VarNr)) {
cout << "Could not find set >" << VarName << "<" << endl;
return 1;
}
if (0==gdx.DataReadStrStart(VarNr, NrRecs))
gdxerror(gdx.GetLastError(), "gdxDataReadStrStart");
nr_time = NrRecs;
vector <string> time_periods(nr_time);
for (int i=0; i<nr_time; ++i) {
gdx.DataReadStr(sp, v, NrRecs);
time_periods[i]=sp[0];
}
/*----------------------------------------------------------------------------*/
/* Read in the realization_set from the GDX input file and save the
/* realizations in a vector called realization_vector[]
/*----------------------------------------------------------------------------*/
VarName = "realization_set";
if (0==gdx.FindSymbol(VarName, VarNr)) {
cout << "Could not find set >" << VarName << "<" << endl;
return 1;
}
if (0==gdx.DataReadStrStart(VarNr, NrRecs))
gdxerror(gdx.GetLastError(), "gdxDataReadStrStart");
nr_realizations = NrRecs;
vector <string> realization_vector(nr_realizations);
for (int i=0; i<nr_realizations; ++i) {
gdx.DataReadStr(sp, v, NrRecs);
realization_vector[i]=sp[0];
}
gdx.DataReadDone();
/*----------------------------------------------------------------------------*/
/* Read in the parameter prob from the GDX input file and save the
/* probabilities in a vector called prob_vector[]
/*----------------------------------------------------------------------------*/
VarName = "prob";
91
A. Appendix
if (0==gdx.FindSymbol(VarName, VarNr)) {
cout << "Could not find set >" << VarName << "<" << endl;
return 1;
}
gdx.SymbolInfo(VarNr, VarName, dim, vartype);
if (1 != dim || GMS_DT_PAR != vartype) {
cout << VarName << " is not a one dimensional set" << endl;
return 1;
}
if (0==gdx.DataReadStrStart(VarNr, NrRecs))
gdxerror(gdx.GetLastError(), "gdxDataReadStrStart");
nr_realizations = NrRecs;
vector <long double> prob_vector(nr_realizations);
for (int i=0; i<nr_realizations; ++i) {
gdx.DataReadStr(sp, v, NrRecs);
prob_vector[i]= v[0];
}
gdx.DataReadDone();
if ((status=gdx.GetLastError()))
gdxerror(status, "GDX");
if (gdx.Close())
gdxerror(gdx.GetLastError(), "gdxClose");
/*----------------------------------------------------------------------------*/
/* Here we call the function WriteTree that generates the desired tree sets
/* and parameters
/*----------------------------------------------------------------------------*/
assert((start = clock())!=-1);
if ((status=WriteTree(gdxfile_output, nr_time, nr_realizations,
time_periods, realization_vector, prob_vector)))
stop = clock();
time1 = (double) (stop-start)/CLOCKS_PER_SEC;
cout << "Treegeneration finished, time elapsed: " << time1 << endl;
cout << "Returning to GAMS " << endl;
cout << "............................................" << endl;
cout << endl;
TERMINATE:
return status;
}
/*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*/
92
Bibliography
[4] Sion Grande Dixence SA. Grande-dixence - a legend in the heart of the
alps, 2011. Available online at http://www.grande-dixence.ch/.
[6] McCarl. Mccarl gams user guide. Website, 2011. Available online at
http://www.gams.com/dd/docs/bigdocs/gams2002/mccarlgamsuserguide.pdf
Chapter 15, page 536.
93
Bibliography
94