farmnbd.gms : The Farmer's Problem - Stochastic with NBD

Description

This model helps a farmer to decide how to allocate
his or her land. The yields are uncertain. Here we use
Lindo NBD algorithm and need to modify the model since
Lindo's NDB algorithm requires that a RV occurs only once
in the model.


Small Model of Type : SP


Category : GAMS EMP library


Main file : farmnbd.gms

$title The Farmer's Problem - Stochastic with NBD (FARMNDB,SEQ=100)
$onText

This model helps a farmer to decide how to allocate
his or her land. The yields are uncertain. Here we use
Lindo NBD algorithm and need to modify the model since
Lindo's NDB algorithm requires that a RV occurs only once
in the model.


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

Contributor: Michael Ferris
$offText

* Only run for Lindo
$ifI not "%gams.emp%"=="lindo" $exit

Set crop  / wheat, corn, sugarbeets /
    ch    header for data table /
           yield  yield in tons per acre
           cost   plantcost on dollars per acre
           pprice crop seed purchase price in dollars per ton
           minreq minimum requirements of crop in ton to feed cattle /
alias (c,crop);

Table cd(crop,ch) crop data
           yield   cost  pprice  minreq
wheat        2.5    150     238     200
corn         3      230     210     240
sugarbeets  20      260
;

Parameter
   yf(crop)     yield factor / #crop 1 /
   land   available land in acres /500/;

Set seq price curve segments / s1*s2 /;
Table pricecurve(crop,seq,*) dollars per ton
              price     ub
wheat.s1        170    inf
corn.s1         150    inf
sugarbeets.s1    36   6000
sugarbeets.s2    10    inf
;
set pcs(crop,seq) relevant segments; option pcs<pricecurve;

set errorPC(crop) price curve is not concave;
errorPC(c) = smin(pcs(c,seq), pricecurve(c,seq,'price')-pricecurve(c,seq+1,'price'))<0;
abort$card(errorPC) errorPC;

Variables
   x(c)     crop planted in acres of land
   w(c,seq) crops sold in segment of cost curve in tons
   y(c)     crops purchased in tons
   profit   objective variable in dollars;
Positive variables x,w,y;

Equations
  profitdef  objective function
  landuse    capacity
  bal(c)     crop balance;

profitdef..    profit =e= sum(pcs, w(pcs)*pricecurve(pcs,'price'))
                        - sum(c, cd(c,'cost')*x(c) + cd(c,'pprice')*y(c));

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

bal(c)..       yf(c)*cd(c,'yield')*x(c) + y(c) - sum(pcs(c,seq), w(pcs)) =g= cd(c,'minreq');

* No purchase of crops that don't have a purchase price
y.fx(c)$(cd(c,'pprice')=0) = 0;
w.up(pcs) = pricecurve(pcs,'ub');

model farm_emp /all/;

Set s            scenarios / s1*s3 /;
parameter probab(s) / s1 0.25, s2 0.50, s3 0.25 /;
parameter yfac(s) / s1 0.8, s2 1.0, s3 1.2 /;

file emp / '%emp.info%' /; put emp '* problem %gams.i%'/;
put 'jrandvar ';
loop(c, put yf.tn(c); );
put /;
loop(s, put probab(s);
  loop(c, put yfac(s));
  put /;
);
putclose 'stage 2 yf y w bal profit';

Parameter
    srep(s,*)    scenario attributes / #s.prob 0 /
    s_yf(s,c)    yield factor realization by scenario and crop
    s_profit(s)  profit by scenario
    s_w(s,c,seq) crops sold in segment of cost curve in tons by scenario
    s_y(s,c)     crops purchased in tons by scenario;

Set dict / s     .scenario.''
           ''    .opt.     srep
           yf    .randvar. s_yf
           profit.level.   s_profit
           w     .level.   s_w
           y     .level.   s_y /;

farm_emp.optcr = 1e-6;
farm_emp.optca = 1e-2;

* The first two options will select the NBD algorithm within Lindo
* The NBD algorithm has the requirement that a random variable can only
* occur once. Otherwise Lindo issues the following message and terminates:
* *** Lindo does not allow multiple occurrences of one RV with NBD method
* Therefore, we have replaced the RV yf (yield factor) that occured in the
* bal equation for every crop c by a a set of joined RV yf(c). The original
* model with a single RV is captured in farmsp.

$onEcho > lindo.opt
STOC_MAP_MPI2LP 1
STOC_METHOD 1
STOC_CALC_EVPI 0
$offEcho

option emp = lindo;
farm_emp.optfile = 1;
solve farm_emp using emp maximizing profit scenario dict;

display srep, s_yf;