如何防止在序言重复(How can I prevent duplicates in prolog)

2019-09-01 05:29发布

我的多解问题的出现是由于序言的回溯通过目标循环。 虽然我明白,在技术上,只要每个解决方案是正确的,这对我来说并不实用。 有没有办法删除重复的方法?

这是我到目前为止的代码:

flight(london, paris).
flight(paris, amsterdam).
flight(amsterdam, rome).
flight(rome, paris).
flight(rome, rio_de_janeiro).
route_from(A,B) :-
  flight(A,B).
route_from(A,B) :-
  flight(A,R),
  route_from(R,B).

一个例子查询:

?- route_from(A, paris).
A = london ;
A = rome ;
A = london ;
A = london ;
A = london ;
A = london ;
A = london ;
A = london ;
A = london ;
etc.

问候。

Answer 1:

你不是返回重复的解决方案以外的更大的问题。 你的程序,按原样将无限循环,因为在你的图形循环。

为了避免循环,你可以保持访问的城市列表:

route_from(A,B) :-
  route_from(A,B, []).

route_from(A,B, _) :-
  flight(A,B).
route_from(A,B, Visited) :-
  flight(A,R),
  \+ member(A, Visited),
  route_from(R,B, [A|Visited]).

现在,这不会阻止,如果有去一个城市不止一种方式返回重复。 您可以使用setof/3 + member/2 ,收集所有的解决方案,而重复。

route_from_without_duplicates(A,B):-
  setof(A-B, route_from(A,B), Routes),
  member(A-B, Routes).


文章来源: How can I prevent duplicates in prolog