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

MiniZinc语法错误求助:赛事赛程约束建模问题排查

体育赛事赛程规划MiniZinc语法错误排查与修复

问题背景

规划20支队伍的体育赛事赛程:

  • 每轮14支队伍参赛、6支轮休
  • 每队总计14场比赛
  • 同一项目参赛次数不超过2次
  • 尽量均衡各队休息间隔

使用MiniZinc构建约束模型时,遇到语法错误:MiniZinc: syntax error: syntax error, unexpected [, expecting end of file,转无BOM UTF-8格式后问题仍存在。

错误原因分析

  1. 数组声明语法错误:
    原代码中var 1..N_ROUNDS: RoundOfMatch [m in 1..N_MATCHES];不符合MiniZinc数组声明规范,正确的数组变量声明格式应为array[索引范围] of var 类型: 变量名;。

  2. count函数用法错误:
    MiniZinc的count函数用于统计数组中某个值的出现次数,而非遍历集合统计条件满足的次数。原代码中count(m in 1..N_MATCHES)(...)的写法不合法,需替换为sum + bool2int的组合来统计满足条件的元素数量。

修正后的完整代码

int: N_MATCHES = 140;
int: N_TEAMS   = 20;
int: N_ROUNDS  = 20;
int: N_SPORTS  = 7;

% 需补充具体的SportOf和TeamsOf输入数据
array[1..N_MATCHES] of int: SportOf;
array[1..N_MATCHES] of set of int: TeamsOf;

% 修正数组变量声明语法
array[1..N_MATCHES] of var 1..N_ROUNDS: RoundOfMatch;

% A. 足球(SportOf=1)仅在第1-10轮,接力赛(SportOf=3)仅在第11-20轮
constraint
  sum(m in 1..N_MATCHES) (bool2int(SportOf[m] == 1 /\ RoundOfMatch[m] > 10)) = 0
  /\
  sum(m in 1..N_MATCHES) (bool2int(SportOf[m] == 3 /\ RoundOfMatch[m] < 11)) = 0;

% B1. 第1-10轮:每场包含2场足球(1),1场篮球(4)、排球(2)、标签赛(6)、目标球(7)、夺旗赛(5)
constraint
  forall(r in 1..10) (
       sum(m in 1..N_MATCHES) (bool2int(SportOf[m] == 1 /\ RoundOfMatch[m] == r)) = 2
    /\
       sum(m in 1..N_MATCHES) (bool2int(SportOf[m] == 4 /\ RoundOfMatch[m] == r)) = 1
    /\
       sum(m in 1..N_MATCHES) (bool2int(SportOf[m] == 2 /\ RoundOfMatch[m] == r)) = 1
    /\
       sum(m in 1..N_MATCHES) (bool2int(SportOf[m] == 6 /\ RoundOfMatch[m] == r)) = 1
    /\
       sum(m in 1..N_MATCHES) (bool2int(SportOf[m] == 7 /\ RoundOfMatch[m] == r)) = 1
    /\
       sum(m in 1..N_MATCHES) (bool2int(SportOf[m] == 5 /\ RoundOfMatch[m] == r)) = 1
  );

% B2. 第11-20轮:每场包含2场接力赛(3),1场篮球(4)、排球(2)、标签赛(6)、目标球(7)、夺旗赛(5)
constraint
  forall(r in 11..20) (
       sum(m in 1..N_MATCHES) (bool2int(SportOf[m] == 3 /\ RoundOfMatch[m] == r)) = 2
    /\
       sum(m in 1..N_MATCHES) (bool2int(SportOf[m] == 4 /\ RoundOfMatch[m] == r)) = 1
    /\
       sum(m in 1..N_MATCHES) (bool2int(SportOf[m] == 2 /\ RoundOfMatch[m] == r)) = 1
    /\
       sum(m in 1..N_MATCHES) (bool2int(SportOf[m] == 6 /\ RoundOfMatch[m] == r)) = 1
    /\
       sum(m in 1..N_MATCHES) (bool2int(SportOf[m] == 7 /\ RoundOfMatch[m] == r)) = 1
    /\
       sum(m in 1..N_MATCHES) (bool2int(SportOf[m] == 5 /\ RoundOfMatch[m] == r)) = 1
  );

% 同一队伍在同一轮中最多参加1场比赛
constraint
  forall(r in 1..N_ROUNDS, t in 1..N_TEAMS) (
    sum(m in 1..N_MATCHES) (bool2int(t in TeamsOf[m] /\ RoundOfMatch[m] == r)) <= 1
  );

% 休息间隔优化:最小化连续参赛次数
array[1..N_TEAMS, 1..N_ROUNDS] of var bool: Play;
constraint
  forall(t in 1..N_TEAMS, r in 1..N_ROUNDS) (
    Play[t,r] <-> exists(m in 1..N_MATCHES)(
      t in TeamsOf[m] /\ RoundOfMatch[m] == r
    )
  );

array[1..N_TEAMS, 1..(N_ROUNDS-1)] of var 0..1: consecutive;
constraint
  forall(t in 1..N_TEAMS, r in 1..(N_ROUNDS-1)) (
    consecutive[t,r] = bool2int( Play[t,r] /\ Play[t,r+1] )
  );

% 补充每队总计14场比赛的约束
constraint
  forall(t in 1..N_TEAMS) (
    sum(r in 1..N_ROUNDS) (bool2int(Play[t,r])) = 14
  );

% 补充同一项目参赛次数不超过2次的约束
constraint
  forall(t in 1..N_TEAMS, s in 1..N_SPORTS) (
    sum(m in 1..N_MATCHES) (bool2int(t in TeamsOf[m] /\ SportOf[m] == s)) <= 2
  );

solve minimize sum(t in 1..N_TEAMS, r in 1..(N_ROUNDS-1))( consecutive[t,r] );

output [
  "Success: RoundOfMatch = [",
  concat([
    show(RoundOfMatch[m]) ++
    if m < N_MATCHES then ", " else "" endif
    | m in 1..N_MATCHES
  ]),
  "]\n"
];

额外注意事项

  1. 需为SportOf和TeamsOf数组补充具体输入数据,例如每一场比赛对应的项目和参赛队伍集合,否则模型无法运行。
  2. 原模型未覆盖每队14场比赛和同一项目参赛不超过2次的需求,上述修正代码已补充对应的约束条件。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 04:57:03