rev |
line source |
alpar@9
|
1 # Model I Forest Estate Modelling using GLPK/MathProg
|
alpar@9
|
2 # Reading and writing dbf files
|
alpar@9
|
3
|
alpar@9
|
4 # by Noli Sicad --- nsicad@gmail.com
|
alpar@9
|
5 # 18 December 2009
|
alpar@9
|
6
|
alpar@9
|
7 # Forest Management 4th Edition
|
alpar@9
|
8 # by Lawrence Davis, K. Norman Johnson, Pete Bettinger, Theodore Howard
|
alpar@9
|
9 # Chapter 11 - Daniel Pickett
|
alpar@9
|
10 # http://warnell.forestry.uga.edu/Warnell/Bettinger/mgtbook/index.htm
|
alpar@9
|
11
|
alpar@9
|
12 # Model I Formulation
|
alpar@9
|
13
|
alpar@9
|
14 /* Note: This is not the full LP model mentioned in the book.
|
alpar@9
|
15 Some of the constraints are deliberately omitted in this model for the purpose of clarity.
|
alpar@9
|
16
|
alpar@9
|
17 The features of MathProg in this example are:
|
alpar@9
|
18 * reading and writing dbf from regular dbf files,
|
alpar@9
|
19 * reading dbf file (database of shapefile (stands.shp)) (e.g. area parameter),
|
alpar@9
|
20 * using the area data in the constraints and
|
alpar@9
|
21 * writing dbf file from result of LP model.
|
alpar@9
|
22
|
alpar@9
|
23 Model I - Harvest Scheduling formulation for Sustainable Forest Management (SFM)
|
alpar@9
|
24
|
alpar@9
|
25 Features are:
|
alpar@9
|
26 * Net Present Value for the objective function (Revenue - Cost)
|
alpar@9
|
27 * Harvest Constraints by period - Sustainable Yield per Period
|
alpar@9
|
28 * Even-Flow Constraint / Volume - Harvest Flow Constraint - Alpha (1-Apha)
|
alpar@9
|
29 * Even-Flow Constraint / Volume - Harvest Flow Constraint - Beta (1 +Beta)
|
alpar@9
|
30 * Forest / Land Constraint -- Total Area of the forest
|
alpar@9
|
31 * Forest Stand Constraint -- Individual stands
|
alpar@9
|
32
|
alpar@9
|
33 What is next? -- Forest Mgt Carbon Accounting for Climate Change
|
alpar@9
|
34
|
alpar@9
|
35 Note: The model file that the data containing in
|
alpar@9
|
36 the dbf files is public domain material (so it is compatible with the
|
alpar@9
|
37 GNU GPL) and data can be found in
|
alpar@9
|
38 http://warnell.forestry.uga.edu/Warnell/Bettinger/mgtbook/index.htm
|
alpar@9
|
39
|
alpar@9
|
40 # Noli Sicad --- nsicad@gmail.com
|
alpar@9
|
41
|
alpar@9
|
42 */
|
alpar@9
|
43
|
alpar@9
|
44 set G_STAND_TYPE; # A, B, C
|
alpar@9
|
45
|
alpar@9
|
46 set I_CULTURAL_PRES;
|
alpar@9
|
47 set J_MGT_YEAR;
|
alpar@9
|
48
|
alpar@9
|
49 param K_PERIOD;
|
alpar@9
|
50 param Forest_Cost{G_STAND_TYPE,I_CULTURAL_PRES, J_MGT_YEAR}; # cost
|
alpar@9
|
51
|
alpar@9
|
52 param Yield_Table_Vol{G_STAND_TYPE, I_CULTURAL_PRES, J_MGT_YEAR, 1..K_PERIOD} >= 0;
|
alpar@9
|
53
|
alpar@9
|
54
|
alpar@9
|
55 param Alpha >= 0;
|
alpar@9
|
56 param Beta >= 0;
|
alpar@9
|
57
|
alpar@9
|
58 param TCost_Table{G_STAND_TYPE, I_CULTURAL_PRES, J_MGT_YEAR, 1..K_PERIOD} >= 0;
|
alpar@9
|
59
|
alpar@9
|
60 param NetRev_Table{G_STAND_TYPE, I_CULTURAL_PRES, J_MGT_YEAR, 1..K_PERIOD};
|
alpar@9
|
61
|
alpar@9
|
62
|
alpar@9
|
63 var XForestLand{g in G_STAND_TYPE, i in I_CULTURAL_PRES, j in J_MGT_YEAR} >= 0;
|
alpar@9
|
64
|
alpar@9
|
65
|
alpar@9
|
66 #reading dbf tables
|
alpar@9
|
67 table tab IN "xBASE" "standtype.dbf": G_STAND_TYPE <- [STAND];
|
alpar@9
|
68 display G_STAND_TYPE;
|
alpar@9
|
69
|
alpar@9
|
70
|
alpar@9
|
71 table tab2 IN "xBASE" "cultural_pres.dbf": I_CULTURAL_PRES <- [CUL_PRES];
|
alpar@9
|
72 display I_CULTURAL_PRES;
|
alpar@9
|
73
|
alpar@9
|
74 table tab3 IN "xBASE" "mgt_year.dbf": J_MGT_YEAR <- [MGT_YEAR];
|
alpar@9
|
75 display J_MGT_YEAR;
|
alpar@9
|
76
|
alpar@9
|
77 /*
|
alpar@9
|
78 param Forest_Cost{G_STAND_TYPE,I_CULTURAL_PRES, J_MGT_YEAR} default 0; # cost
|
alpar@9
|
79 */
|
alpar@9
|
80
|
alpar@9
|
81 set S1, dimen 3;
|
alpar@9
|
82 table tab4 IN "xBASE" "Forest_Cost.dbf": S1 <- [STAND, CUL_PRES, MGT_YEAR],Forest_Cost ~FCOST;
|
alpar@9
|
83 display Forest_Cost;
|
alpar@9
|
84
|
alpar@9
|
85 set S2, dimen 4;
|
alpar@9
|
86 table tab5 IN "xBASE" "Yield_Table_Vol.dbf": S2 <- [STAND, CUL_PRES, MGT_YEAR, PERIOD],Yield_Table_Vol ~YIELD;
|
alpar@9
|
87 display Yield_Table_Vol;
|
alpar@9
|
88
|
alpar@9
|
89 set S3, dimen 4;
|
alpar@9
|
90 table tab5 IN "xBASE" "TCost_Table.dbf": S3 <- [STAND, CUL_PRES, MGT_YEAR, PERIOD],TCost_Table ~TCOST;
|
alpar@9
|
91 display TCost_Table;
|
alpar@9
|
92
|
alpar@9
|
93
|
alpar@9
|
94 set S4, dimen 4;
|
alpar@9
|
95 table tab5 IN "xBASE" "NetRev_Table.dbf": S4 <- [STAND, CUL_PRES, MGT_YEAR, PERIOD],NetRev_Table ~NETREV;
|
alpar@9
|
96 display NetRev_Table;
|
alpar@9
|
97
|
alpar@9
|
98
|
alpar@9
|
99 param MGT;
|
alpar@9
|
100
|
alpar@9
|
101 param Area_Stand_Indi{g in G_STAND_TYPE, m in 1..MGT} default 0;
|
alpar@9
|
102
|
alpar@9
|
103 set ST, dimen 2;
|
alpar@9
|
104 table tab5 IN "xBASE" "stands.dbf": ST <- [VEG_TYPE, MGT], Area_Stand_Indi ~ACRES;
|
alpar@9
|
105 display Area_Stand_Indi;
|
alpar@9
|
106
|
alpar@9
|
107 param Area_Stand_Type{g in G_STAND_TYPE}:= sum {m in 1..MGT } Area_Stand_Indi[g,m];
|
alpar@9
|
108 display Area_Stand_Type;
|
alpar@9
|
109
|
alpar@9
|
110
|
alpar@9
|
111 param Total_Area := sum {g in G_STAND_TYPE, m in 1..MGT } Area_Stand_Indi[g,m];
|
alpar@9
|
112 display Total_Area;
|
alpar@9
|
113
|
alpar@9
|
114 param Harvest_Min_Vol_Period;
|
alpar@9
|
115
|
alpar@9
|
116
|
alpar@9
|
117 var NetPresentValue;
|
alpar@9
|
118
|
alpar@9
|
119 # Objective function
|
alpar@9
|
120 maximize Net_Present_Value: NetPresentValue;
|
alpar@9
|
121
|
alpar@9
|
122 subject to NPV:
|
alpar@9
|
123 NetPresentValue = sum {g in G_STAND_TYPE, i in I_CULTURAL_PRES, j in J_MGT_YEAR} Forest_Cost[g,i,j] * XForestLand[g,i,j];
|
alpar@9
|
124
|
alpar@9
|
125 # Harvest Constraint by Period
|
alpar@9
|
126 subject to Harvest_Period_H {k in 1..K_PERIOD}:
|
alpar@9
|
127 sum {g in G_STAND_TYPE, i in I_CULTURAL_PRES, j in J_MGT_YEAR} Yield_Table_Vol[g,i,j,k] * XForestLand[g,i,j] >= Harvest_Min_Vol_Period;
|
alpar@9
|
128
|
alpar@9
|
129
|
alpar@9
|
130 #Even-Flow Constraint / Volume - Harvest Flow Constraint - Alpha
|
alpar@9
|
131 subject to Even_Flow_Constaints_Alpha {k in 6..K_PERIOD-1}:
|
alpar@9
|
132 (1 - Alpha) * sum {g in G_STAND_TYPE, i in I_CULTURAL_PRES, j in J_MGT_YEAR} Yield_Table_Vol[g,i,j,k] * XForestLand[g,i,j] -
|
alpar@9
|
133 sum {g in G_STAND_TYPE,i in I_CULTURAL_PRES, j in J_MGT_YEAR} Yield_Table_Vol[g,i,j,k+1] * XForestLand[g,i,j] <= 0;
|
alpar@9
|
134
|
alpar@9
|
135 # Even-Flow Constraint / Volume - Harvest Flow Constraint - Beta
|
alpar@9
|
136 subject to Even_Flow_Constaints_Beta {k in 6..K_PERIOD-1}:
|
alpar@9
|
137 (1 + Beta) * sum {g in G_STAND_TYPE, i in I_CULTURAL_PRES, j in J_MGT_YEAR} Yield_Table_Vol[g,i,j,k] * XForestLand[g,i,j] -
|
alpar@9
|
138 sum {g in G_STAND_TYPE,i in I_CULTURAL_PRES, j in J_MGT_YEAR} Yield_Table_Vol[g,i,j,k+1] * XForestLand[g,i,j] >= 0;
|
alpar@9
|
139
|
alpar@9
|
140 # Forest / Land Constraints
|
alpar@9
|
141 subject to Total_Area_Constraint:
|
alpar@9
|
142 sum {g in G_STAND_TYPE, i in I_CULTURAL_PRES, j in J_MGT_YEAR} XForestLand[g,i,j] <= Total_Area;
|
alpar@9
|
143 display Total_Area;
|
alpar@9
|
144
|
alpar@9
|
145 # Forest / Land Constraints for A B C
|
alpar@9
|
146 subject to Area {g in G_STAND_TYPE}:
|
alpar@9
|
147 sum {i in I_CULTURAL_PRES,j in J_MGT_YEAR} XForestLand[g,i,j] = Area_Stand_Type[g];
|
alpar@9
|
148
|
alpar@9
|
149
|
alpar@9
|
150
|
alpar@9
|
151 solve;
|
alpar@9
|
152 #RESULT SECTION
|
alpar@9
|
153 printf '#################################\n';
|
alpar@9
|
154 printf 'Forest Management Model I - Noli Sicad\n';
|
alpar@9
|
155 printf '\n';
|
alpar@9
|
156 printf 'Net Present Value = %.2f\n', NetPresentValue;
|
alpar@9
|
157 printf '\n';
|
alpar@9
|
158
|
alpar@9
|
159 printf '\n';
|
alpar@9
|
160 printf 'Variables\n';
|
alpar@9
|
161 printf 'Stand_Type Age_Class Mgt_Presc Sign Value \n';
|
alpar@9
|
162 printf{g in G_STAND_TYPE, i in I_CULTURAL_PRES, j in J_MGT_YEAR}:'%5s %10s %11s = %10.2f\n', g,i,j, XForestLand[g,i,j];
|
alpar@9
|
163 printf '\n';
|
alpar@9
|
164
|
alpar@9
|
165 printf 'Constraints\n';
|
alpar@9
|
166 printf 'Period Harvest Sign \n';
|
alpar@9
|
167 for {k in 1..K_PERIOD} {
|
alpar@9
|
168 printf '%5s %10.2f >= %.3f\n', k, sum {g in G_STAND_TYPE, i in I_CULTURAL_PRES, j in J_MGT_YEAR} Yield_Table_Vol[g,i,j,k] * XForestLand[g,i,j], Harvest_Min_Vol_Period;
|
alpar@9
|
169 }
|
alpar@9
|
170
|
alpar@9
|
171 # xbase (dbf) output
|
alpar@9
|
172 table Harvest{k in 1..K_PERIOD} OUT "xBASE" "HarvestArea1.dbf" "N(5)N(15,2)" : k ~ Period, (sum {g in G_STAND_TYPE, i in I_CULTURAL_PRES, j in J_MGT_YEAR} Yield_Table_Vol[g,i,j,k] * XForestLand[g,i,j]) ~ H_Area;
|
alpar@9
|
173
|
alpar@9
|
174 # xbase (dbf) read
|
alpar@9
|
175 set S, dimen 2;
|
alpar@9
|
176 table tab2 IN "xBASE" "HarvestArea1.dbf": S <- [Period, H_Area];
|
alpar@9
|
177 display S;
|
alpar@9
|
178
|
alpar@9
|
179
|
alpar@9
|
180
|
alpar@9
|
181
|
alpar@9
|
182 printf '\n';
|
alpar@9
|
183 printf 'Constraint\n';
|
alpar@9
|
184 printf 'Harvest Period\n';
|
alpar@9
|
185 printf 'Type AgeClass PrescMgt Period Value\n';
|
alpar@9
|
186 printf{g in G_STAND_TYPE, i in I_CULTURAL_PRES, j in J_MGT_YEAR, k in 1..K_PERIOD}:'%5s %11s %11s %5s %10.2f\n', g,i,j, k, (Yield_Table_Vol[g,i,j,k] * XForestLand[g,i,j]);
|
alpar@9
|
187
|
alpar@9
|
188
|
alpar@9
|
189 printf 'Even_Flow_Constaint_Alpha (1-Alpha)\n';
|
alpar@9
|
190 printf 'Period Sign \n';
|
alpar@9
|
191 for {k in 6..K_PERIOD-1} {
|
alpar@9
|
192 printf "%s %10.2f <= %s\n", k, ((1 - Alpha) * sum {g in G_STAND_TYPE, i in I_CULTURAL_PRES, j in J_MGT_YEAR} Yield_Table_Vol[g,i,j,k] * XForestLand[g,i,j] - sum {g in G_STAND_TYPE,i in I_CULTURAL_PRES, j in J_MGT_YEAR} Yield_Table_Vol[g,i,j,k+1] * XForestLand[g,i,j]),0;
|
alpar@9
|
193 }
|
alpar@9
|
194 printf '\n';
|
alpar@9
|
195
|
alpar@9
|
196
|
alpar@9
|
197 # Forest / Land Constraints
|
alpar@9
|
198 printf '\n';
|
alpar@9
|
199 printf 'Total Area Constraint\n';
|
alpar@9
|
200 printf 'Type AgeClass PrescMgt Value Sign Total_Area \n';
|
alpar@9
|
201 printf '%5s <= %.3f\n',sum {g in G_STAND_TYPE, i in I_CULTURAL_PRES, j in J_MGT_YEAR} XForestLand[g,i,j], Total_Area;
|
alpar@9
|
202
|
alpar@9
|
203 printf 'Area\n';
|
alpar@9
|
204 printf 'Area Value Sign Areas_Stand\n';
|
alpar@9
|
205 for {g in G_STAND_TYPE} {
|
alpar@9
|
206 printf '%5s %10.2f <= %.3f\n', g, sum {i in I_CULTURAL_PRES,j in J_MGT_YEAR} XForestLand[g,i,j], Area_Stand_Type[g];
|
alpar@9
|
207 }
|
alpar@9
|
208
|
alpar@9
|
209
|
alpar@9
|
210 #DATA SECTION
|
alpar@9
|
211
|
alpar@9
|
212 data;
|
alpar@9
|
213
|
alpar@9
|
214 # Most of the data has been moved to dbf format
|
alpar@9
|
215
|
alpar@9
|
216 param MGT:=31;
|
alpar@9
|
217
|
alpar@9
|
218 param K_PERIOD:= 7;
|
alpar@9
|
219
|
alpar@9
|
220 param Alpha:= 0.20;
|
alpar@9
|
221 param Beta:= 0.20;
|
alpar@9
|
222
|
alpar@9
|
223 param Harvest_Min_Vol_Period:= 12000;
|
alpar@9
|
224
|
alpar@9
|
225 end;
|
alpar@9
|
226
|