正如标题所说,我必须制作一个prolog程序,使用最佳优先搜索解决8个难题,我是Prolog和A.I的新手。所以我很难过。
现在我所拥有的是移动规则:
%% move left in the top row
move([X1,0,X3, X4,X5,X6, X7,X8,X9],
[0,X1,X3, X4,X5,X6, X7,X8,X9]).
move([X1,X2,0, X4,X5,X6, X7,X8,X9],
[X1,0,X2, X4,X5,X6, X7,X8,X9]).
%% move left in the middle row
move([X1,X2,X3, X4,0,X6,X7,X8,X9],
[X1,X2,X3, 0,X4,X6,X7,X8,X9]).
move([X1,X2,X3, X4,X5,0,X7,X8,X9],
[X1,X2,X3, X4,0,X5,X7,X8,X9]).
%% move left in the bottom row
move([X1,X2,X3, X4,X5,X6, X7,0,X9],
[X1,X2,X3, X4,X5,X6, 0,X7,X9]).
move([X1,X2,X3, X4,X5,X6, X7,X8,0],
[X1,X2,X3, X4,X5,X6, X7,0,X8]).
%% move right in the top row
move([0,X2,X3, X4,X5,X6, X7,X8,X9],
[X2,0,X3, X4,X5,X6, X7,X8,X9]).
move([X1,0,X3, X4,X5,X6, X7,X8,X9],
[X1,X3,0, X4,X5,X6, X7,X8,X9]).
%% move right in the middle row
move([X1,X2,X3, 0,X5,X6, X7,X8,X9],
[X1,X2,X3, X5,0,X6, X7,X8,X9]).
move([X1,X2,X3, X4,0,X6, X7,X8,X9],
[X1,X2,X3, X4,X6,0, X7,X8,X9]).
%% move right in the bottom row
move([X1,X2,X3, X4,X5,X6,0,X8,X9],
[X1,X2,X3, X4,X5,X6,X8,0,X9]).
move([X1,X2,X3, X4,X5,X6,X7,0,X9],
[X1,X2,X3, X4,X5,X6,X7,X9,0]).
%% move up from the middle row
move([X1,X2,X3, 0,X5,X6, X7,X8,X9],
[0,X2,X3, X1,X5,X6, X7,X8,X9]).
move([X1,X2,X3, X4,0,X6, X7,X8,X9],
[X1,0,X3, X4,X2,X6, X7,X8,X9]).
move([X1,X2,X3, X4,X5,0, X7,X8,X9],
[X1,X2,0, X4,X5,X3, X7,X8,X9]).
%% move up from the bottom row
move([X1,X2,X3, X4,X5,X6, X7,0,X9],
[X1,X2,X3, X4,0,X6, X7,X5,X9]).
move([X1,X2,X3, X4,X5,X6, X7,X8,0],
[X1,X2,X3, X4,X5,0, X7,X8,X6]).
move([X1,X2,X3, X4,X5,X6, 0,X8,X9],
[X1,X2,X3, 0,X5,X6, X4,X8,X9]).
%% move down from the top row
move([0,X2,X3, X4,X5,X6, X7,X8,X9],
[X4,X2,X3, 0,X5,X6, X7,X8,X9]).
move([X1,0,X3, X4,X5,X6, X7,X8,X9],
[X1,X5,X3, X4,0,X6, X7,X8,X9]).
move([X1,X2,0, X4,X5,X6, X7,X8,X9],
[X1,X2,X6, X4,X5,0, X7,X8,X9]).
%% move down from the middle row
move([X1,X2,X3, 0,X5,X6, X7,X8,X9],
[X1,X2,X3, X7,X5,X6, 0,X8,X9]).
move([X1,X2,X3, X4,0,X6, X7,X8,X9],
[X1,X2,X3, X4,X8,X6, X7,0,X9]).
move([X1,X2,X3, X4,X5,0, X7,X8,X9],
[X1,X2,X3, X4,X5,X9, X7,X8,0]).
(我知道使用列表有一种更简单的方法,但这对我有用)
我在互联网上找到的最好的第一个代码:http://www.cs.unm.edu/~luger/ai-final/code/PROLOG.best.html
但是在最好的第一个代码中,有一个不运行的启发式函数:
go(Start, Goal) :-
empty_set(Closed),
empty_sort_queue(Empty_open),
heuristic(Start, Goal, H),
state_record(Start, nil, 0, H, H, First_record),
insert_sort_queue(First_record, Empty_open, Open),
path(Open,Closed, Goal).
我假设因为它没有在任何地方定义,我需要自己定义它,因为启发式方法会根据问题而改变。
所以我为8拼图使用了“瓦片不合适”的启发式,因为它听起来比曼哈顿距离或其他什么更容易编码。但现在我被困在如何编程,我在谷歌搜索如何比较列表和如何添加变量,我有点做了这个,我不知道是否会工作:
heuristic([],[],H).
heuristic([Head1|Tail1],[Head2|Tail2], H):-
not(samePlace(Head1,Head2))->H1 is H + 1,
heuristic(Tail1, Tail2, H1).
我的想法是它搜索开始列表的每个元素并将其与目标列表进行比较,然后如果它们不同,它会向H添加1,H为不合适的区块数。
我还定义了“同一地方的瓷砖规则”:
samePlace([X,_,_,_,_,_,_],[X,_,_,_,_,_,_]).
samePlace([_,X,_,_,_,_,_],[_,X,_,_,_,_,_]).
samePlace([_,_,X,_,_,_,_],[_,_,X,_,_,_,_]).
samePlace([_,_,_,X,_,_,_],[_,_,_,X,_,_,_]).
samePlace([_,_,_,_,X,_,_],[_,_,_,_,X,_,_]).
samePlace([_,_,_,_,_,X,_],[_,_,_,_,_,X,_]).
samePlace([_,_,_,_,_,_,X],[_,_,_,_,_,_,X]).
(etc...)
但当然我得到一个“错误:启发式/ 3:参数没有充分实例化”,我认为这意味着我从未初始化H。
我不知道代码的其余部分是如何工作的,所以我知道最好的第一个算法首先是广度,但是它将队列符号排序到启发式而不是仅添加到它。
我的问题是: - 我是在正确的轨道上,还是我完全想念那里的“启发式”功能意味着什么? - 我如何初始化H? - 我的“启发式”功能代码在语法上是否正确?
对于长篇文章感到抱歉,但规则确实说我应该提供大量信息。 我希望你可以帮助我,任何帮助都表示赞赏,所以如果你知道其他任何方式,请随意发布,我是一个菜鸟。
提前致谢。
答案 0 :(得分:0)
现在你错过了heuristic / 3中的else分支。这可能是有意的,但我认为如果samePlace(Head1,Head2)在某处是真的,这将无法返回一个值,从而开始回调调用代码。根据我的经验,这通常是后续奇怪错误消息的原因,就像您正在报告的那样。
另一个问题是,即使谓词成功,您也无法“返回”该值:尝试改为
heuristic([],[],0).
heuristic([Head1|Tail1],[Head2|Tail2], H):-
heuristic(Tail1, Tail2, H1),
( not(samePlace(Head1,Head2))
-> H is H1 + 1
; H is H1
).