簡體   English   中英

swi-prolog查找網格中的所有路徑

[英]swi-prolog find all paths in grid

我需要像這樣在網格中的兩個給定點之間建立所有可能的路徑

 [1,1][2,1][3,1][4,1][5,1]
 [1,2][2,2][3,2][4,2][5,2]
 [1,3][2,3][3,3][4,3][5,3]
 [1,4][2,4][3,4][4,4][5,4]
 [1,5][2,5][3,5][4,5][5,5]

我有一個名為doesnt_contain的實用程序(無論是什么),它檢查元素是否已在路徑中,以避免循環。 我嘗試從給定的點開始,在每一步中,我都想向北,向東南和向西走。 當達到目標時,我將該路徑添加到所有可能路徑的列表中。 這是代碼:

doesnt_contain([], _, _).
doesnt_contain([[H1|[H2|_]]|T], X, Y):- (X =\= H1; Y =\= H2), doesnt_contain(T, X, Y).
doesnt_contain([[H1|[H2|_]]|_], X, Y):- X == H1, Y == H2, fail.

build_paths(X1, Y1, X2, Y2, _, L, AL):- X1 =:= X2, Y1 =:= Y2, write([L|AL]).
build_paths(X1, Y1, X2, Y2, Limit, L, AL):-
    (X1 =\= X2; Y1 =\= Y2),
    ((X1 < Limit, X is X1 + 1, doesnt_contain(L, X, Y1), 
    build_paths(X, Y1, X2, Y2, Limit, [[X, Y1]|L], AL));
    (Y1 < Limit, Y is Y1 + 1, doesnt_contain(L, X1, Y), 
    build_paths(X1, Y, X2, Y2, Limit, [[X1, Y]|L], AL));
    (X1 > 1, X is X1 - 1, doesnt_contain(L, X, Y1), 
    build_paths(X, Y1, X2, Y2, Limit, [[X, Y1]|L], AL));
    (Y1 > 1, Y is Y1 - 1, doesnt_contain(L, X1, Y), 
    build_paths(X1, Y, X2, Y2, Limit, [[X1, Y]|L], AL))).

還有一個按以下順序進行參數輸出的示例:(開始X),(開始Y),(結束X),(結束Y),(網格限制),(包括開始的初始路徑),(所有路徑的列表) )。

?- build_paths(2, 2, 4, 4, 5, [[2,2]], []).
[[[4,4],[3,4],[2,4],[1,4],[1,5],[2,5],[3,5],[4,5],[5,5],[5,4],[5,3],[5,2],[4,2],[3,2],[2,2]]]
true .

這段代碼給了我一條路徑,然后停了下來。 我需要所有可能的路徑。 我想我知道為什么找到第一個路徑后它就會停止。 這是因為運算符or(;)。 但是我不知道如何使它生成所有路徑。

我試圖清理您的代碼...

build_paths(P, P, _, L) :- !, writeln(L).
build_paths(P1, P2, Limit, Ps) :-
    move(P1, P, Limit),
    \+ memberchk(P, Ps),
    build_paths(P, P2, Limit, [P|Ps]).

move([X1,Y1], [X,Y], Limit) :-
    X1 < Limit, X is X1 + 1, Y is Y1 ;
    Y1 < Limit, Y is Y1 + 1, X is X1 ;
    X1 > 1, X is X1 - 1, Y is Y1 ;
    Y1 > 1, Y is Y1 - 1, X is X1.

用它來稱呼它

?- aggregate(count, build_paths([2, 2], [4, 4], 5, []), CountSol).

我懂了

...
[[4,4],[3,4],[3,3],[4,3],[4,2],[4,1],[3,1],[3,2],[2,2],[2,3],[2,4],[2,5],[1,5],[1,4],[1,3],[1,2],[1,1],[2,1]]
[[4,4],[5,4],[5,5],[4,5],[3,5],[3,4],[3,3],[4,3],[4,2],[4,1],[3,1],[3,2],[2,2],[2,3],[2,4],[2,5],[1,5],[1,4],[1,3],[1,2],[1,1],[2,1]]
[[4,4],[4,5],[3,5],[3,4],[3,3],[4,3],[4,2],[4,1],[3,1],[3,2],[2,2],[2,3],[2,4],[2,5],[1,5],[1,4],[1,3],[1,2],[1,1],[2,1]]
CountSol = 18184.

值得注意的主要是生成和測試之間的分離。 您將位置更新和檢查聯系在一起,這使您的代碼更容易出錯。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM