如何从此代码中删除回溯?

时间:2018-12-21 23:20:19

标签: prolog clpfd

目标是使用约束(clpfd)选择不相互接触的形状。调用start(Pairs,4)将返回Pairs = [1,3,5,7]

我注意到的一个问题是,如果我在贴标签之前打印Final,它将打印[1,3,5,7]。这意味着标签没有做任何事情。

我可以更改/添加到此代码中以解决此问题并删除可能的回溯吗?

enter image description here

:-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]).

1 个答案:

答案 0 :(得分:2)

这是一个独立集问题,它是一个NP难题。因此,几乎没有人会找到一种无需搜索(回溯)一般实例的方法。

关于您的代码,labeling/2无济于事,因为您的rules/2实际上是一个搜索过程,它返回可以找到它的解决方案。 all_different/1也没有用,因为ascending/1暗含了它。

大概,您的目标是一个程序,该程序设置约束(不进行任何搜索),然后使用labeling/2搜索解决方案。为此,您需要重新考虑约束模型。阅读一些独立的书。