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

MiniZinc派生枚举问题:如何简化变长算术谜的数据格式?

解决变长密码算术谜的类型匹配与数据简洁性问题

针对你扩展MiniZinc密码算术模型时遇到的类型不匹配问题,这里提供几种无需繁琐构造函数的优化方案:

方案1:统一枚举类型,用特殊枚举值表示零

不需要单独定义Letters_or_zero枚举,而是在原Letters枚举中添加一个代表零的特殊值(比如ZERO),这样所有涉及填充的位置直接使用这个枚举值即可,避免跨枚举类型的转换:

enum Letters = {ZERO, S, E, N, D, M, O, R, Y}; % 示例枚举,根据实际单词调整

% 数据声明可直接使用枚举值,无需构造函数
array[1..num_addends, 1..max_length] of Letters = [
  [S, E, N, D],
  [ZERO, M, O, R, E], % 短单词用ZERO填充
  [ZERO, ZERO, M, O, N, E, Y] % 和的位置也统一用ZERO填充对齐
];

这样Firsts、sums、tot都可以统一使用Letters类型,彻底消除类型不匹配问题,同时数据声明保持简洁。

方案2:使用可选类型替代枚举扩展

如果不想修改原Letters枚举,可以用MiniZinc的opt Letters类型来表示允许空(零填充)的位置,空值直接用none表示,无需额外构造函数:

enum Letters = {S, E, N, D, M, O, R, Y};

% 用opt Letters类型定义数组,none代表零填充
array[1..num_addends, 1..max_length] of opt Letters = [
  [S, E, N, D, none, none],
  [none, M, O, R, E, none],
  [none, none, M, O, N, E, Y] % 对齐到最长长度
];

% 在约束中处理none值:将none映射为0
constraint forall(i in 1..num_addends, j in 1..max_length) (
  if sums[i,j] is not none then value(sums[i,j]) >= 1 else value(sums[i,j]) = 0 endif
);

这种方式既保留了原Letters枚举的纯净性,又避免了类型转换的繁琐,数据声明中用none代替零填充,直观简洁。

方案3:调整数据结构,按实际长度存储单词

如果不想用零填充,可以将每个加数存储为单独的数组(长度可变),然后通过索引计算对齐到最高位:

enum Letters = {S, E, N, D, M, O, R, Y};

% 每个加数是变长数组,无需填充
array[1..num_addends] of array[int] of Letters = [
  [S, E, N, D],
  [M, O, R, E],
  [M, O, N, E, Y]
];

% 计算最长长度
int: max_len = max([length(addend) | addend in addends]);

% 约束中通过偏移计算每一位的数值
constraint forall(pos in 1..max_len) (
  sum(
    if length(addend) >= pos then value(addend[length(addend) - pos + 1]) else 0 endif
    for addend in addends[1..num_addends-1]
  ) + carry_in[pos] = value(addends[num_addends][length(addends[num_addends]) - pos + 1]) + 10 * carry_out[pos]
);

这种方案彻底取消了零填充,数据结构更贴合实际单词长度,同时避免了类型问题,只是约束部分需要额外处理索引偏移,但逻辑清晰。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 15:55:19