2012-01-13 76 views
0

我有充分的事实,如数据库:序言 - 帮助固定规则

overground(newcrossgate,brockley,2). 
overground(brockley,honoroakpark,3). 
overground(honoroakpark,foresthill,3). 
overground(foresthill,sydenham,2). 
overground(sydenham,pengewest,3). 
overground(pengewest,anerley,2). 
overground(anerley,norwoodjunction,3). 
overground(norwoodjunction,westcroydon,8). 
overground(sydenham,crystalpalace,5). 
overground(highburyandislington,canonbury,2). 
overground(canonbury,dalstonjunction,3). 
overground(dalstonjunction,haggerston,1). 
overground(haggerston,hoxton,2). 
overground(hoxton,shoreditchhighstreet,3). 

例如:newcrossgate到Brockley的需要2分钟。

然后我创建了一个规则,这样如果我输入查询istime(newcrossgate,honoroakpark,Z)。那么prolog应该给我两个站之间的时间。 (我制定的规则旨在计算任何两个电台之间的距离,而不是相邻电台之间的距离)。

istime(X,Y,Z):- istime(X,Y,0,Z); istime(Y,X,0,Z). 
istime(X,Y,T,Z):- overground(X,Y,Z), T1 is T + Z. 
istime(X,Y,Z):- overground(X,A,T), istime(A,Y,T1), Z is T + T1. 
istime(X,Y,Z):- overground(X,B,T), istime(B,X,T1), Z is T + T1. 

它似乎适用于新的crossgate到第一对情侣站,比如newcrossgate到foresthill或sydenham。然而,在测试新赛季到westcroydon需要26分钟后,我尝试了新的crossgate进行crystalpalace,prolog说应该花费15分钟......尽管事实上它是westcroydon之后的下一站。很显然,这里有些事情是错误的,但是它对大多数电台都有效,偶尔会偶尔出现一些错误,谁能告诉我什么是错的? :S

+0

最后一项是否正确?你似乎从X到B,然后从B到X.你什么时候去Y? – mgibsonbr 2012-01-13 23:32:39

回答

1

您是否试图循环回答;? 26mins是 newcrossgate和westcroydon之间的最短时间...

编辑:我的坏!显然,较短的结果是由于代码中的错误(请参阅我对第4条的评论)。但是,您的代码是正确的,15分钟是newcrossgate和crystalpalace之间的最短路线。只是因为有一条从newcrossgate到westcroydon,然后是crystalpalace的路线,这并不意味着它是最短的路线,或者程序最先屈服的路线。

更新:如果你遇到了问题,以找到一些途径,我建议改变第三子句:

istime(X,Y,_,Z):- overground(X,A,T), istime(A,Y,T1), Z is T + T1. 

原因很简单:你的第一句话交换X与Y,这很好,因为你说的路线是对称的。然而,第3条款并没有从中受益,因为它从未被交换过的商品调用过。忽略第三个参数(你还没有使用它),从而让第一个子句调用第三个参数可能会解决你的问题,因为现在有一些以前没有使用的有效路由。

(也:我同意尼古拉斯·凯莉的答案,这将是更好地使用第三个参数作为蓄能器,但正如我所说,忽略它现在可能只是工作)

+0

我改变了从B到X的路由到B到Y的路由代码的最后一行,我希望那就是你的意思。我正在测试,看看它的工作是否完美。 (X,Y,Z): - 地上(X,B,T),istime(B,Y,T1),Z是T + T1。 – JimmyK 2012-01-14 11:44:16

+0

该死的似乎没有工作...每次我尝试一个较长的旅程,如里士满咆哮,我只是得到错误... – JimmyK 2012-01-14 11:56:53

+0

@JimmyK不是真的,如果仔细观察,改变的子句与第三个子句相同(将变量的名称从A更改为B无关紧要),因此它只会重复计算。 – mgibsonbr 2012-01-14 13:48:44

2

这在本质上是相同的问题作为你以前的问题,唯一的区别就是你需要随着时间累积时间。

我看到的一件事是你的“公开”谓词istime/3试图做太多。它应该做的就是种子累加器并调用工作者谓词istime/4。既然你正在寻找途径/时间在两个方向上,市民谓语应该只是

istime(X , Y , Z) :- istime(X , Y , 0 , Z) . 
istime(X , Y , Z) :- istime(Y , X , 0 , Z) . 

以上基本上是你的istime/3谓词的第一条

istime(X,Y,Z):- istime(X,Y,0,Z); istime(Y,X,0,Z). 

istime/3其余条款,递归的:

istime(X,Y,Z):- overground(X,A,T), istime(A,Y,T1), Z is T + T1. 
istime(X,Y,Z):- overground(X,B,T), istime(B,X,T1), Z is T + T1. 

应该适当地的istime/4一部分,并具有存在于蓄压器。这就是你的问题所在。

给它另一个镜头并编辑你的问题来显示下一个迭代。如果你仍然无法弄清楚,我会告诉你一些不同的方法来做到这一点。

一些提示

  1. 你的“工人”谓词可能会看起来很像你前面的练习“中找到两个站之间的路线”,但它有一个额外的参数,累加器的经过时间。

  2. 有两种特殊情况。如果您使用您在使用的方法“找两个站之间的路线”的解决方案,在特殊情况下是

    • A和B是直接相邻。
    • A和B通过至少一个中间停止点连接。

还有另一种方法为好,可能被描述为使用先行,在这种情况下,特殊情况是

  • A和B是相同的,在这种情况下你到达。
  • A和B不是且通过零个或多个中间停靠点连接。

FWIW,您不应该期望经过时间最短或跳数最少的路线成为第一个找到的解决方案。回溯将产生所有路线,但是它们的发现顺序与事实存储在数据库中的顺序有关。对图表的最低成本搜索完全是另一个鱼群。

+0

试着你现在说的,谢谢你的帮助。 – JimmyK 2012-01-14 11:46:01

1

为了使其发挥作用,您需要做与上一句中所述的旅程相反的操作。 将谓词保持原样,istime(X,Y,Z)并且只是生成另一个包含反向旅程的子句。 这种方式适用于所有车站。 (试过并测试过)

+0

嗯..似乎没有工作太好,我得到了两个不同的时间为同一个确切的旅程完成一种方式,然后在相反 – JimmyK 2012-01-14 16:41:20