我有表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)
(如果更多解决,我想拥有所有)
有任何概念我怎么能在哈斯克尔做到这一点?
也许你可以用文字解释你的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)旁边的点,然后我们检查几个条件(例如,if(I3,J3)是否属于任何其他路径 - 这是错误的点)。然后我们递归地生成从(I1,J1)到(I3,J3)的路径。我们有问题,当(I3,J3)是路径的结束时,因为(I3,J3)属于输入和条件+成员((I3,J3),输入)不满足。
因此,我写了最后一个谓词:
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中制作它。真的,我有很大问题,请帮助我。
答案 0 :(得分:1)
您的代码翻译为
go m n (i,j) =
[ (i+1,j) | i<m ] ++
[ (i-1,j) | i>1 ] ++
[ (i,j+1) | j<n ] ++
[ (i,j-1) | j>1 ]
-- isEndOfPath p q = p == q
genPath p q acc m n input buf = head $ -- since you have a cut there
g p q acc buf
where
g p q acc buf | p==q = [(acc,buf)] -- return acc, buf
g p q acc buf = [s |
r <- go m n q, notElem r buf, notElem r acc,
notElem r input,
s <- g p r (r:acc) (r:buf)] ++
[s |
r <- go m n q, notElem r acc,
r==p,
s <- g p r (r:acc) (r:buf)]