如何在图中找到深度有限的路径?

时间:2014-04-11 05:41:47

标签: prolog

link(a, b).
link(a, c).
link(b, c).
link(b, e).
link(c, f).
link(c, g).
link(c, d).

symlink(F1, F2) :-
  link(F1, F2).

symlink(F1, F2) :-
  link(F2, F1).

profile(a,box). %Tag it is the same as box for a.

find(Start, Tag, Rpath) :
  find2(Start, Tag, 0, [], Rpath).

find2(Step, Tag, Count, Path, Rpath) :-
  C is Count +1,
  C < 5,
  symlink(Step, A),
  compat(A,Tag), % Compatible means the distance between the tag of A
                 % and the Tag that is given as argument should be maximum 1. 
  append(Path, [A|E],Rpath), %This part i want make my final path in Rpath.
  not(member(Step,Path)),
  find2(A, Tag, C, [Step|Path], Rpath).

1 个答案:

答案 0 :(得分:1)

你非常接近这里的工作谓词。我已经提供了一个代码片段,希望能够解决您犯下的一些小错误。请注意,find/3是您实际使用的谓词(来自外部),即所谓的包装子句

find/4以下列方式工作:

  • 第一个子句仅用于检测最大深度的超越。
  • 第二个子句仅用于检测目标节点,即与给定标签匹配的目标节点。
  • 第三个条款确实可以在图中找到对称链接。

需要注意的一些小事:

  • symlink/2重命名为symmetric_link/2,以避免与符号链接混淆。
  • 使用\+代替not进行否定(前者更常见,我相信)。
  • 使用tag/2标记节点,而不是profile/2,以避免与分析/分析代码性能的行为混淆。

代码段:

link(a, b).
link(a, c).
link(b, c).
link(b, d).
link(b, e).
link(c, f).
link(c, g).
link(c, d).

tag(a, box).

symmetric_link(F1, F2) :-
  link(F1, F2).
symmetric_link(F1, F2) :-
  link(F2, F1).

maximum_depth(5).

find(Start, End, Path):-
  find(Start, End, 0, [Start], Path).

find(_, _, Depth, _, _):-
  maximum_depth(Max),
  Depth > Max, !,
  fail.
find(Node, Tag, _, _, [Node]):-
  tag(Node, Tag), !.
find(Node1, Tag, Depth1, History, [Node1|Path]):-
  symmetric_link(Node1, Node2),
  \+ memberchk(Node2, History),
  Depth2 is Depth1 + 1,
  find(Node2, Tag, Depth2, [Node2|History], Path).

使用示例:

?- find(g, box, Path).
Path = [g, c, d, b, a] ;
Path = [g, c, a] ;
Path = [g, c, b, a].

我还没有完全测试过这个谓词,并建议你为这些谓词编写一个单元测试。我使用plUnit来运行SWI-Prolog和SICStus Prolog,但也可能有其他人。

希望这有帮助!