如何在GAMS中为年度集合的二进制变量设置递增强约束?
GAMS中工厂建成不可逆的约束实现方法
正确的约束写法
GAMS要求所有约束必须定义在Equation块内,并用..连接约束的左右表达式。针对你需要的"工厂一旦建成则后续年份保持建成状态"的逻辑,只需对相邻年份设置递推约束:
* 先定义方程 Equation build_irreversible(a) 'Plant once built remains operational'; * 对每个非最后一年,设置前一年construct值 ≤ 后一年construct值 build_irreversible(a)$(ord(a) < 30).. construct(a) <= construct(a+1);
或者用集合基数判断(更通用,无需硬编码年份数):
build_irreversible(a)$(a < card(a)).. construct(a) <= construct(a+1);
这里的$是GAMS的条件过滤符号,用来排除最后一个年份(避免a+1超出集合范围)。
替代方案:用建设年份变量简化逻辑
如果不想写多个约束,可以定义一个整数变量表示工厂的建设年份,通过等式直接推导各年份的construct值:
* 定义建设年份变量,up=31表示永不建设 Integer Variable build_year 'Year when plant is built' /lo=1, up=31/; Equation construct_def(a) 'Link construct variable to build_year'; * 当年份≥建设年份时,construct=1;否则=0 construct_def(a).. construct(a) =e= (ord(a) >= build_year);
这个方案约束数量更少,逻辑更直观,同时自动满足"建成后不拆除"的要求。
错误原因说明
你之前直接写construct('1') <= construct('2')会报错,是因为GAMS不允许裸写不等式约束——所有约束必须归属到Equation块,并用..作为约束定义的分隔符。另外,=L=是用来设置变量下界(如construct(a).L=1是赋值变量当前值),不能用于约束中的比较逻辑。
内容的提问来源于stack exchange,提问作者Shoorga
相关产品推荐
相关产品推荐

