程序应检查两个给定城市之间是否有直接路线。或者,它可以列出给定城市的所有连接城市。
我的解决方案是:
我列出了我访问过的城市名单。如果下一个城市不是我来自的城市,下一个城市的名字不在列表中,我让你按屏幕。
我的代码是:
% 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
我的代码检查两个给定城市之间是否有直接路线。它无法列出给定城市的所有连接城市。我在哪里犯错误?
答案 0 :(得分:0)
让我们遵循您的代码逻辑:
?- route(newyork, Y).
Prolog尝试将其与数据库中的知识统一起来。它找到了这个定义:
route(X,Y):-myroute(X,X,Y,[]).
因此,X
与newyork
统一,并继续检查是否为
根据{{1}}的定义,myroute(newyork, newyork, Y, [])
是正确的。
Prolog在it数据库中找到该术语的匹配项,其中包含route
谓词的第一个定义,并继续统一myroute
,X
和Y
定义为_L
,newyork
和newyork
,即根据[]
的定义检查是否可以满足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(递归情况)"。