You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在GAMS中记忆索引t并调用between函数编写约束?

在GAMS中实现带between函数的关联约束

核心思路

要实现“记录第一个约束满足条件的t值,再用该值作为第二个约束的起始点”,需要通过辅助变量捕获关键t值,再基于这个值构建后续约束。以下是具体实现步骤:

1. 定义基础集合与变量

首先声明索引集合、核心变量及辅助变量:

Set t /1*10/;

* 核心变量(根据实际需求替换)
Variable x(t), y(t);

* 辅助变量:用于记录第一个约束满足条件的t值
Integer Variable t0;
t0.up = card(t); * 上限设为t的最大索引值10
t0.lo = 1;       * 下限设为t的最小索引值1

* 二进制辅助变量:标记哪个t满足第一个约束的between条件
Binary Variable delta(t);

2. 第一个约束:捕获满足between条件的t值

假设第一个约束要求x(t)落在[L1, U1]区间内,且仅存在一个这样的t(若允许多个,可删除约束1a):

* 约束1:x(t)在[L1, U1]区间时,delta(t)=1;否则delta(t)=0
Constr1(t):
  between(L1, x(t), U1) = delta(t);

* 约束1a:确保只有一个t满足条件(按需保留)
Constr1a:
  sum(t, delta(t)) = 1;

* 约束1b:将满足条件的t值赋值给t0
Constr1b:
  t0 = sum(t, t*delta(t));

3. 第二个约束:以t0为起始点判断终止条件

假设第二个约束要求从t0到10的所有t,y(t)落在[L2, U2]区间内:

* 约束2:对t >= t0的索引,y(t)需在[L2, U2]区间内
Constr2(t):
  if(t.val >= t0.l, between(L2, y(t), U2) = 1);

注:GAMS中if语句可用于约束的条件性定义,t.val是集合t的当前元素值,t0.l是辅助变量t0的当前水平值。

替代实现(无需二进制变量)

如果需要找到最小的满足between条件的t,可直接用逻辑约束定义t0:

* 约束1:x(t)在[L1, U1]区间
Constr1(t):
  between(L1, x(t), U1) = 1;

* 约束1a:t0是满足Constr1的最小t
Constr1a(t):
  t0 <= t + (1 - between(L1, x(t), U1))*card(t);
Constr1b:
  t0 >= sum(t, t*between(L1, x(t), U1))/card(t);

关键说明

  • between(lower, expr, upper)是GAMS内置函数,当lower <= expr <= upper时返回1,否则返回0;
  • 辅助变量t0的取值逻辑需根据业务场景调整,比如是否允许多个t满足第一个约束;
  • 若第二个约束的终止条件是“从t0到指定t_end”,只需调整if语句中的判断条件即可。

内容的提问来源于stack exchange,提问作者Starwinwin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 05:39:57