Reputation: 1300
I have several farmers and I would like to conduct optimization (profit maximization) for each of them in GAMS. I can do this for a single farmer, so my problem is how to iteratively make it works for multiple farmers.
I recorded the data in 3 different .csv
files as follows (see code):
resource_allocation.csv
for a single farmer and resource_allocations.csv
for multiple farmers)resource_endowment.csv
for a single farmer and resource_endowments.csv
for multiple farmers)activity_gross_margin.csv
for a single farmer and activity_gross_margins.csv
for multiple farmers)The following code does what I want for the single farmer case.
SETS
resr resource of the farmer
crop crops grown by the farmer
;
PARAMETERS
resource_allocation resource allocated by the farmer
resEndow resouce endowment of the farmer
grosMarg activities' gross margin of the farmer
;
$onEcho > resource_allocation.csv
resrs,Corn, Bean, Sorghum, Peanut
Land,1,1,1,1
Labor,1.42,1.87,1.92,2.64
Mules,1.45,1.27,1.16,1.45
Market,0,0,0,0.98
$offEcho
$call csv2gdx resource_allocation.csv id=resource_allocation useHeader=y fieldSep=Comma index=1 values=2..lastCol trace=3
$ifE errorLevel<>0 $abort Problems reading resource_allocation.csv!
$gdxIn resource_allocation.gdx
$load resr = dim1
$load crop = dim2
$load resource_allocation
$gdxIn
;
$onEcho > resource_endowment.csv
resr,resEndow
Labor,16.5
Land,5
Mules,10
Market,0.5
$offEcho
$call csv2gdx resource_endowment.csv id=resEndow useHeader=y fieldSep=Comma index=1 values=2 trace=3
$ifE errorLevel<>0 $abort Problems reading resource_endowment.csv!
$gdxIn resource_endowment.gdx
$load resEndow
$gdxIn
;
$onEcho > activity_gross_margin.csv
crop,grosMarg
Corn,1372
Bean,1219
Sorghum,1523
Peanut,4874
$offEcho
$call csv2gdx activity_gross_margin.csv id=grosMarg useHeader=y fieldSep=Comma index=1 values=2 trace=3
$ifE errorLevel<>0 $abort Problems reading activity_gross_margin.csv!
$gdxIn activity_gross_margin.gdx
$load grosMarg
$gdxIn
;
*DISPLAY resEndow, grosMarg, farmData;
VARIABLES
Prft Total gross margin
x(crop) activity levels
;
EQUATIONS
Profit definition of Z
RESCON ressouse constraint
NONNEG non-negativity condition;
Profit.. Prft =E= sum(crop, grosMarg (crop)*x(crop));
RESCON(resr).. sum(crop, resource_allocation(resr, crop)*x(crop)) =L= resEndow(resr);
NONNEG(crop).. x(crop) =G= 0;
model mayaland / Profit, RESCON, NONNEG /
;
SOLVE mayaland maximizing Prft using LP;
DISPLAY x.l, Prft.l;
My problem is how to make the above model work for multiple farmers and export the results in a comprehensive layout that clearly identify each farmer based on farmer's name, farmer's region, and farmer's practice (see data below). For this, I am only showing how the data look like on my end. I don't have much of ideas on the code to write (which is why I am asking this question). Note that, in the data below, I just replicated the same information from the single farmer datasets and add 3 additional columns to make the distinction between farmer 1
and farmer 2
clear. So, we expect the 2 solutions to be the same. I also would like to have the solution exported to a .csv
file, so I can process it further.
*******************************************************************
* Here starts my problem: How can I run the above run over the
* sets farmers, regions, and practices such that I get 1 solution
* for each unique combination of(farmers, regions, practices)
*******************************************************************
SETS
farmers
regions
practices
resrs
crops
;
PARAMETERS
resource_allocations
resource_endowments
activity_gross_margins
;
SETS resrs, crops;
PARAMETERS
farmDatas
resEndows
grosMargs
;
$onEcho > resource_allocations.csv
farmers,regions,practices,resrs,Corn, Bean, Sorghum, Peanut
farmer 1,region 1,practice 1,Land,1,1,1,1
farmer 1,region 1,practice 1,Labor,1.42,1.87,1.92,2.64
farmer 1,region 1,practice 1,Mules,1.45,1.27,1.16,1.45
farmer 1,region 1,practice 1,Market,0,0,0,0.98
farmer 2,region 2,practice 2,Land,1,1,1,1
farmer 2,region 2,practice 2,Labor,1.42,1.87,1.92,2.64
farmer 2,region 2,practice 2,Mules,1.45,1.27,1.16,1.45
farmer 2,region 2,practice 2,Market,0,0,0,0.98
$offEcho
$call csv2gdx resource_allocations.csv id=resource_allocations useHeader=y fieldSep=Comma index=1..4 values=5..lastCol trace=3
$ifE errorLevel<>0 $abort Problems reading resource_allocations.csv!
$gdxIn resource_allocations.gdx
$load farmers = dim1
$load regions = dim2
$load practices = dim3
$load resrs = dim4
$load crops = dim5
$load resource_allocations
$gdxIn
;
$onEcho > resource_endowments.csv
farmers,regions,practices,resrs,resEndows
farmer 1,region 1,practice 1,Labor,16.5
farmer 1,region 1,practice 1,Land,5
farmer 1,region 1,practice 1,Mules,10
farmer 1,region 1,practice 1,Market,0.5
farmer 2,region 2,practice 2,Labor,16.5
farmer 2,region 2,practice 2,Land,5
farmer 2,region 2,practice 2,Mules,10
farmer 2,region 2,practice 2,Market,0.5
$offEcho
$call csv2gdx resource_endowments.csv id=resEndows useHeader=y fieldSep=Comma index=1..4 values=5..lastCol trace=3
$ifE errorLevel<>0 $abort Problems reading resource_endowments.csv!
$gdxIn resource_endowments.gdx
$load resEndows
$gdxIn
;
$onEcho > activity_gross_margins.csv
farmers,regions,practices,crops,grosMargs,
farmer 1,region 1,practice 1,Corn,1372,
farmer 1,region 1,practice 1,Bean,1219,
farmer 1,region 1,practice 1,Sorghum,1523,
farmer 1,region 1,practice 1,Peanut,4874,
farmer 2,region 2,practice 2,Corn,1372,
farmer 2,region 2,practice 2,Bean,1219,
farmer 2,region 2,practice 2,Sorghum,1523,
farmer 2,region 2,practice 2,Peanut,4874
$offEcho
$call csv2gdx activity_gross_margins.csv id=grosMargs useHeader=y fieldSep=Comma index=1..4 values=5..lastCol trace=3
$ifE errorLevel<>0 $abort Problems reading activity_gross_margins.csv!
$gdxIn activity_gross_margins.gdx
$load grosMargs
$gdxIn
;
Please note that I have already asked this question here. However, I couldn't work out the suggestion I got from the answer. This is, I have a bit of an idea of the workflow as pseudo code but I could not translate it into actually code that GAMS understands. I know that I can update model parameters in a loop
, but I couldn't extract the data for each farmer from the multiple farmer datasets. Note that after adding the 3 identifier columns (i.e. farmers, regions, practices), the dimensions of the data is no longer the same as in the model equations.
Based on the suggestion I received from the previous question, I tried to make up a set frp
and loop through it to extract single farmer data and solve the model as in the code chunk below.
sets
frp(farmers,regions,practices) the looping index
;
$onEcho > frp.csv
farmers,regions,practices,frp,
farmer 1,region 1,practice 1,1,
farmer 2,region 2,practice 2,2
$offEcho
$call csv2gdx frp.csv id=frp useHeader=y fieldSep=Comma index=1..3 values=4 trace=3
$ifE errorLevel<>0 $abort Problems reading frp.csv!
$gdxIn frp.gdx
$load frp
$gdxIn
;
parameter results(farmers,regions,practices,*,*) 'collect results';
loop(frp(farmers,regions,practices),
* extract data for single case (I assume I need to update the following 3 parameters)
resEndow(resr) = resource_endowments(farmer,region,practice,resrs);
grosMarg (crop) = activity_gross_margins (farmers,regions,practices,crops,grosMargs)
resource_allocation(resr, crop) = resource_allocations(farmers,regions,practices,resrs)
* solve single case
SOLVE mayaland maximizing Prft using LP;
* store results in parameter
results(farmer,region,practice,'x',crops) = x.l(crops);
results(farmer,region,practice,'profit','-') = Prft.l;
);
* export results to spreadsheet or csv file (have not even tried to export becuase I couldn't make the loop work).
I got a bunch of errors but the first one says:
**** 120 Unknown identifier entered as set **** 141 Symbol declared but no values have been assigned. Check for missing **** data definition, assignment, data loading or implicit assignment **** via a solve statement. **** A wild shot: You may have spurious commas in the explanatory **** text of a declaration. Check symbol reference list.
Upvotes: 0
Views: 128
Reputation: 2292
There is not really a one single general problem you have in the code you tried, but you mixed up the names of different symbols and also names of GDX files with names of symbols loaded from those files. However, it was pretty straight forward to go through your errors as pointed out by GAMS one by one to resolve them all. This is the new loop (I kept your code as comment and the fixed one just below):
loop(frp(farmers,regions,practices),
* extract data for single case (I assume I need to update the following 3 parameters)
*old resEndow(resr) = resource_endowments(farmer,region,practice,resrs);
resEndow(resr) = resEndows(farmers,regions,practices,resr);
*old grosMarg (crop) = activity_gross_margins (farmers,regions,practices,crops,grosMargs)
grosMarg (crop) = grosMargs (farmers,regions,practices,crop,'grosMargs');
*old resource_allocation(resr, crop) = resource_allocations(farmers,regions,practices,resrs)
resource_allocation(resr, crop) = resource_allocations(farmers,regions,practices,resr,crop);
* solve single case
SOLVE mayaland maximizing Prft using LP;
* store results in parameter
*old results(farmer,region,practice,'x',crops) = x.l(crops);
results(farmers,regions,practices,'x',crop) = x.l(crop);
*old results(farmer,region,practice,'profit','-') = Prft.l;
results(farmers,regions,practices,'profit','-') = Prft.l;
);
Upvotes: 1