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

如何在MiniZinc中按最小化重叠顺序求解以获取新颖解?

在MiniZinc中优先生成低重叠度的新颖解(以八皇后为例)

要让MiniZinc优先生成与已有解重叠度低的新颖解,核心是通过跟踪重叠分数+自定义搜索启发式引导求解方向,模拟类似广度优先的探索逻辑,以下是具体实现方案:

1. 定义重叠度计算规则

以八皇后为例,假设已存储的解存在列表previous_solutions中(每个解是长度为8的数组,对应每列皇后的行号)。新解q与单个已有解的重叠度可定义为相同列行号一致的数量:

int: overlap(array[int] of int: q, array[int] of int: prev_q) = sum(i in 1..8) (if q[i] == prev_q[i] then 1 else 0 endif);

总重叠度可选择与所有已有解的重叠度之和,或取最大值(按需选择):

int: total_overlap = sum(s in previous_solutions) overlap(q, s);

2. 两种核心实现方式

方式一:迭代求解+最小化重叠度

每次生成一个解后将其加入previous_solutions,后续求解时同时满足八皇后约束、排除重复解,并最小化总重叠度:

array[1..8] of var 1..8: q;

% 八皇后基础约束
constraint all_different(q);
constraint all_different([q[i] + i | i in 1..8]);
constraint all_different([q[i] - i | i in 1..8]);

% 排除已生成的重复解
constraint forall(s in previous_solutions) (q != s);

% 优先生成重叠度最低的解
solve minimize total_overlap;

这种方式直接通过优化目标引导求解器优先探索低重叠分支,效果直观。

方式二:自定义搜索启发式

不修改目标函数,而是通过::search注解指定变量选择和赋值顺序,优先选择与已有解差异大的分支:

% 优先选择当前可选值与已有解重叠最少的列,再选最小行号
solve :: int_search(q, first_fail, indomain_min, complete) minimize total_overlap;

如果使用支持自定义启发式的求解器(如Gecode),还可以进一步定制评估逻辑——比如对每个列的可选行号,计算其在已有解中的出现频率,优先选择频率最低的行号。

3. 模拟广度优先搜索效果

MiniZinc默认深度优先易产生高重叠解,要贴近BFS逻辑:

  • 优先对前几列强制选择与已有解不同的行号,再填充后续列;
  • 使用重启策略,每次重启后优先探索未被充分遍历的分支,避免陷入局部高重叠解的搜索路径。

4. 实用优化建议

  • 将previous_solutions作为模型参数传入,避免硬编码,方便动态更新;
  • 若解的数量较多,可只保留最近N个解参与重叠度计算,或改用最大重叠度替代总和,平衡计算效率和新颖性要求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 00:17:06