如何使用Prolog在图表上找到所有连接的城市?

时间:2016-12-12 19:00:43

标签: prolog

程序应检查两个给定城市之间是否有直接路线。或者,它可以列出给定城市的所有连接城市。

我的解决方案是:

我列出了我访问过的城市名单。如果下一个城市不是我来自的城市,下一个城市的名字不在列表中,我让你按屏幕。

我的代码是:

% knowledge base

path(newyork,losangeles). 
path(losangeles,newyork). 

path(losangeles,chicago). 
path(chicago,losangeles). 

path(chicago,houston). 
path(houston,chicago). 

path(houston,newyork). 
path(newyork,houston). 

% rules
route(X,Y):-myroute(X,X,Y,[]).

myroute(X,Y,Z,_L):- path(Y,Z), not(X = Z).
myroute(X,Y,A,L):- path(Y,A), not(X = A) , not(member(A,L)),   
                   append(X,L,T) , myroute(Y,A,_Q,T). 

输出:

?- route(newyork,Y). 
Y = losangeles ;
Y = houston ;
false

预期产出:

?- route(newyork,Y). 
Y = losangeles ;
Y = chicago ;
Y = houston ;
false

我的代码检查两个给定城市之间是否有直接路线。它无法列出给定城市的所有连接城市。我在哪里犯错误?

1 个答案:

答案 0 :(得分:0)

让我们遵循您的代码逻辑:

?- route(newyork, Y).

Prolog尝试将其与数据库中的知识统一起来。它找到了这个定义:
route(X,Y):-myroute(X,X,Y,[]).

因此,Xnewyork统一,并继续检查是否为 根据{{​​1}}的定义,myroute(newyork, newyork, Y, [])是正确的。

Prolog在it数据库中找到该术语的匹配项,其中包含route谓词的第一个定义,并继续统一myrouteXY定义为_Lnewyorknewyork,即根据[]的定义检查是否可以满足myroute(newyork, newyork, Y, [])

根据myroute的第一个定义,prolog检查它是否可以在其数据库中找到满足myroute的事实,这样Z就不是newyork。对于path(newyork, Z)Z=losangeles,有两个事实可以满足这一要求。请注意,数据库中没有Z=houston事实,因此根据您当前的定义,这不符合答案。

另请注意,如果第一个path(newyork, chicago)定义失败,那么第二个定义失败,因为它首先检查完全相同的东西!因此,在这种情况下,通过回溯找不到其他解决方案。

你应该做什么
我不会为你解决你的运动(特别是因为你没有问我:p)但是一般来说,你的myroute谓语可能会如下工作:

myroute

并从myroute(StartPoint, EndPoint, RouteSoFar) :- % your definition here 调用,如此:

route

route(X, Y) :- myroute(X, Y, []). 是累加器;在第一个调用中,我们将其称为RouteSoFar,因为我们还没有访问任何节点,但在后续调用myroute时,它将是您在再次递归调用谓词之前添加的列表。在谓词定义的某处,您必须检查您要访问的节点是否已经在访问节点列表中。

myroute的逻辑是:"如果存在从X到Z(基本情况)的简单路径,或者存在从X到中间UNVISITED节点的路径,则存在从X到Z的myroute Y,然后是从Y到Z的myroute(递归情况)"。