如何在含动态方程的GAMS模型中正确实现循环?
在GAMS中构建递归动态蛛网模型的正确方式
问题背景
尝试用GAMS构建递归动态的蛛网模型,设置初始价格P(t=1)=40,目标是模拟系统趋近均衡的过程。直接使用索引t编写循环时,触发报错:Error 50: Loop controlling index appears in model equation(s)。为绕开错误,新增索引z做循环后代码可运行,但不确定该写法的副作用,原代码如下:
Set t /t1*t10/ * HERE IS THE TRICK z /z1*z10/; Parameters a /100/, b /2/, c /20/, d /1/; Variables P(t), Qd(t), Qs(t), obj; Positive Variables P, Qd, Qs; Equations Demand(t), Supply(t), Equilibrium(t), Objective; Demand(t).. Qd(t) =E= a - b * P(t); Supply(t).. Qs(t) =E= c + d * P(t-1); Equilibrium(t).. Qd(t) =E= Qs(t); Objective.. obj =E= 1; P.l('t1') = 40; Model cobwebModel /all/; Loop(z, Solve cobwebModel using LP maximizing obj; P.l(t+1) = (a - c + d * P.l(t)) / (b + d); );
标准GAMS风格的重构方案
原代码中的循环完全冗余,GAMS可通过时间索引t自动处理递归迭代,无需额外循环变量。正确的无循环代码如下:
* This is a correct setting. No need to loop. Set t /1*10/; Parameters a /100/, b /2/, c /20/, d /1/; Variables P(t), Qd(t), Qs(t), obj; Positive Variables P, Qd, Qs; Equations Demand(t), Supply(t), Equilibrium(t), Objective; Demand(t).. Qd(t) =E= a - b * P(t); Supply(t).. Qs(t) =E= c + d * P(t-1); Equilibrium(t).. Qd(t) =E= Qs(t); Objective..obj =E= 1; * Initial point P.l('1') = 40; Model cobwebModel /all/; Solve cobwebModel using LP maximizing obj; Display P.l, Qd.l, Qs.l;
关键说明
- 原循环的问题:GAMS禁止循环控制索引出现在模型方程中,会引发索引冲突。新增
z循环的写法不仅冗余,还会导致重复求解,降低运行效率。 - 正确逻辑:通过定义带时间递归的方程(如供给方程中引用
P(t-1)),GAMS会自动按时间顺序求解变量——从初始值P.l('1')=40开始,依次计算后续各期的P、Qd、Qs值,最终得到从初始点趋近均衡的10组结果,呈现典型的蛛网振荡特征。 - 可扩展性:该写法无需额外循环变量,后续扩展时间维度(如增加时间点)仅需修改
Set t的定义即可,完全符合GAMS标准建模风格。
内容的提问来源于stack exchange,提问作者garej
相关产品推荐
相关产品推荐

