Recursion 如何在PROLOG中找到两个站点之间的路由

Recursion 如何在PROLOG中找到两个站点之间的路由,recursion,routes,prolog,predicate,transitive-closure,Recursion,Routes,Prolog,Predicate,Transitive Closure,对不起,我知道这个问题经常出现,但我做了很多研究,我就是不知道如何解决这个问题。我在PROLOG中表示了一个tube映射,需要编写一个谓词来返回两个站点之间的所有路由。我知道我需要使用递归,并尝试了一系列不同的解决方案,但没有一个是有效的。我掌握的事实是: station('AL',[metropolitan]).%Aldgate on the Metropolitan Line station('BG',[central]).%Bethnal Green on the Central Line

对不起,我知道这个问题经常出现,但我做了很多研究,我就是不知道如何解决这个问题。我在PROLOG中表示了一个tube映射,需要编写一个谓词来返回两个站点之间的所有路由。我知道我需要使用递归,并尝试了一系列不同的解决方案,但没有一个是有效的。我掌握的事实是:

station('AL',[metropolitan]).%Aldgate on the Metropolitan Line
station('BG',[central]).%Bethnal Green on the Central Line
station('BR',[victoria]).%Brixton on the Victoria Line
station('BS',[metropolitan]).%Baker Street on the Metropolitan Line
station('CL',[central]).%Chancery Lane on the Central Line
station('EC',[bakerloo]).%Elephant & Castle on the Bakerloo Line
station('EM',[bakerloo,northern]).%Embankment on the Bakerloo and Northern Lines
station('EU',[northern]).%Euston on the Northern Line
station('FP',[victoria]).%Finsbury Park on the Victoria Line
station('FR',[metropolitan]).%Finchley Road on the Metropolitan Line
station('KE',[northern]).%Kennington on the Northern Line
station('KX',[metropolitan,victoria]).%Kings Cross on the Metropolitan and Victoria Lines
station('LG',[central]).%Lancaster Gate on the Central Line
station('LS',[central,metropolitan]).%Liverpool Street on the Central and Metropolitan Lines
station('NH',[central]).%Notting Hill Gate on the Central Line
station('OC',[bakerloo,central,victoria]).%Oxford Circus on the Bakerloo, Central and Victoria Lines
station('PA',[bakerloo]).%Paddington on the Bakerloo Line
station('TC',[central,northern]).%Tottenham Court Road on the Central and Northern Lines
station('VI',[victoria]).%Victoria on the Victoria Line
station('WA',[bakerloo]).%Warwick Avenue on the Bakerloo Line
station('WS',[northern,victoria]).%Warren Street on the Northern and Victoria Lines
adjacent('WA','PA').%Warwick Avenue is adjacent to Paddington
adjacent('PA','OC').%Paddington is adjacent to Oxford Circus
adjacent('OC','EM').%Oxford Circus is adjacent to Embankment
adjacent('EM','EC').%Embankment is adjacent to Elephant & Castle
adjacent('NH','LG').%Notting Hill Gate is adjacent to Lancaster Gate
adjacent('LG','OC').%Lancaster Gate is adjacent to Oxford Circus
adjacent('OC','TC').%Oxford Circus is adjacent to Tottenham Court Road
adjacent('TC','CL').%Tottenham Court Road is adjacent to Chancery Lane
adjacent('CL','LS').%Chancery Lane is adjacent to Lviverpool Street
adjacent('LS','BG').%Liverpool Street is adjacent to Bethnal Green
adjacent('FR','BS').%Finchley Road is adjacent to Baker Street
adjacent('BS','KX').%Baker Street is adjacent to Kings Cross
adjacent('KX','LS').%Kings Cross is adjacent to Liverpool Street
adjacent('LS','AL').%Liverpool Street is adjacent to Algate
adjacent('EU','WS').%Euston is adjacent Warren Street
adjacent('WS','TC').%Warren Street is adjacent to Tottenham Court Road
adjacent('TC','EM').%Tottenham Court Road is adjacent to Embankment
adjacent('EM','KE').%Embankment is adjacent to Kennington
adjacent('BR','VI').%Brixton is adjacent to Victoria
adjacent('VI','OC').%Victoria is adjacent to Oxford Circus
adjacent('OC','WS').%Oxford Circus is adjacent to Warren Street
adjacent('WS','KX').%Warrent Street is adjacent to Kings Cross
adjacent('KX','FP').%Kings Cross is adjacent to Finsbury Park
我尝试过的解决方案是:

route(From,To,Route) :-
   routeattempt(From,To,[From],Route),
   reverse(Route,route).

routeattempt(From,To,Inbetween,Route) :-
   adjacent(From,To),
   \+member(From,Inbetween),
   Route = [From|Inbetween].
routeattempt(From,To,Visited,Route) :-
   adjacent(From,Inbetween),
   Inbetween \== To,
   \+member(Inbetween,Visited),
   routeattempt(Inbetween,To,Inbetween|Visited],Route).
但它只是对任何输入返回false。如果有人能帮忙,那就太好了。

这让人困惑

这个想法显然是为了
路线尝试/4
找到一条从
的路线,并将其存储为
路线中的站点列表。但是参数3,这里的
[from]
到底做了什么?它似乎是访问站点的列表,但您真的需要它吗?您已经有了
路线了

现在您必须创建子类:
From
to
相邻:

routeattempt(From,To,Inbetween,Route) :-
   adjacent(From,To),
   \+member(From,Inbetween),
   Route = [From|Inbetween].
或者它们不是:

routeattempt(From,To,Visited,Route) :-
   adjacent(From,Inbetween),
   Inbetween \== To,
   \+member(Inbetween,Visited),
   routeattempt(Inbetween,To,Inbetween|Visited],Route).
在第一种情况下(基本情况),不清楚为什么要检查
From
是否是
interween
的成员。事实上,这将排除在两个相邻站点之间找到任何路由,因为
route/3
将已将
From
存入列表
interween
。两个相邻站点之间的路由不应该不存在吗只要是
[从,到]
,而不是
[从中间]

在第二种情况下,通过中间的路站
,这也不等于
,而且还没有被访问过。好的。但是在递归调用之后,您需要完成
路由


尝试在
相邻/2
之前添加
格式(“当前路由从~w到~w:~w\n,[from,to,route])
,看看会发生什么。

route/2谓词的第三行显示
反向(route,route).
这不可能是正确的,第二个
路由是一个常量。您要将
路由
反转到输出中,因此需要输出中出现的
路由。
最后一行中还有一个语法错误:
路由尝试(中间,到,中间,已访问),路由).
有一个未关闭的列表。因此,将注释“%Aldgate on the Metropolitan Line”作为值放入事实中:
station('FR',[Metropolitan],“Finchley Road on the Metropolitan Line”)
。然后您可以在以后打印时使用它们。此时,当然不使用
station/2
routeattempt(From,To,Visited,Route) :-
   adjacent(From,Inbetween),
   Inbetween \== To,
   \+member(Inbetween,Visited),
   routeattempt(Inbetween,To,Inbetween|Visited],Route).