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

MiniZinc如何对数组对应天数的时间步子集进行求和

MiniZinc按天分段求和实现方案

错误原因

你原来的写法报错是因为MiniZinc的范围运算符..要求两侧边界为编译期可确定的常量表达式,你在范围中使用了依赖迭代变量d的动态计算表达式,无法在编译阶段解析出合法范围,因此会抛出语法错误。

解决方案

以下是两种常用的实现方式,第一种优先推荐,可维护性更高:

方式1:预定义每日对应时间步集合

提前将每天对应的时间步范围存储为固定集合数组,求和时直接调用对应天的集合即可,是最稳妥的实现方式:

set of int: Days = 1..3; 
set of int: Timesteps = 1..36;
% 定义单日时间步数量,方便后续修改
int: STEPS_PER_DAY = 12;

% 预定义每天对应的时间步集合
array[Days] of set of Timesteps: daily_timesteps = [
    (d-1)*STEPS_PER_DAY + 1 .. d*STEPS_PER_DAY | d in Days
];

array[Timesteps] of var -1.0..1.0: X; 
% 注意:12个X求和的范围是-12~12,原来的-1.0..1.0范围会导致约束冲突
array[Days] of var -12.0..12.0: Y;

constraint forall(d in Days)(
    Y[d] = sum(t in daily_timesteps[d])(X[t])
);

方式2:sum内使用where条件过滤

如果不想额外定义集合变量,可以直接在sum的迭代范围中增加过滤条件,筛选属于当前天的时间步:

set of int: Days = 1..3; 
set of int: Timesteps = 1..36;
int: STEPS_PER_DAY = 12;

array[Timesteps] of var -1.0..1.0: X; 
array[Days] of var -12.0..12.0: Y;

constraint forall(d in Days)(
    Y[d] = sum(t in Timesteps where t > (d-1)*STEPS_PER_DAY /\ t <= d*STEPS_PER_DAY)(X[t])
);

注意事项

  • 你原代码中Y变量的取值范围设置有误,12个取值范围为-1~1的变量求和后,取值范围应为-12.0..12.0,若保留原来的-1.0..1.0会直接触发约束冲突导致模型无解。
  • 推荐将单日时间步数量提取为单独的参数变量,后续需要修改时间步配置时只需修改一处即可,避免硬编码带来的维护问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 13:27:02