目标是使用约束(clpfd)选择不相互接触的形状。调用start(Pairs,4)
将返回Pairs = [1,3,5,7]
。
我注意到的一个问题是,如果我在贴标签之前打印Final,它将打印[1,3,5,7]
。这意味着标签没有做任何事情。
我可以更改/添加到此代码中以解决此问题并删除可能的回溯吗?
:-use_module(library(clpfd)).
:-use_module(library(lists)).
% init initialises Pairs and Max
% Pairs - The elements inside the Nth list in Pairs,
% represent the index of the shapes that shape N can touch
init([[3,5,6,7],[4,5,7],[1,4,5,7],[2,3,7],[1,2,3,7],[1],[1,2,3,4,5]],7).
start(Final, N):-
init(Pairs, Max),
length(Final, N),
domain(Final, 1, Max),
ascending(Final),
all_different(Final),
rules(Pairs,Final),
labeling([],Final).
rules(_,[]).
rules(Pairs,[H|T]):-
nth1(H,Pairs,PairH),
secondrule(PairH,T),
rules(Pairs,T).
secondrule(_, []).
secondrule(PairH, [H|T]):-
element(_,PairH,H),
secondrule(PairH, T).
ascending([_|[]]).
ascending([H|[T1|T2]]):-
H #< T1,
ascending([T1|T2]).
答案 0 :(得分:2)
这是一个独立集问题,它是一个NP难题。因此,几乎没有人会找到一种无需搜索(回溯)一般实例的方法。
关于您的代码,labeling/2
无济于事,因为您的rules/2
实际上是一个搜索过程,它返回可以找到它的解决方案。 all_different/1
也没有用,因为ascending/1
暗含了它。
大概,您的目标是一个程序,该程序设置约束(不进行任何搜索),然后使用labeling/2
搜索解决方案。为此,您需要重新考虑约束模型。阅读一些独立的书。