我使用的伊万·布拉科书序言研究:人工智能编程,我发现了一些困难,实现一个运动提出的最后一部分
这次演习是使用图形来决定如何移动块,对他们的顺序安排节目。
这是关系到程序必须做的图像:
正如可以在先前IMMAGE见块A,B,C可以使用许多可容许移动被移动:
块可以仅当它是在该堆的顶部上移动
块可以在地面上被移动(上空隙栈)
块可以在另一个块被移动(在另一个堆叠的包含一些其它块顶部)
因此,这些移动受理诱导一个状态,图中的另一种状态,像这样的东西之间的可能的转换的图表:
所以,你可以在本身前面的图,我可以用rappresent 3子列表列表的情况。
每个子列表rappresent堆在那里我可以根据先前的限制把块
因此,例如前一图的中心节点的情况可表示为:
[[A], [B], [C]]
因为每个堆叠包含单个块。
通过在左上角,其中我一个堆叠中的其它块C,A下方的节点所表示的情况,B可以表示为:
[[C,A,B], [], []]
好了,我的计划是下列之一:
del(X, [X|Tail], Tail).
del(X, [Y|Tail], [Y|Tail1]) :- del(X, Tail, Tail1).
/* s(CurrentState, SuccessorState): Predicate that calculate a legal move from
the CurrentState to the SuccessorState:
*/
s(Stacks, [Stack1, [Top1|Stack2] | OtherStacks]) :-
del( [Top1|Stack1], Stacks, Stacks1),
del( Stack2, Stacks1, OtherStacks).
goal(Situation) :- member([a,b,c], Situation).
在这最后的日子我已经深入研究它,我理解它是如何工作的。
基本S / 3谓词是我的继任函数s(CurrentState, SuccessorState)
计算从一个合法的移动CurrentState
到SuccessorState
。
这个谓词效果很好,其实如果我启动以下查询:
[debug] ?- s([[a,b,c],[],[]],R).
R = [[b, c], [a], []]
我获得[[B,C],[A],[]是用于将状态的后续状态 [[A,B,C],[],[]],这是好事,因为我已移动a
块从所述第二堆栈的顶部的第一堆栈的顶部(这是无效),这是一个完全合法的举动。
好了,去上我的goal/1
谓词说,当我已经达到了一个最终状态(当计算必须停止):
goal(Situation) :- member([a,b,c], Situation).
它说的情况(具体的堆栈列表配置)是一个目标的情况,如果在相关堆栈列出有一个堆栈是[A,B,C]名单。
所以下面的情况是目标的情况:
[[a,b,c],[],[]]
[[], [a,b,c],[]]
[[],[], [a,b,c]]
好了,现在我的问题是下面的一个:我要实现的solve/2
谓词是这样的:
solve([[c,a,b],[],[]], Situation)
从一个传递情况开始(在这种情况下,具有在第一堆栈中的所有块与堆叠的名单c
在地面上, b
在中间, a
在顶部)和到达目标的情况。
我不知道到底是什么我必须做的,我怎么也得解决这个问题(可惜我没有老师)
我试图激发自己看着这个版本的八皇后问题,即使用了类似的编程技术(其中我有一个目标,以满足和解决谓语):
s(Queens, [Queen|Queens]) :- member(Queen, [1,2,3,4,5,6,7,8]),
noattack(Queen, Queens, 1).
goal([_,_,_,_,_,_,_,_]).
noattack(_,[],_) :- !.
noattack(Y,[Y1|Ylist],Xdist) :- Y =\= Y1,
Y1-Y =\= Xdist,
Y-Y1 =\= Xdist,
Dist1 is Xdist + 1,
noattack(Y,Ylist,Dist1).
solve(N,[N]) :- goal(N). % sample call: solve([], X).
solve(N, [N|Sol1]) :- s(N,N1),
solve(N1,Sol1).