Prolog 最少移动次数
在本页中 演示了如何解决流行的狼、山羊和卷心菜难题Prolog 最少移动次数,prolog,river-crossing-puzzle,Prolog,River Crossing Puzzle,在本页中 演示了如何解决流行的狼、山羊和卷心菜难题 change(e,w). change(w,e). move([X, X,Goat,Cabbage], wolf,[Y, Y,Goat,Cabbage]) :- change(X,Y). move([X,Wolf, X,Cabbage], goat,[Y,Wolf, Y,Cabbage]) :- change(X,Y). move([X,Wolf,Goat, X],cabbage,[Y,Wolf,Goat,
change(e,w).
change(w,e).
move([X, X,Goat,Cabbage], wolf,[Y, Y,Goat,Cabbage]) :- change(X,Y).
move([X,Wolf, X,Cabbage], goat,[Y,Wolf, Y,Cabbage]) :- change(X,Y).
move([X,Wolf,Goat, X],cabbage,[Y,Wolf,Goat, Y]) :- change(X,Y).
move([X,Wolf,Goat,Cabbage],nothing,[Y,Wolf,Goat,Cabbage]) :- change(X,Y).
oneEq(X,X,_).
oneEq(X,_,X).
safe([Man,Wolf,Goat,Cabbage]) :-
oneEq(Man,Goat, Wolf),
oneEq(Man,Goat,Cabbage).
solution([e,e,e,e],[]).
solution(Config,[FirstMove|OtherMoves]) :-
move(Config,FirstMove,NextConfig),
safe(NextConfig),
solution(NextConfig,OtherMoves).
但为了找到该程序的实际解决方案,有必要指定所需的确切移动次数,如下所示:
?- length(X,7), solution([w,w,w,w],X).
X = [goat, nothing, wolf, goat, cabbage, nothing, goat] ;
X = [goat, nothing, wolf, goat, cabbage, nothing, goat] ;
X = [goat, nothing, wolf, goat, cabbage, nothing, goat] ;
X = [goat, nothing, wolf, goat, cabbage, nothing, goat] ;
X = [goat, nothing, wolf, goat, cabbage, nothing, goat] ;
X = [goat, nothing, wolf, goat, cabbage, nothing, goat] ;
X = [goat, nothing, wolf, goat, cabbage, nothing, goat] ;
X = [goat, nothing, wolf, goat, cabbage, nothing, goat] ;
X = [goat, nothing, wolf, goat, cabbage, nothing, goat] ;
X = [goat, nothing, wolf, goat, cabbage, nothing, goat] ;
X = [goat, nothing, wolf, goat, cabbage, nothing, goat] ;
X = [goat, nothing, wolf, goat, cabbage, nothing, goat] ;
X = [goat, nothing, wolf, goat, cabbage, nothing, goat] ;
X = [goat, nothing, wolf, goat, cabbage, nothing, goat] ;
X = [goat, nothing, wolf, goat, cabbage, nothing, goat] ;
X = [goat, nothing, wolf, goat, cabbage, nothing, goat] ;
X = [goat, nothing, cabbage, goat, wolf, nothing, goat] ;
X = [goat, nothing, cabbage, goat, wolf, nothing, goat] ;
X = [goat, nothing, cabbage, goat, wolf, nothing, goat] ;
X = [goat, nothing, cabbage, goat, wolf, nothing, goat] ;
X = [goat, nothing, cabbage, goat, wolf, nothing, goat] ;
X = [goat, nothing, cabbage, goat, wolf, nothing, goat] ;
X = [goat, nothing, cabbage, goat, wolf, nothing, goat] ;
X = [goat, nothing, cabbage, goat, wolf, nothing, goat] ;
X = [goat, nothing, cabbage, goat, wolf, nothing, goat] ;
X = [goat, nothing, cabbage, goat, wolf, nothing, goat] ;
X = [goat, nothing, cabbage, goat, wolf, nothing, goat] ;
X = [goat, nothing, cabbage, goat, wolf, nothing, goat] ;
X = [goat, nothing, cabbage, goat, wolf, nothing, goat] ;
X = [goat, nothing, cabbage, goat, wolf, nothing, goat] ;
X = [goat, nothing, cabbage, goat, wolf, nothing, goat] ;
X = [goat, nothing, cabbage, goat, wolf, nothing, goat] ;
false.
?- length(Xs,8), solution([w,w,w,w],Xs). % try length = 8
false. % no solutions!
?- length(Xs,9), solution([w,w,w,w],Xs). % try length = 9
...
有没有一种标准方法可以在不必指定上述程序中的移动次数的情况下找到最小移动解决方案?length/2具有生成功能,那么只需避免指定值:
?- length(X,_),solution([w,w,w,w],X).
正如我们所知,有有限数量的解具有相同的最小步数,我们将关注实现通用终止
minlen_solution(Xs,S) :-
( setof(t,solution([w,w,w,w],Xs),_) % eliminate redundant answers
*-> Xs = S
; minlen_solution([_|Xs],S) % no solution? try bigger length
).
minlen_solution/2
使用名为“软切割”的(*->)/2
,以提交最小解决方案长度
关于便携性的说明:
- 在SWI Prolog中,构造具有以下形式
- SICStus Prolog通过谓词提供了这个特性。 可获得更多信息
?- minlen_solution([],Xs).
Xs = [goat,nothing,cabbage,goat, wolf,nothing,goat]
; Xs = [goat,nothing, wolf,goat,cabbage,nothing,goat].
如果我们想找到所有长度大于或等于8的解,我们
可以这样做:
?- length(X,7), solution([w,w,w,w],X).
X = [goat, nothing, wolf, goat, cabbage, nothing, goat] ;
X = [goat, nothing, wolf, goat, cabbage, nothing, goat] ;
X = [goat, nothing, wolf, goat, cabbage, nothing, goat] ;
X = [goat, nothing, wolf, goat, cabbage, nothing, goat] ;
X = [goat, nothing, wolf, goat, cabbage, nothing, goat] ;
X = [goat, nothing, wolf, goat, cabbage, nothing, goat] ;
X = [goat, nothing, wolf, goat, cabbage, nothing, goat] ;
X = [goat, nothing, wolf, goat, cabbage, nothing, goat] ;
X = [goat, nothing, wolf, goat, cabbage, nothing, goat] ;
X = [goat, nothing, wolf, goat, cabbage, nothing, goat] ;
X = [goat, nothing, wolf, goat, cabbage, nothing, goat] ;
X = [goat, nothing, wolf, goat, cabbage, nothing, goat] ;
X = [goat, nothing, wolf, goat, cabbage, nothing, goat] ;
X = [goat, nothing, wolf, goat, cabbage, nothing, goat] ;
X = [goat, nothing, wolf, goat, cabbage, nothing, goat] ;
X = [goat, nothing, wolf, goat, cabbage, nothing, goat] ;
X = [goat, nothing, cabbage, goat, wolf, nothing, goat] ;
X = [goat, nothing, cabbage, goat, wolf, nothing, goat] ;
X = [goat, nothing, cabbage, goat, wolf, nothing, goat] ;
X = [goat, nothing, cabbage, goat, wolf, nothing, goat] ;
X = [goat, nothing, cabbage, goat, wolf, nothing, goat] ;
X = [goat, nothing, cabbage, goat, wolf, nothing, goat] ;
X = [goat, nothing, cabbage, goat, wolf, nothing, goat] ;
X = [goat, nothing, cabbage, goat, wolf, nothing, goat] ;
X = [goat, nothing, cabbage, goat, wolf, nothing, goat] ;
X = [goat, nothing, cabbage, goat, wolf, nothing, goat] ;
X = [goat, nothing, cabbage, goat, wolf, nothing, goat] ;
X = [goat, nothing, cabbage, goat, wolf, nothing, goat] ;
X = [goat, nothing, cabbage, goat, wolf, nothing, goat] ;
X = [goat, nothing, cabbage, goat, wolf, nothing, goat] ;
X = [goat, nothing, cabbage, goat, wolf, nothing, goat] ;
X = [goat, nothing, cabbage, goat, wolf, nothing, goat] ;
false.
?- length(Xs,8), solution([w,w,w,w],Xs). % try length = 8
false. % no solutions!
?- length(Xs,9), solution([w,w,w,w],Xs). % try length = 9
...
然而,我们仍然必须承诺最低长度
使用minlen_solutions/2
我们可以直接指定解决方案列表长度的下限,如下所示:
?- length(Xs,8),minlen_solution(Xs,S).
S = [goat, goat, goat,nothing,cabbage, goat, wolf,nothing,goat]
; S = [goat, goat, goat,nothing, wolf, goat,cabbage,nothing,goat]
; S = [goat,nothing,cabbage,cabbage,cabbage, goat, wolf,nothing,goat]
; S = [goat,nothing,cabbage,cabbage, wolf, goat,cabbage,nothing,goat]
; S = [goat,nothing,cabbage, goat, goat, goat, wolf,nothing,goat]
; S = [goat,nothing,cabbage, goat, wolf,cabbage,cabbage,nothing,goat]
; S = [goat,nothing,cabbage, goat, wolf,nothing, goat, goat,goat]
; S = [goat,nothing,cabbage, goat, wolf,nothing,nothing,nothing,goat]
; S = [goat,nothing,cabbage, goat, wolf, wolf, wolf,nothing,goat]
; S = [goat,nothing,nothing,nothing,cabbage, goat, wolf,nothing,goat]
; S = [goat,nothing,nothing,nothing, wolf, goat,cabbage,nothing,goat]
; S = [goat,nothing, wolf, goat,cabbage,cabbage,cabbage,nothing,goat]
; S = [goat,nothing, wolf, goat,cabbage,nothing, goat, goat,goat]
; S = [goat,nothing, wolf, goat,cabbage,nothing,nothing,nothing,goat]
; S = [goat,nothing, wolf, goat,cabbage, wolf, wolf,nothing,goat]
; S = [goat,nothing, wolf, goat, goat, goat,cabbage,nothing,goat]
; S = [goat,nothing, wolf, wolf,cabbage, goat, wolf,nothing,goat]
; S = [goat,nothing, wolf, wolf, wolf, goat,cabbage,nothing,goat].
为了可读性,上面只显示了S
的答案替换
请注意,所有使用minlen_solution/2
的查询都会普遍终止。s(X)用于演示迭代深化。