我正在尝试使用回溯来解决Prolog中的迷宫。
我的问题是,当我运行该程序时,它第一次可以正确运行,但是此后,它将结束位置作为起始位置,并一直从那里寻找路径,因此陷入了无限循环。当两个位置之间不存在路径时,它可以正常工作。我尝试了很多东西,但似乎没有任何效果。这是我的代码:
path(Dest, Dest, _, [], _) :- !.
path([Row0,Col0],[Row1,Col1],M,Path,1) :-
next_move([Row0,Col0],[Rnew,Cnew]),
is_available(Rnew, Cnew,Ret),
write(Rnew),
write(Cnew),
not(member([Rnew, Cnew], M)),
path([Rnew, Cnew], [Row1, Col1], [[Rnew,Cnew]|M], Path, Ret).
path([X0,Y0], [X1,Y1], [[X0,Y0]|M], [[X,Y]|Path], 0) :-
path([X,Y],[X1,Y1],M,Path,1).
示例输出:
?- solves([1,1],[1,7],P).
P = [[1, 2], [1, 3], [1, 4], [1, 5], [1, 6], [1, 7]] ;
P = [[1, 2], [1, 3], [1, 4], [1, 5], [1, 6], [2, 6], [2, 7], [2|...],
[...|...]|...] ;
P = [[1, 2], [1, 3], [1, 4], [1, 5], [1, 6], [2, 6], [2, 7], [2|...],
[...|...]|...] ;
P = [[1, 2], [1, 3], [1, 4], [1, 5], [1, 6], [2, 6], [2, 7], [2|...],
[...|...]|...] .
在执行程序时,如果在两个位置之间存在路径,则应显示所有路径。否则应返回false。如上所示,我的代码进入了无限循环并不断生成路径。
请帮忙,因为我对Prolog的经验不是很丰富。 谢谢。
答案 0 :(得分:1)
path/5
谓词的第一个子句及其第二个子句中的递归调用是错误的。应该是:
path(Dest, Dest, _, [], _) :- !.
path([Row0,Col0],[Row1,Col1],M,[[Rnew,Cnew]|Path],1) :-
next_move([Row0,Col0],[Rnew,Cnew]),
is_available(Rnew, Cnew,Ret),
write(Rnew),
write(Cnew),
\+ member([Rnew, Cnew], M),
path([Rnew, Cnew], [Row1, Col1], [[Rnew,Cnew]|M], Path, Ret).
此外,请使用ISO Prolog标准\+/1
谓词,而不要使用not/1
传统谓词。
答案 1 :(得分:0)
在这里,我什至看到过这篇文章,还有很多讽刺意味-您正在参加PPL课程? :)
通常在序言中不必返回0或1的值来说明语句是对还是错,这隐含了谓词是否已通过。
例如 最好将is_available(Rnew,Cnew,Ret)编写为is_available(Rnew,Cnew)-如果is_available解析为false,则它将停止并开始回溯以寻找其他解决方案(如果没有其他选择)。 / p>
此外,这意味着如果没有解决方案,则在尝试评估迷宫时将打印'false'值。
关于您的输出问题-实际上这不是“中断”;它只是抑制输出! 在运行迷宫求解表达式之前,请尝试在swi终端中运行此代码:
set_prolog_flag(answer_write_options,[max_depth(0)])。