我是prolog的新手。我在互联网上找到了广泛的第一个搜索程序,即搜索城市之间的路线。我想扩展程序来存储和计算距离。但我无法弄明白该怎么做。
原始代码:
move(loc(omaha), loc(chicago)).
move(loc(omaha), loc(denver)).
move(loc(chicago), loc(denver)).
move(loc(chicago), loc(los_angeles)).
move(loc(chicago), loc(omaha)).
move(loc(denver), loc(los_angeles)).
move(loc(denver), loc(omaha)).
move(loc(los_angeles), loc(chicago)).
move(loc(los_angeles), loc(denver)).
bfs(State, Goal, Path) :-
bfs_help([[State]], Goal, RevPath), reverse(RevPath, Path).
bfs_help([[Goal|Path]|_], Goal, [Goal|Path]).
bfs_help([Path|RestPaths], Goal, SolnPath) :-
extend(Path, NewPaths),
append(RestPaths, NewPaths, TotalPaths),
bfs_help(TotalPaths, Goal, SolnPath).
extend([State|Path], NewPaths) :-
bagof([NextState,State|Path],
(move(State, NextState), not(member(NextState, [State|Path]))),
NewPaths), !.
extend(_, []).
输出:
1 ?- bfs(loc(omaha), loc(chicago), X).
X = [loc(omaha), loc(chicago)] ;
X = [loc(omaha), loc(denver), loc(los_angeles), loc(chicago)] ;
false.
我试过这个:
bfs(A,B,Path,D) :-
bfs(A,B,Path),
path_distance(Path,D).
path_distance([_], 0).
path_distance([A,B|Cs], S1) :-
move(A,B,D),
path_distance(Cs,S2),
S1 is S2+D.
bfs(A,B, Path) :-
bfs_help([[A]], B, RevPath), reverse(RevPath, Path).
bfs_help([[Goal|Path]|_], Goal, [Goal|Path]).
bfs_help([Path|RestPaths], Goal, SolnPath) :-
extend(Path, NewPaths),
append(RestPaths, NewPaths, TotalPaths),
bfs_help(TotalPaths, Goal, SolnPath).
extend([State|Path], NewPaths) :-
bagof([NextState,State|Path],
(move(State, NextState,_), not(member(NextState, [State|Path]))),
NewPaths), !.
extend(_, []).
输出
5 ?- bfs(loc(omaha), loc(chicago), X,D).
false.
我想要的是什么:
1 ?- bfs(loc(omaha), loc(chicago), X, D).
X = [loc(omaha), loc(chicago)] ;
D = 1
X = [loc(omaha), loc(denver), loc(los_angeles), loc(chicago)] ;
D = 6
false.
请有人帮我解决这个问题! 抱歉我的英文。
答案 0 :(得分:2)
定义关系path_distance/2
似乎最便宜。那不是最优雅的方式,
但它应该符合你的目的:
bfs(A,B,Path,D) :-
bfs(A,B,Path),
path_distance(Path,D).
path_distance([_], 0).
path_distance([A,B|Cs], S1) :-
move(A,B,D),
path_distance([B|Cs],S2),
S1 is S2+D.
您可能还会重新考虑bfs/3
。查询
?- bfs(A,B, Path).
给出了相当奇怪的结果。
现在使用move/2
和move/3
。因此:
move(A,B) :-
move(A,B,_).
move(loc(omaha), loc(chicago),1).
move(loc(omaha), loc(denver),2).
move(loc(chicago), loc(denver),1).
move(loc(chicago), loc(los_angeles),2).
move(loc(chicago), loc(omaha),1).
move(loc(denver), loc(los_angeles),2).
move(loc(denver), loc(omaha),1).
move(loc(los_angeles), loc(chicago),2).
move(loc(los_angeles), loc(denver),3).