2

我有表 mxn 和点对。例如,我们可以有表 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 中实现。真的,我有很大的问题,请帮助我。

4

1 回答 1

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)]
于 2013-06-20T06:45:22.687 回答