使用cumulative约束时触发无限值错误,寻求技术指导
MiniZinc cumulative约束无限值错误修复方案
问题场景与代码
我在做带优先级的任务调度建模,需处理任务的必填/禁用资源,同时确定任务开始时间和资源分配方案。相关代码如下:
决策变量定义
array[Tasks, Resources] of var 0..1: resource_allocation; % 每个任务的资源选择
必填/禁用资源约束
% 强制分配与禁止分配约束 constraint forall(t in Tasks, r in resource_required[t])(resource_allocation[t,r]=1); constraint forall(t in Tasks, r in resource_forbidden[t])(resource_allocation[t,r]=0);
其中resource_required和resource_forbidden是存储对应资源编号的整数集合。
出错的资源互斥约束
为保证每个工人(资源)同一时间仅处理一项任务,我尝试为每个资源添加cumulative约束,但执行报错:
% 原错误约束:同一时间资源仅分配给一个任务 constraint forall(t in Resources)( cumulative(start, duration, [resource_allocation[t, r] | t in Tasks], 1) );
错误信息
JC:70.12-82 in call 'cumulative' cumulative:21-3.49-7 in binary '/\' operator expression cumulative:25-3.49-7 in if-then-else expression cumulative:26-5.48-9 in binary '/\' operator expression cumulative:30-5.48-9 in if-then-else expression cumulative:47.7-32 in call 'fzn_cumulative' fzn_cumulative:4-9.20-17 in let expression fzn_cumulative:8-13.20-17 in if-then-else expression fzn_cumulative:10-17.19-17 in let expression fzn_cumulative:12.21-74 in variable declaration for 'late' in call 'max' with i = <expression> MiniZinc: evaluation error: arithmetic operation on infinite value Process finished with non-zero exit code 1.
问题根源与修复
核心问题
- 变量名冲突:forall循环中用
t遍历Resources,但列表推导又用t遍历Tasks,导致索引逻辑完全混乱,资源分配的取值错误。 - 数组索引颠倒:cumulative的第三个参数是每个任务对当前资源的占用情况,正确索引应为
resource_allocation[task, res],原代码颠倒了任务和资源的顺序。
修复后的约束代码
% 修正后的资源互斥约束 constraint forall(res in Resources)( cumulative(start, duration, [resource_allocation[task, res] | task in Tasks], 1) );
额外注意事项
- 确保
start数组的变量有有限域,比如设置上限为所有任务总时长,避免无限值问题:array[Tasks] of var 0..sum(duration): start; duration数组需为已知常量或有明确有限域的变量。
可选优先级约束补充
如果需要实现任务优先级调度,可添加如下约束:
% 高优先级任务先执行(假设priority值越大优先级越高) constraint forall(t1, t2 in Tasks where priority[t1] > priority[t2])( start[t1] + duration[t1] <= start[t2] );
内容的提问来源于stack exchange,提问作者Yop
相关产品推荐
相关产品推荐

