farm.gms : The Farmer's Problem formulated for DECIS

Description

This model helps a farmer to decide how to allocate
his or her land. The yields are uncertain.


Reference

  • Birge, J R, and Louveaux, F V, Introduction to Stochastic Programming. Springer, 1997.

Small Model of Types : DECIS lp


Category : GAMS Model library


Main file : farm.gms

$title The Farmer's Problem formulated for GAMS/DECIS (FARM,SEQ=199)

$onText
This model helps a farmer to decide how to allocate
his or her land. The yields are uncertain.


Birge, R, and Louveaux, F V, Introduction to Stochastic Programming.
Springer, 1997.

Keywords: linear programming, stochastic programming, agricultural cultivation,
          farming, cropping
$offText

$if not set decisalg $set decisalg decism

Set
   crop                                            / wheat, corn, sugarbeets /
   cropr(crop) 'crops required for feeding cattle' / wheat, corn             /
   cropx                                           / wheat
                                                     corn
                                                     beets1 'up to 6000 ton'
                                                     beets2 'in excess of 6000 ton' /;

Parameter
   yield(crop)       'tons per acre'               / wheat         2.5
                                                     corn          3
                                                     sugarbeets   20   /
   plantcost(crop)   'dollars per acre'            / wheat       150
                                                     corn        230
                                                     sugarbeets  260   /
   sellprice(cropx)  'dollars per ton'             / wheat       170
                                                     corn        150
                                                     beets1       36
                                                     beets2       10   /
   purchprice(cropr) 'dollars per ton'             / wheat       238
                                                     corn        210   /
   minreq(cropr)     'minimum requirements in ton' / wheat       200
                                                     corn        240   /;

Scalar
   land      'available land' /  500 /
   maxbeets1 'max allowed'    / 6000 /;

*--------------------------------------------------------------------------
* First a non-stochastic version
*--------------------------------------------------------------------------
Variable
   x(crop)    'acres of land'
   w(cropx)   'crops sold'
   y(cropr)   'crops purchased'
   yld(crop)  'yield'
   profit     'objective variable';

Positive Variable x, w, y;

Equation
   profitdef  'objective function'
   landuse    'capacity'
   req(cropr) 'crop requirements for cattle feed'
   ylddef     'calc yields'
   beets      'total beet production';

$onText
The YLD variable and YLDDEF equation isolate the stochastic
YIELD parameter into one equation, making the DECIS setup
somewhat easier than if we would substitute YLD out of
the model.
$offText

profitdef..    profit =e= - sum(crop,  plantcost(crop)*x(crop))
                       -    sum(cropr, purchprice(cropr)*y(cropr))
                       +    sum(cropx, sellprice(cropx)*w(cropx));

landuse..      sum(crop, x(crop)) =l= land;

ylddef(crop).. yld(crop) =e= yield(crop)*x(crop);

req(cropr)..   yld(cropr) + y(cropr) - sum(sameas(cropx,cropr),w(cropx)) =g= minreq(cropr);

beets..        w('beets1') + w('beets2') =l= yld('sugarbeets');

w.up('beets1') = maxbeets1;

Model simple / profitdef, landuse, req, beets, ylddef /;

solve simple using lp maximizing profit;

*--------------------------------------------------------------------------
* Extensive form stochastic model
* This is a standard LP.
*--------------------------------------------------------------------------
Set s 'scenarios' / above, avg, below /;

Variable
   ws(cropx, s) 'crops sold under scenario s'
   ys(cropr, s) 'crops purchased under scenario s';

Positive Variable ws, ys;

Parameter p(s) 'probability';
p(s) = 1/3;

abort$(abs(sum(s,p(s)) - 1.0) > 0.001) "probabilities don't add up";

Parameter syield(crop,s);
syield(crop,'below') = 0.8*yield(crop);
syield(crop,'avg')   =     yield(crop);
syield(crop,'above') = 1.2*yield(crop);

Equation
   sprofitdef    'objective function extensive form stochastic model'
   sreq(cropr,s)
   sbeets(s);

sprofitdef..    profit =e= - sum(crop, plantcost(crop)*x(crop))
                           + sum(s, p(s)*(- sum(cropr, purchprice(cropr)*ys(cropr,s))
                                          + sum(cropx, sellprice(cropx)*ws(cropx,s))));

sreq(cropr,s)..    syield(cropr,s)*x(cropr) + ys(cropr,s)
                -  sum(sameas(cropx,cropr),ws(cropx,s))
               =g= minreq(cropr);

sbeets(s)..    ws('beets1',s) + ws('beets2',s) =l= syield('sugarbeets',s)*x('sugarbeets');

ws.up('beets1',s) = maxbeets1;

Model extform / sprofitdef, landuse, sreq, sbeets /;

solve extform using lp maximizing profit;

* collect results for x for different runs
Set runs / extform      'extensive form'
           decisapprox  'default decis'
           decisexact   'stochastic universe option' /;

Parameter px(runs,crop) 'results for stage 1 variables';

* store stage 1 results
px('extform',crop) = x.l(crop);

*--------------------------------------------------------------------------
* Default DECIS setup
* Based upon the non-stochastic (core) model.
*--------------------------------------------------------------------------

* output the stochastic file
File stg / MODEL.STG /;
stg.nd = 8;
put stg;
put 'BLOCKS DISCRETE'/;
loop(s,
   put 'BL BLOCK1 PERIOD2 ',p(s)/;
   loop(crop, put 'x ', crop.tl,' ylddef ', crop.tl,' ', (-syield(crop,s))/;);
);
putClose;

$onText
Notice the (-yield) expression in for the coefficient for x in
equation ylddef. The row listing for YLDDEF shows that the expression
yield(crop)*x(crop) is moved by GAMS to the left-hand side causing a
minus sign. The parentheses are needed as the PUT syntax does
not allow expressions there.
$offText

* output a MINOS option file
File mopt / MINOS.SPC /;
put  mopt;
put "begin"/;
put "rows 250"/;
put "columns 250"/;
put "elements 10000"/;
put "end"/;
putClose;

* assign stages
x.stage(cropr)     = 1;
y.stage(cropr)     = 2;
w.stage(cropx)     = 2;
yld.stage(crop)    = 2;
landuse.stage      = 1;
ylddef.stage(crop) = 2;
req.stage(cropr)   = 2;
beets.stage        = 2;

option lp = %decisalg%;

solve simple using lp maximizing profit;

* store stage 1 results
px('decisapprox',crop) = x.l(crop);

*--------------------------------------------------------------------------
* Let DECIS solve the model exactly
* Stochastic Universe option: 4 "ISTRAT"
*--------------------------------------------------------------------------
File decopt / %decisalg%.opt /;
put  decopt;
put '4 "ISTRAT"'/;
putClose;

simple.optFile = 1;

solve simple using lp maximizing profit;

* store stage 1 results
px('decisexact',crop) = x.l(crop);

display px;