我需要在网格中的两个给定点之间构建所有可能的路径,如此
[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(;)运算符。但我不知道如何让它生成所有路径。
答案 0 :(得分:1)
我试图清理你的代码......
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.
值得注意的是主要是生成和测试之间的分离。您将位置更新和检查捆绑在一起,这使您的代码更容易出错。