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

如何在MiniZinc中对'array[int] of var set of int'使用arg_sort?

MiniZinc中arg_sort无法处理var set of int的解决方法

我在用Chuffed求解器运行MiniZinc模型时遇到类型错误,简化后的出错代码如下:

% Model parameters.
int: n_steps;               % 调度周期的步数
enum tasks;                 % 所有任务ID的集合
enum work_centers;          % 所有工作中心ID的集合

% task_work_center[t] 表示任务t所需的工作中心
array [tasks] of work_centers: task_work_center; 

% 模型变量
% task_start[t] 是任务t的开始步数
array [tasks] of var 1..n_steps: task_start ::add_to_output;

% 约束
array[work_centers] of var set of 1..n_steps: work_center_tasks = [{task_start[t] | t in tasks where task_work_center[t]==wc} | wc in work_centers];
array[work_centers] of var int: task_permutation;

include "arg_sort.mzn";
constraint
    forall(wc in work_centers)(
        task_permutation[wc] = arg_sort(work_center_tasks[wc])  %%% 此处报错!!!
    );

% 目标
solve satisfy;

运行后出现的类型错误:

MiniZinc: type error: no function or predicate with this signature
found: `arg_sort(var set of int)' Cannot use the following functions
or predicates with the same identifier: function array [int] of $$E :
arg_sort(array [$$E] of $$T: x);
(argument 1 expects type array[int] of int, but type var set of int given) function array [int] of var $$E : arg_sort(array [$$E] of
var $$T: x);
(argument 1 expects type array[int] of var int, but type var set of int given) function array [int] of $$E : arg_sort(array [$$E] of
float: x);
(argument 1 expects type array[int] of float, but type var set of int given) function array [int] of var $$E : arg_sort(array [$$E] of
var float: x);
(argument 1 expects type array[int] of var float, but type var set of int given) predicate arg_sort(array [$$E] of var $$T: x,array [int]
of var $$E: p);
(requires 2 arguments, but 1 given) predicate arg_sort(array [$$E] of var float: x,array [int] of var $$E: p);
(requires 2 arguments, but 1 given)

已知条件:预先知道每个工作中心对应的任务数量(各工作中心维度不同),可以不使用集合建模。


核心思路

arg_sort仅支持数组类型输入,不兼容集合类型。因此需要把原有的集合建模替换为数组建模,直接为每个工作中心生成对应任务的开始时间数组,再用arg_sort处理。

修改后的代码示例

% Model parameters.
int: n_steps;               % 调度周期的步数
enum tasks;                 % 所有任务ID的集合
enum work_centers;          % 所有工作中心ID的集合

% task_work_center[t] 表示任务t所需的工作中心
array [tasks] of work_centers: task_work_center; 

% 预先定义每个工作中心对应的任务子集(根据实际任务分配填写)
% 示例:若work_centers包含wc1、wc2,则定义:
% array[work_centers] of set of tasks: wc_tasks = [
%     {t | t in tasks where task_work_center[t] == wc1},
%     {t | t in tasks where task_work_center[t] == wc2}
% ];
array[work_centers] of set of tasks: wc_tasks;

% 模型变量
% task_start[t] 是任务t的开始步数
array [tasks] of var 1..n_steps: task_start ::add_to_output;

% 为每个工作中心生成任务开始时间的数组(替代原集合)
array[work_centers] of array[int] of var int: wc_task_starts = [
    [task_start[t] | t in wc_tasks[wc]] | wc in work_centers
];

% 存储每个工作中心的任务排列
array[work_centers] of array[int] of var int: task_permutation;

include "arg_sort.mzn";
constraint
    forall(wc in work_centers)(
        task_permutation[wc] = arg_sort(wc_task_starts[wc])
    );

% 目标
solve satisfy;

关键改动说明

  1. 定义工作中心任务子集:新增wc_tasks数组,明确每个工作中心对应的任务集合,作为生成数组的基础。
  2. 替换集合为数组:用wc_task_starts数组替代原work_center_tasks集合,直接生成每个工作中心的任务开始时间数组。
  3. 修正arg_sort调用:现在arg_sort的输入是数组类型,符合函数参数要求,不会再触发类型错误。

如果偏好使用arg_sort的谓词版本(双参数形式),可将约束调整为:

constraint
    forall(wc in work_centers)(
        arg_sort(wc_task_starts[wc], task_permutation[wc])
    );

内容的提问来源于stack exchange,提问作者Emilie Picard-Cantin

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 07:16:12