在GAMS中用宏替代循环提升运行速度是否可行?
GAMS循环提速:替代Loop的正确方案
首先明确:宏无法有效替代大集合的Loop实现提速,原因如下:
- 宏是GAMS预处理阶段的文本替换工具,不是运行时的循环逻辑。调用
mymacro(t)只会把t作为文本替换,不会遍历集合元素; - 手动逐个调用30万次宏不仅会生成海量代码,预处理阶段还会因字符串拼接错误(如
"1"+1的语法问题)报错,且预处理耗时远超原Loop。
最优提速方案:利用有序集合直接递推赋值
GAMS对有序集合的元素间递推支持编译级优化,无需Loop即可高效计算,代码如下:
set t / 1 * 300000 /; parameter pop(t) / 1 3456 / growth(t) ; growth(t) = 25; * 直接按集合顺序递推,自动从t=2开始计算 pop(t) = pop(t-1) + growth(t-1);
原理说明
因为set t是从1到300000的有序集合,GAMS会按照元素的定义顺序依次计算pop(t):
- t=1时,
pop(t)已有初始值3456,跳过计算; - t≥2时,直接使用前一个元素
t-1的pop和growth值计算,全程是编译优化后的向量运算,速度远快于解释执行的Loop。
不推荐的宏方案(仅作技术参考)
若执意尝试宏,可使用预处理阶段的$loop遍历集合生成代码,但30万次生成会导致代码量爆炸,预处理和编译耗时极长,完全不实用:
$macro mymacro(tval) pop(%tval%+1) = pop(%tval%) + growth(%tval%); $loop t mymacro("%t%"); $endloop
内容的提问来源于stack exchange,提问作者Michael
相关产品推荐
相关产品推荐

