【发布时间】:2025-12-10 06:25:01
【问题描述】:
我有几个农民,我想在 GAMS 中为每个农民进行优化(利润最大化)。我可以为一个农民做这个,所以我的问题是如何迭代地使它适用于多个农民。
我将数据记录在3个不同的.csv文件中,如下(见代码):
- 1 个文件说明农民在他的农场上分配了多少资源(
resource_allocation.csv用于单个农民,resource_allocations.csv用于多个农民) - 1 个文件说明农民拥有多少资源可供使用(
resource_endowment.csv用于单个农民,resource_endowments.csv用于多个农民) - 1 个文件说明农民获得了多少毛利率(
activity_gross_margin.csv用于单个农民,activity_gross_margins.csv用于多个农民)
以下代码可以满足我对单身农民案例的要求。
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;
我的问题是如何使上述模型适用于多个农民,并以全面的布局导出结果,根据农民的姓名、农民的地区和农民的实践清楚地识别每个农民(见下面的数据)。为此,我只展示了我的数据看起来如何。我对要编写的代码没有太多想法(这就是我问这个问题的原因)。请注意,在下面的数据中,我只是从单个农民数据集中复制了相同的信息,并添加了 3 个额外的列,以明确区分 farmer 1 和 farmer 2。因此,我们希望这两种解决方案是相同的。我还希望将解决方案导出到.csv 文件,以便进一步处理。
*******************************************************************
* 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
;
请注意,我已经问过这个问题here。但是,我无法解决从答案中得到的建议。也就是说,我对作为伪代码的工作流程有一点了解,但我无法将其转换为 GAMS 理解的实际代码。我知道我可以更新 loop 中的模型参数,但我无法从多个农民数据集中提取每个农民的数据。请注意,添加 3 个标识符列(即农民、地区、实践)后,数据的维度不再与模型方程中的相同。
根据我从上一个问题中得到的建议,我尝试组成一个集合frp 并循环通过它来提取单个农民数据并求解模型,如下面的代码块。
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).
我遇到了一堆错误,但第一个错误说:
**** 120 未知标识符按集合输入 **** 141 已声明符号但未分配任何值。检查是否丢失 **** 数据定义、赋值、数据加载或隐式赋值 **** 通过解决语句。 **** 一个狂野的镜头:您可能在解释中使用了虚假逗号 **** 声明文本。检查符号参考列表。
【问题讨论】:
-
“但是,我无法解决我从答案中得到的建议。” - 你能分享一下你尝试了什么并显示你遇到了什么错误吗?这样,提供一些帮助会更容易。
-
嗨@Lutz,感谢您查看此内容。我更新了问题以显示我尝试过的内容。如果您需要我提供进一步的更新,请告诉我。
标签: gams-math