srkandw.gms : Stochastic Programming Scenario Reduction

**Description**

A refinery can blend raw materials into different products. At present, the management is trying to decide how much of each of the raw materials to purchase and stock, so that they can be blended to satisfy the demand for the products in future time periods. The demand has to be completely satisfied, and in case of raw material shortage the products can be outsourced at a higher cost. There is an inventory constraint on how much raw material can be stocked in total. Kall, P, and Wallace, S W, Stochastic Programming. John Wiley and Sons, Chichester, England, 1994.

**Reference**

- Kall, P, and Wallace, S W, Stochastic Programming. John Wiley and Sons, Chichester, England, 1994.

**Small Model of Type :** LP

**Category :** GAMS Model library

**Main file :** srkandw.gms

$Title Stochastic Programming Scenario Reduction (SRKANDW,SEQ=248) $ontext A refinery can blend raw materials into different products. At present, the management is trying to decide how much of each of the raw materials to purchase and stock, so that they can be blended to satisfy the demand for the products in future time periods. The demand has to be completely satisfied, and in case of raw material shortage the products can be outsourced at a higher cost. There is an inventory constraint on how much raw material can be stocked in total. Kall, P, and Wallace, S W, Stochastic Programming. John Wiley and Sons, Chichester, England, 1994. $offtext sets i raw materials / raw-1, raw-2 / j products / p-1,p-2 / t time periods / time-1, time-2 / n nodes / n-0*n-12 /; alias(n,nn); Parameters c(i) present cost of raw materials / raw-1 2, raw-2 3/; table a(j,i) yields raw-1 raw-2 p-1 2 6 p-2 3 3.4 ; table f(j,t) cost of outsourcing time-1 time-2 p-1 7 10 p-2 12 15 ; scalar b inventory capacity / 50 /; table stdat(n,*) scenario tree data prob p-1 p-2 n-1 .3 200 180 n-2 .4 180 160 n-3 .3 160 140 n-4 .2 200 180 n-5 .5 180 160 n-6 .3 160 140 n-7 .3 200 180 n-8 .4 180 160 n-9 .3 160 140 n-10 .4 200 180 n-11 .4 180 160 n-12 .2 160 140 ; set tn(t,n) time node mapping / time-1.(n-1*n-3), time-2.(n-4*n-12) /, tree(n,n) / n-0.(n-1*n-3), n-1.(n-4*n-6), n-2.(n-7*n-9), n-3.(n-10*n-12) /; set sn(n) 'subset of nodes in reduced subtree', leaf(n) 'leaf nodes in original tree'; leaf(n)$[sum{tn('time-2',n), 1}] = YES; display leaf; parameter dem(j,n) stochastic demand prob(n) node probability sprob(n) node probability in reduced tree; dem(j,n) = stdat(n,j); prob('n-0') = 1; prob(n)$tn('time-1',n) = stdat(n,'prob'); prob(n)$tn('time-2',n) = sum(tree(nn,n), stdat(nn,'prob')*stdat(n,'prob')); display prob; variables x(i,t) raw material purchased for use in time t y(j,t,n) outsourced products cost positive variables x,y; equations obj total cost definition bal purchase limit dembal(j,t,n) demand balance; obj.. cost =e= sum((i,t), c(i)*x(i,t)) + sum((j,tn(t,sn)), sprob(sn)*f(j,t)*y(j,tn)); bal.. sum((i,t), x(i,t)) =l= b; dembal(j,tn(t,sn)).. sum(i, a(j,i)*x(i,t)) + y(j,tn) =g= dem(j,sn); * In order to use the SPOSL system we need to insert some dummy links * between stages two and three. Without these links, the SPOSL system will * identify only a two stage problem with different subproblem structures. * The value EPS is used to insert a constraint entry with numerical values * of zero. equation dembalx(j,t,n) demand balance modified to include back link; dembalx(j,tn(t,sn)).. sum(i, a(j,i)*x(i,t)) + y(j,tn) =g= dem(j,sn) + eps*sum(tree(nn,sn), y(j,t-1,nn)); model srkandw / obj, bal, dembalx /; $if set noscenred $goto noscenreduction * now we prepare to run ScenRed * this includes some sets & parameters used for scenred I/O $libinclude scenred2.gms scalar psum, rc, runCount, runMax; set run / run1 * run9 /; set method 'reduction method used' / '0-default', '1-fastback', '2-fastback+forw', '3-fastback+back' /; parameter report(method,run,*); set rleaf(method,run,n) 'leaf set of reduced tree'; runMax = INF; $if set runmax runMax = %runmax%; ScenRedParms('report_level') = 0; runCount = 0; loop {method$(runCount < runMax), ScenRedParms('reduction_method') = ord(method)-1; loop {run$(runCount < runMax), * these parms control the tree output from ScenRed * at least one of the following two parameters is required ScenRedParms('red_num_leaves') = ord(run); * ScenRedParms('red_percentage') = 0.5; $libinclude runscenred2 kandw scen_red n tree prob na sprob dem sn(n) = sprob(n); display ScenRedParms, ScenRedReport; display sprob, sn; psum = sum {leaf(sn), sprob(sn)}; abort$[abs(psum-1) gt 1e-8] "Error in reduced tree: leaf probabilities do not sum to 1"; solve srkandw min cost us lp; runCount = runCount + 1; report(method,run, 'obj') = srkandw.objval; report(method,run, 'red_percentage') = ScenRedReport('red_percentage'); report(method,run, 'reduction_method') = ScenRedReport('reduction_method'); report(method,run, 'run_time') = ScenRedReport('run_time'); rleaf (method,run, leaf(sn)) = YES; }; }; display report; display rleaf; $ontext * experiment with a different strategy here * set the desired reduction in terms of distance, not the size * also, there's really no need to dump the original tree more than once ScenRedParms('red_num_leaves') = 0; parameter report2(method,run,*); set rleaf2(method,run,n) 'leaf set of reduced tree'; runCount = 0; loop {method$(runCount < runMax), ScenRedParms('reduction_method') = ord(method)-1; loop {run$((runCount < runMax) and (ord(run) <= 5)), ScenRedParms('red_percentage') = ord(run)/4; $libinclude runscenred2 kandw scen_red n tree prob na sprob dem sn(n) = sprob(n); display ScenRedParms, ScenRedReport; display sprob, sn; psum = sum {leaf(sn), sprob(sn)}; abort$[abs(psum-1) gt 1e-8] "Error in reduced tree: leaf probabilities do not sum to 1"; solve srkandw min cost us lp; runCount = runCount + 1; report2(method,run, 'obj') = srkandw.objval; report2(method,run, 'red_percentage') = ScenRedReport('red_percentage'); report2(method,run, 'red_leaves') = ScenRedReport('red_leaves'); report2(method,run, 'reduction_method') = ScenRedReport('reduction_method'); report2(method,run, 'run_time') = ScenRedReport('run_time'); rleaf2 (method,run, leaf(sn)) = YES; }; }; display report2; display rleaf2; $offtext $goto alldone $label noscenreduction * set "reduced tree" to be the whole tree sn(n) = yes; sprob(n) = prob(n); solve srkandw min cost us lp; $label alldone