ringing(5).
ringing(9).
ringing(16).
touching(2, 1).
touching(7, 1).
touching(1, 2).
touching(8, 2).
touching(8, 3).
touching(8, 4).
touching(9, 4).
touching(6, 5).
touching(9, 5).
touching(5, 6).
touching(9, 6).
touching(1, 7).
touching(8, 7).
touching(9, 7).
touching(10, 7).
touching(11, 7).
touching(12, 7).
touching(13, 7).
touching(14, 7).
touching(2, 8).
touching(3, 8).
touching(4, 8).
touching(7, 8).
touching(4, 9).
touching(5, 9).
touching(6, 9).
touching(7, 9).
touching(7, 10).
touching(7, 11).
touching(7, 12).
touching(7, 13).
touching(7, 14).
touching(15, 14).
touching(14, 15).
touching(16, 15).
touching(15, 16).
adjacent(RoomA, RoomB) :-
touching(RoomA, RoomB)
; touching(RoomB, RoomA).
path_to_phone(FirstRoom, LastRoom,Path) :- % Base Case
ringing(LastRoom),
%touching(FirstRoom, X),
travel(FirstRoom, LastRoom, [FirstRoom],Q),
reverse(Q,Path).
travel(FirstRoom, LastRoom,P, [LastRoom|P]) :-
% write('who call this\n'),
adjacent(FirstRoom,LastRoom).
travel(FirstRoom,LastRoom, Visited,Path) :-
touching(FirstRoom,X),
X \== LastRoom,
\+member(X,Visited),
%write(visited),
travel(X,LastRoom,[X|Visited],Path).
%write('call?\n').
在path_to_phone中,如果一个房间有响铃,那么它将继续查看该房间的路径。 我不确定为什么路径输出两次。基于此,我怎样才能走最短的路径来获得房间。
答案 0 :(得分:2)
我认为这是因为您以两种方式定义双向图。 你只需要一种方式。 我的意思是你定义"触摸(2,1)。"和"触摸(1,2)。"和 邻近/ 2也是。
这些定义都用于表示双向图。 需要两个中的任何一个,但两者都是多余的。
删除下面的冗余术语后,您的代码将会收集。 (旅行/ 2也需要修改如下)。
抱歉我的英语不好。
ringing(5).
ringing(9).
ringing(16).
touching(2, 1).
touching(7, 1).
%touching(1, 2).
touching(8, 2).
touching(8, 3).
touching(8, 4).
touching(9, 4).
touching(6, 5).
touching(9, 5).
%touching(5, 6).
touching(9, 6).
%touching(1, 7).
touching(8, 7).
touching(9, 7).
touching(10, 7).
touching(11, 7).
touching(12, 7).
touching(13, 7).
touching(14, 7).
%touching(2, 8).
%touching(3, 8).
%touching(4, 8).
%touching(7, 8).
%touching(4, 9).
%touching(5, 9).
%touching(6, 9).
%touching(7, 9).
%touching(7, 10).
%touching(7, 11).
%touching(7, 12).
%touching(7, 13).
%touching(7, 14).
touching(15, 14).
%touching(14, 15).
touching(16, 15).
%touching(15, 16).
adjacent(RoomA, RoomB) :-
touching(RoomA, RoomB)
; touching(RoomB, RoomA).
path_to_phone(FirstRoom, LastRoom,Path) :- % Base Case
ringing(LastRoom),
%touching(FirstRoom, X),
travel(FirstRoom, LastRoom, [FirstRoom],Q),
reverse(Q,Path).
travel(FirstRoom, LastRoom,P, [LastRoom|P]) :-
% write('who call this\n'),
adjacent(FirstRoom,LastRoom).
travel(FirstRoom,LastRoom, Visited,Path) :-
adjacent(FirstRoom,X), %touching(FirstRoom,X),
X \== LastRoom,
\+member(X,Visited),
%write(visited),
travel(X,LastRoom,[X|Visited],Path).
%write('call?\n').
ringing(5).
ringing(9).
ringing(16).
touching(2, 1).
touching(7, 1).
%touching(1, 2).
touching(8, 2).
touching(8, 3).
touching(8, 4).
touching(9, 4).
touching(6, 5).
touching(9, 5).
%touching(5, 6).
touching(9, 6).
%touching(1, 7).
touching(8, 7).
touching(9, 7).
touching(10, 7).
touching(11, 7).
touching(12, 7).
touching(13, 7).
touching(14, 7).
%touching(2, 8).
%touching(3, 8).
%touching(4, 8).
%touching(7, 8).
%touching(4, 9).
%touching(5, 9).
%touching(6, 9).
%touching(7, 9).
%touching(7, 10).
%touching(7, 11).
%touching(7, 12).
%touching(7, 13).
%touching(7, 14).
touching(15, 14).
%touching(14, 15).
touching(16, 15).
%touching(15, 16).
adjacent(RoomA, RoomB) :-
touching(RoomA, RoomB)
; touching(RoomB, RoomA).
path_to_phone(FirstRoom, LastRoom,Path) :- % Base Case
ringing(LastRoom),
%touching(FirstRoom, X),
travel(FirstRoom, LastRoom, [FirstRoom],Q),
reverse(Q,Path).
travel(FirstRoom, LastRoom,P, [LastRoom|P]) :-
% write('who call this\n'),
adjacent(FirstRoom,LastRoom).
travel(FirstRoom,LastRoom, Visited,Path) :-
adjacent(FirstRoom,X), %touching(FirstRoom,X),
X \== LastRoom,
\+member(X,Visited),
%write(visited),
travel(X,LastRoom,[X|Visited],Path).
%write('call?\n').
要获得最短路径,在这种情况下,您可以使用
[trace] ?- path_to_phone(2,5,A).
A = [2, 1, 7, 8, 4, 9, 5] ;
A = [2, 1, 7, 8, 4, 9, 6, 5] ;
A = [2, 1, 7, 9, 5] ;
A = [2, 1, 7, 9, 6, 5] ;
A = [2, 8, 4, 9, 5] ;
A = [2, 8, 4, 9, 6, 5] ;
A = [2, 8, 7, 9, 5] ;
A = [2, 8, 7, 9, 6, 5] ;
false.
,findall
和length
来获得答案,因为问题的大小非常小。
当节点数很大时,您可以使用sort
算法来获得最短路径。它需要实现breadth first search
数据结构。