【发布时间】:2013-06-18 13:43:04
【问题描述】:
我有表 m x n 和点对。例如,我们可以有 3 x 3 的表格和点对:
A = (1,3),(3,2) B = (1,2),(3,1)
我必须找到所有成对连接点的路径。这些路径不能相互交叉。我们可以向左、向右、向下和向上。在前面的示例中,我们有以下路径:
A = (1,3) -> (2,3) -> (3,3) -> (3,2) B = (1,2) -> (2,2) -> (2,1) -> (3,1)
(如果有更多的解决方案,我想要全部)
有没有人知道如何在 haskell 中做到这一点?
也许你可以用语言解释你的 Prolog 算法
好的,我还有我的代码,所以:
我有四个谓词去左、右、上和下。
go((I1,J1),(I2,J2),_,_) :-
J1 is J2,
I2>=2,
I1 is I2 - 1.
go((I1,J1),(I2,J2),_,N) :-
I1 is I2,
J2=<N-1,
J1 is J2 + 1.
go((I1,J1),(I2,J2),M,_) :-
J1 is J2,
I2=<M-1,
I1 is I2 + 1.
go((I1,J1),(I2,J2),_,_) :-
I1 is I2,
J2>=2,
J1 is J2 - 1.
例如go((I,J),(3,3),5,5) 返回
(I,J) = (2,3)
(I,J) = (4,3)
(I,J) = (3,2)
(I,J) = (3,4)
当然,参数 5 是表格的大小 - 这里我们有表格 5x5。
我一定知道,什么时候结束,所以我写道:
endOfPath((I1,J1),(I2,J2)) :-
I1 == I2,
J1 == J2.
然后我可以生成从点 (I1,J1) 到 (I2,J2) 的路径的谓词。首先我们必须检查它是否是路径的结尾:
generatePath((I1,J1),(I2,J2),T,T,_,_,_,B,B) :-
endOfPath((I1,J1),(I2,J2)),!.
如果它不是路径的尽头,我们必须递归地生成路径。
generatePath((I1,J1),(I2,J2), Acc,T,M,N,Input,Bufor,NewBufor) :-
go((I3,J3),(I2,J2),M,N),
\+ member((I3,J3),Bufor),
\+ member((I3,J3),Acc),
\+ member((I3,J3),Input),
generatePath((I1,J1),(I3,J3),[(I3,J3)|Acc],T,M,N,Input,[(I3,J3)|Bufor],NewBufor).
因此,首先我们找到直接在 (I2,J2) 旁边的点,然后我们检查几个条件(例如,如果 (I3,J3) 属于任何其他路径 - 这是错误的点)。然后我们递归地生成从 (I1,J1) 到 (I3,J3) 的路径。我们有问题,当 (I3,J3) 是路径的结尾时,因为 (I3,J3) 属于 Input 并且条件 + member((I3,J3),Input) 不满足。
因此,我写了最后一个谓词:
generatePath((I1,J1),(I2,J2), Acc,T,M,N,Input,Bufor,NewBufor) :-
go((I3,J3),(I2,J2),M,N),
\+ member((I3,J3),Acc),
I3 == I1, J3 == J1,
generatePath((I1,J1),(I3,J3),[(I3,J3)|Acc],T,M,N,Input,[(I3,J3)|Bufor],NewBufor).
这很容易并且效果很好,但我不知道如何在 Haskell 中实现。真的,我有很大的问题,请帮助我。
【问题讨论】:
-
你试过什么?您是否能够用任何其他语言解决并努力在 haskell 中实现它?它看起来是一个算法问题,与 haskell 无关,直到您说出您卡在哪里并需要有关 haskell 实施的帮助。
-
我在 Prolog 中完成了这项任务。但我不知道如何找到两点之间的任何路径。在序言中这很容易,但我不知道如何在 Haskell 中做到这一点。如何找到两点之间的任何路径?
-
我认为你也可以标记prolog并添加你尝试过的prolog代码。
-
你非得走向另一点吗? B 路径可以从 (1,2) -> (1,3) 开始吗?
-
@DiegoNolan - B 路径无法开始 (1,2) -> (1,3) 因为点 (1,3) 属于路径 A(这是该路径的起点) .
标签: haskell