Skip to content

Instantly share code, notes, and snippets.

@trialsolution
Created October 31, 2012 11:59
Show Gist options
  • Save trialsolution/3986673 to your computer and use it in GitHub Desktop.
Save trialsolution/3986673 to your computer and use it in GitHub Desktop.
EV frontier analysis for a simple farm management problem
$ontext
PROBLEM STATMENT
EV analysis from Hazell-Norton
AIM: draw the EV-frontier for the following farm planning problem
MODEL 1. EXPECTED PROFIT MAXIMIZATION (farm with fixed land, 4 crops, fixed labour and a rotational constraint)
expected margin 253 443 284 516 [maximize]
land 1 1 1 1 [<=200]
labor 25 36 27 87 [<=10000]
rotational const -1 1 -1 1 [<=0]
MODEL 2. minimize risk at a given level of total expected gross margins
for that we need an estimate for the covariance matrix of crop gross margins
use the time-series below
gross margins (/ha)
year1 292 -128 420 579
2 179 560 187 639
3 114 648 366 379
4 247 544 249 924
5 426 182 322 5
6 259 850 159 569
avg 253 443 284 516 [expected value of gross margins]
covariances
11.264 -20.548 1.424 -15.627
...
$offtext
* --- data input part
set input_items /emargin, land, labor, rotcoef/;
set crops /x1*x4/;
set years /year1*year6/;
table I(input_items,crops)
x1 x2 x3 x4
emargin 253 443 284 516
land 1 1 1 1
labor 25 36 27 87
rotcoef -1 1 -1 1
;
table GM(years,crops) "time series on gross margins"
x1 x2 x3 x4
year1 292 -128 420 579
year2 179 560 187 639
year3 114 648 366 379
year4 247 544 249 924
year5 426 182 322 5
year6 259 850 159 569
;
* --- LP specific declarations
parameter
margins(crops) "crop margins per ha"
rotationalCoeff(crops) "coefficients for the rotational constraint"
laborCoeff(crops) "labour requirement"
;
scalar
landMax "total land available" /200/
laborMax "total labour hours available" /10000/
;
variable
EMargin "expected margin [total]"
;
positive variable
levels(crops) "crop production levels [ha]"
;
equations
EMargin_ "total expected gross margin"
LandC_ "land constraint"
RotationalC_ "rotational constraint"
LaborC_ "labor requirements"
;
Emargin_.. EMargin =e= sum(crops, margins(crops) * levels(crops));
LandC_.. sum(crops, levels(crops)) =l= landMax;
RotationalC_.. sum(crops, levels(crops) * rotationalCoeff(crops)) =l= 0;
LaborC_.. sum(crops, levels(crops) * laborCoeff(crops)) =l= laborMax;
* --- LP for maximizing expected gross margin
model maxEM /Emargin_, LandC_, RotationalC_, LaborC_/;
* --- problem initialization (data assignments)
margins(crops) = I("emargin",crops);
rotationalCoeff(crops) = I("rotcoef",crops);
laborCoeff(crops) = I("labor",crops);
* --- solve the LP
solve maxEM using LP maximizing Emargin;
* --- variance minimazation problem (quadratic)
* --- specific declarations
parameter varGM(crops,crops) "covariance matrix of the gross margins";
alias(crops,crops1);
* --- expected value of gross margins [should be identical to margins(crops) of above]
parameter EGM(crops) "expected gross margin per crop";
variable totVar "total variance [to be minimized]";
scalar totEM "total expected gross margin [we calculate the optimal variance at this level]"
equation
TotalVariance_ "calculate total variance of gross margins"
TotalEMC_ "total expected gross margin as constraint"
;
TotalVariance_.. sum( (crops,crops1), levels(crops)*levels(crops1)*varGM(crops,crops1) ) =e= totVar;
TotalEMC_.. sum(crops, levels(crops) * EGM(crops)) =g= totEM;
* --- quadratic programming for the variance minimazation
model minV /TotalVariance_, TotalEMC_,LandC_, RotationalC_, LaborC_/;
* --- calculate the covariance matrix
EGM(crops) = sum(years, GM(years,crops)) / sum(years$GM(years,crops),1);
display EGM,margins;
* -- to avoid problems with the rounding error in the initial problem setup
EGM(crops) = margins(crops);
* --- covariance matrix
varGM(crops,crops1) = sum(years, (GM(years,crops) - EGM(crops)) * (GM(years,crops1) - EGM(crops1))) / card(years);
display varGM;
* --- solve the variance minimazation at the LP solution point
totEM = Emargin.L;
solve minv using NLP minimizing totVar;
* --- the land use should be identical to the LP solution
* --- decrease total expected gross margin stepwise and collect the points on the EV-frontier
scalar EM_decrease "decrease of total expected margin in each step [percentage points]" /1/;
set steps /step1*step10/;
parameter EV_frontier(steps,*) "points at the EV frontier";
parameter landuse(steps,crops) "land use at the EV frontier";
loop(steps,
totEM = totEM - Emargin.L * (EM_decrease/100);
solve minv using NLP minimizing totVar;
EV_frontier(steps,"E") = totEM;
EV_frontier(steps,"V") = totVar.L;
landuse(steps,crops) = levels.L(crops);
);
* --- see how the associated risk decreases and the land use of less risky crops increases
display EV_frontier,landuse;
* --- for reporting [graph]
* --- the result parameter needs to be re-structured so that gnuplotxyz can graph it
set line /"EV_frontier"/;
set item /"variance","expected_value"/;
parameter frontier(line,steps,item);
frontier("EV_frontier",steps,"variance") = EV_frontier(steps,"V") ;
frontier("EV_frontier",steps,"expected_value") = EV_frontier(steps,"E") ;
$libinclude 'd:\util\gnuplotxyz\gnuplotxyz.gms' frontier expected_value variance
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment