SWI-Prolog中的寻路(生成和测试方法)

时间:2018-04-14 15:43:22

标签: prolog

好的,所以我正在尝试构建一个路径搜索SWI-Prolog程序,让网格遍历'知识库中的事实属性:

y_max(Ymax).
x_max(Xmax).
pick_up(Y,X).

例如,下面的代码代表它下面的网格:

y_max(6).
x_max(6).
pick_up(4,4).
pick_up(3,2).

% 6 | | | | | |F|
%   -------------
% 5 | | | | | | |
%   -------------
% 4 | | | |P| | |
%   -------------
% 3 | |P| | | | |
%   -------------
% 2 | | | | | | |
%   -------------
% 1 |L| | | | | |
%    1 2 3 4 5 6

% (Note that coordinates will be in the form [Y,X].

其中F是路径的起点,是[6,6],L是路径的末端,[1,1],路径应该是这样的,以便有多少pick_up&#34 ;对象"沿路径尽可能地被拾起。所以在这种情况下,#34;理想"解决方案是:

% 6 | | | | |X|F|
%   -------------
% 5 | | | |X|X| |
%   -------------
% 4 | |X|X|P| | |
%   -------------
% 3 |X|P| | | | |
%   -------------
% 2 |X| | | | | |
%   -------------
% 1 |L| | | | | |
%    1 2 3 4 5 6

路径P将是: P = [[6,6],[6,5],[5,5],[5,4],[4,4],[4,3],[4,2],[3,2] ,[3,1],[2,1],[1,1]]

我的主要关系是:

solve(P,A) :-

将根据给出图形的知识库返回理想(最短)路径P和A,其中A是路径拾取的拾取对象的数量(应该是拾取对象的最大数量)可以拿起来。

我试图使用生成和测试类型方法来做到这一点。因为根据知识库无法知道路径的长度(据我所知),我假设我必须递归生成和测试坐标?我试图在不使用任何库的情况下进行这项练习,以便真正掌握这种Prolog编程风格,在此我生成并测试路径。

这是我到目前为止所做的,但我似乎无法做到这一点。相反,它只是给我一个ERROR:每次都超出全局堆栈。

% FACTS
y_max(6).
x_max(6).
pick_up(5,5).
pick_up(4,4).
pick_up(2,2).

solve(A,P) :-
   y_max(Y), x_max(X), aggregate_all(count,pick_up(O,E),C),
   A = C, append(P,[Y,X],Np), build_path(Y,X,Y,X,P),                                                                                                                                         
   % I'm assuming at this point the list is generated, now to test...
   member([Y,X],P), is_last([1,1],P), member([O,E],P).

% cases to end recursion - not sure if I'm doing this part correctly...                                                                                                                                        
build_path(Y,X,1,2,P) :- append(P,[1,1],Q), P = Q.
build_path(Y,X,2,1,P) :- append(P,[1,1],Q), P = Q.

% recursive case                                                                                                                                                                                               
build_path(Y,X,PrevY,PrevX,P) :-
   integer(NextY), integer(NextX),
   NextY =< Y, NextY >= 1,
   NextX =< X, NextY >= 1,
   (  (NextY =:= PrevY-1, NextX =:= PrevX)
   ;  (NextY =:= PrevY+1, NextX =:= PrevX)
   ;  (NextY =:= PrevY, NextX =:= PrevX+1)
   ;  (NextY =:= PrevY, NextX =:= PrevX-1)
   ),
   append(P,[NextY,NextX],Np),
   build_path(Y,X,NextY,NextX,Np).

is_last([Y,X],[H|[]]) :- H = [Y,X].
is_last([Y,X],[H|T]) :- is_last([Y,X],T).

那么,我做错了什么?我似乎无法在网上找到一个类似的例子来给我一个正确的想法。我假设我只是过于复杂的事情或者没有正确地向Prolog表达某些信息。如果我的解决方案充满错误,我道歉。我现在正试图掌握Prolog。

2 个答案:

答案 0 :(得分:2)

以下版本似乎有效build_path(MaxY,MaxX,Y0,X0,P0,P,Is0,Is) :- ( Y0 = 1, X0 = 1 -> P = P0, Is = Is0 ; ( Y is Y0 - 1, X is X0 ; Y is Y0 + 1, X is X0 ; Y is Y0, X is X0 + 1 ; Y is Y0, X is X0 - 1 ), Y =< MaxY, Y >= 1, X =< MaxX, X >= 1, \+ member(Y-X,P0), append(P0,[Y-X],P1), ( pick_up(Y,X) -> Is1 = [Y-X|Is0] ; Is1 = Is0 ), build_path(MaxY,MaxX,Y,X,P1,P,Is1,Is) ).

 "policy": {
            "validation": {
                "minimumSizeMB": 0.000005
            }
        }

你需要确保它在到达正方形时停止,所以你需要使用if-then-else或cut。

我添加了一个拾取项目列表,所以现在你只需要找到路径和列表的最佳组合。

答案 1 :(得分:0)

我没有深入阅读你的节目,但至少这些观点似乎不正确:

  1. NextY =:= PrevY-1部分应更改为NextY is PrevY - 1=:=仅用于比较,而不是用于设置值。

  2. 您的代码似乎在build_path处于无限循环中,因为您不检查genarated下一个coodinates不在coodinates列表中。

  3. 3. integer(NextY), integer(NextX),总是失败,因为它们是新变量而没有设置任何值,因为它们不是整数。

    1. 并且您不会检查生成的坐标不在董事会之外。

    2. 你正在尝试depth first search算法。在你使这个程序工作之后,遗憾的是,第一个回答将远离最短路径。当你想要获得最短路径时,我建议breadth first search algorithm

相关问题