带约束的Prolog练习:自定义sequence谓词无合法解问题求助
问题排查与修复方案
错误1:count谓词逻辑错误
你使用的delete/3是普通Prolog的列表操作谓词,不属于CLP(FD)约束体系,它执行时会尝试直接实例化列表元素删除匹配项,但此时Sequence还处于未绑定的域变量状态,根本无法执行删除操作,自然会卡在后续的长度约束校验步骤。
正确的元素计数CLP(FD)实现可以直接用内置的count/4约束谓词,修改后的checkNumber代码如下:
checkNumber(Number,Sequence):- foreach(X in 0..3, count(X, Sequence, #=, Number)).
错误2:cost谓词的约束方向写反
你当前的递归逻辑里写的是NewCost #= TotalCost-Cost,但TotalCost是输出变量,递归计算是从底层向上累加成本,应该把约束反过来:
cost([_|[]],0). cost([X,Y|Sequence],TotalCost):- costTable(X,Y,Cost), cost([Y|Sequence],NewCost), TotalCost #= NewCost + Cost.
之前的写法要求TotalCost先有值才能推导NewCost,但初始状态下TotalCost是未绑定变量,约束无法正常传播,自然得不到有效解。
修复后完整可运行代码
% 记得导入CLP(FD)库 :- use_module(library(clpfd)). costTable(0,1,3). costTable(0,2,3). costTable(0,3,2). costTable(1,3,1). costTable(2,0,1). costTable(2,1,4). costTable(3,1,5). costTable(3,3,2). sequence(Number, Sequence, Cost):- Length is 4*Number, length(Sequence,Length), domain(Sequence,0,3), checkNumber(Number,Sequence), cost(Sequence,Cost), labeling([minimize(Cost)],Sequence). checkNumber(Number,Sequence):- foreach(X in 0..3, count(X, Sequence, #=, Number)). cost([_|[]],0). cost([X,Y|Sequence],TotalCost):- costTable(X,Y,Cost), cost([Y|Sequence],NewCost), TotalCost #= NewCost + Cost.
测试验证
调用sequence(2, Sequence, Cost)可正常返回最小成本解,最小Cost为11,你题目中给出的示例序列成本为15,属于非最优解。
内容的提问来源于stack exchange,提问作者Teresa Corado
相关产品推荐
相关产品推荐

