$title Long Range Forest Planning (STOCFOR3,SEQ=87) $onText The job of a long range forest planner is to decide what parts of the forest will be harvested when. Important criteria for such a decision are the age of the trees, and the likelihood that trees left standing will be destroyed by fire. Gassmann creates a set of K age classifications of equal length (e.g. 20 years), and places each portion of the forest into one of the classes, according to the age of the trees within. He also divides the future planning horizon into T rounds, each with a time length equal to that of each age classification. That is, in one time round, any trees that are not destroyed or harvested will move to the next age class. Gassmann, H I, Optimal harvest of a forest in the presence of uncertainty. Canadian Journal of Forest Research, 19, 1267-1274, 1989 Ariyawansa, K A, and Felt, A J, On a New Collection of Stochastic Linear Programming Test Problems, INFORMS Journal on Computing 16(3), 291-299, 2004 $offText Set t time steps / t1*t7 / k age class / c1*c8 / kn(k) age class that is not harvested / c1,c2 / Alias (k,kk) Parameter d(t) discouting rate dlast discouting rate after last period f(t) probability of fire / #t 0.06258 / a /0.9/, b limit on change from period to period / 1.1 / p penalty for violating limit for yield change / 50 / si(k) area of forest in first period / c1 0.241, c2 0.125, c3 1.404, c4 2.004 c5 9.768, c6 16.385, c7 2.815, c8 61.995 / y(k) yield / c1 0, c2 0, c3 16, c4 107 c5 217, c6 275, c7 298, c8 306 / v(k) value / c1 320.342, c2 356.187, c3 398.437, c4 448.235 c5 506.929, c6 564.929, c7 587.929, c8 595.929 /; * 20 years and 0.005 inflation d(t) = (1-0.004975124)**(20*(ord(t)-1)); dlast = (1-0.004975124)**(20*card(t)); Variables obj objective x(t,k) harvested forest s(t,k) area of forest rf(t,k) remaining forest z(t) yield slack(t) slack for violating defchglo Positive variables x, s, rf, slack; Equations defobj objective defbnd(t,k) limit harvest by area defbal(t,k) material balance defyield(t) yield defchglo(t) limit change on yield defchgup(t) limit change on yield; defobj.. obj =e= sum(t, d(t)*(z(t) - p*slack(t))) + dlast*sum(k, v(k)*rf('t7',k)); defbnd(t,k).. rf(t,k) =e= s(t,k) - x(t,k); defbal(t-1,k).. s(t,k) =e= (1-f(t))*(rf(t-1,k-1) + rf(t-1,k)$sameas('c8',k)) + sum(kk, x(t-1,kk) + f(t)*rf(t-1,kk))$sameas(k,'c1'); defyield(t).. z(t) =e= sum(k, y(k)*x(t,k)); defchglo(t-1).. a*z(t-1) =l= z(t) + slack(t-1); defchgup(t-1).. b*z(t-1) =g= z(t); model forest /all/; s.fx('t1',k) = si(k); x.fx(t,kn) = 0; file emp / '%emp.info%' /; put emp '* problem %gams.i%' /; $onPut randvar f('t2') discrete .1736 .00000 .0299 .20268 .5128 .06258 .2837 .08612 randvar f('t3') discrete .1736 .00000 .0299 .20268 .5128 .06258 .2837 .08612 randvar f('t4') discrete .1736 .00000 .0299 .20268 .5128 .06258 .2837 .08612 randvar f('t5') discrete .6912 .00000 .3088 .20268 randvar f('t6') discrete .6912 .00000 .3088 .20268 randvar f('t7') discrete .6912 .00000 .3088 .20268 $offPut loop(t$(ord(t)>1), put / 'stage ' ord(t):2:0 z(t) slack(t-1) defyield(t) defchglo(t-1) defchgup(t-1); loop(k, put x(t,k) s(t,k) rf(t,k) defbnd(t,k) defbal(t-1,k))); emp.pc=0; loop(t$(ord(t)>1), put / 'stage ' ord(t):2:0 ' f(' t.tl:0 ')'); putclose; Set scen scenarios / s1*s512 /; Parameter s_f(scen,t) probability of fire by scenario; Set dict / scen .scenario.'' f .randvar. s_f /; solve forest max obj using emp scenario dict;