9

我查看了类似的问题,但找不到与我的问题相关的任何内容。我正在努力寻找一个算法或一组“循环”来找到从CityAto的路径CityB,使用

distance(City1,City2,Distance)

事实。到目前为止,我设法做的事情如下,但它总是回溯write(X),到最后一次迭代,然后完成,这是我希望它做的,但只是在一定程度上。

例如,我不希望它打印出任何死胡同的城市名称,或者使用最终迭代。我希望它基本上形成一条从CityAto的路径,在路径上CityB写下它去往的城市的名称。

我希望有人能帮助我!

all_possible_paths(CityA, CityB) :-
    write(CityA),
    nl,
    loop_process(CityA, CityB).

loop_process(CityA, CityB) :- 
    CityA == CityB.
loop_process(CityA, CityB) :-
    CityA \== CityB,
    distance(CityA, X, _),
    write(X),
    nl,
    loop_process(X, CityB).
4

3 回答 3

8

我试图展示如何实现你正在做的事情,以便你可以更好地理解它是如何工作的。因此,由于您的 OP 不是很完整,所以我冒昧了!以下是我正在处理的事实:

road(birmingham,bristol, 9).
road(london,birmingham, 3).
road(london,bristol, 6).
road(london,plymouth, 5).
road(plymouth,london, 5).
road(portsmouth,london, 4).
road(portsmouth,plymouth, 8).

这是我们将调用以查找路径的谓词get_road/4。它基本上调用了工作谓词,它有两个累加器(一个用于已经访问过的点,一个用于我们经过的距离)。

get_road(Start, End, Visited, Result) :-
    get_road(Start, End, [Start], 0, Visited, Result).

这是工作谓词
get_road/6: get_road(+Start, +End, +Waypoints, +DistanceAcc, -Visited, -TotalDistance) :
第一个子句告诉我们第一个点和最后一个点之间是否有道路,我们可以在这里结束。

get_road(Start, End, Waypoints, DistanceAcc, Visited, TotalDistance) :-
    road(Start, End, Distance),
    reverse([End|Waypoints], Visited),
    TotalDistance is DistanceAcc + Distance.

第二个子句告诉如果我们的第一个点和一个中间点之间有一条路,我们可以走它然后解决get_road(intermediate, end)。

get_road(Start, End, Waypoints, DistanceAcc, Visited, TotalDistance) :-
    road(Start, Waypoint, Distance),
    \+ member(Waypoint, Waypoints),
    NewDistanceAcc is DistanceAcc + Distance,
    get_road(Waypoint, End, [Waypoint|Waypoints], NewDistanceAcc, Visited, TotalDistance).

用法如下:

?- get_road(portsmouth, plymouth, Visited, Distance).

和产量:

Visited = [portsmouth, plymouth],
Distance = 8 ;
Visited = [portsmouth, london, plymouth],
Distance = 9 ;
Visited = [portsmouth, plymouth, london, plymouth],
Distance = 18 ;
false.

我希望它对你有帮助。

于 2011-11-29T22:57:33.013 回答
4

请把纯的部分和不纯的部分分开(I/O,比如write/1nl/0还有(==)/2(\==)/2)。只要它们完全与您的纯代码交织在一起,您就不能期望太多。

可能您想要起点、终点和两者之间的路径之间的关系。

该路径应该是非循环的还是您允许循环

为了确保一个元素X不会出现在列表中,请Xs使用目标maplist(dif(X),Xs). 您不需要任何进一步的辅助谓词来使其成为一个很好的关系!

于 2011-11-29T22:43:56.270 回答
1

您应该在 all_possible_paths 中将成功列表作为 Out 变量返回。然后写出那个清单。不要在同一过程中同时执行这两项操作。

于 2011-11-29T22:10:35.187 回答