📄 eight_ida.pl
字号:
% State space definition to be used with IDA*
% Predicates needed are: s/2, f/2, goal/1
% To compute f, a node has also to include its search depth
% Problem-specific procedures for the 8-puzzle */
/* Current situation is represented as a list of positions
of the tiles, with first item in the list corresponding
to the empty square.
Example:
1 1 2 3 is represented by:
2 8 4 [2/2, 1/3, 2/3, 3/3, 3/2, 3/1, 2/1, 1/1]
3 7 6 5
1 2 3
'Empty' can move to any of its neighbours which means that
'empty' and its neighbour interchange their positions.
*/
% Specification for A*
s( [Empty|L], [T|L1], 1) :- % All arc-costs are 1
swap( Empty, T, L, L1). % Swap Empty and T in L giving L1
s( State0, State) :- % Ignore cost
s( State0, State, Cost).
swap( E, T, [T|L], [E|L]) :-
d( E, T, 1). % Manhattan dist. between E and T is 1
swap( E, T, [T1|L], [T1|L1]) :-
swap( E, T, L, L1).
d( X/Y, X1/Y1, D) :-
dif( X, X1, Dx),
dif( Y, Y1, Dy),
D is Dx + Dy.
dif( A, B, D) :-
D is A-B, D >= 0, !;
D is B-A.
% Heuristic estimate h is the sum of distances of each tile
% from its 'home' square plus 3 times 'sequencing' score
h( [Empty|L], H) :-
goal([Empty1|G]),
totdist( L, G, D),
seq( L, S),
H is D + 3*S.
totdist( [], [], 0).
totdist( [T|L], [T1|L1], D) :-
d( T, T1, D1),
totdist( L, L1, D2),
D is D1 + D2.
seq( [First|L], S) :-
seq( [First|L], First, S).
seq( [T1,T2|L], First, S) :-
score( T1, T2, S1),
seq( [T2|L], First, S2),
S is S1 + S2.
seq( [Last], First, S) :-
score( Last, First, S).
score( 2/2, _, 1) :- !. % Tile in centre scores 1
score( 1/3, 2/3, 0) :- !.
score( 2/3, 3/3, 0) :- !.
score( 3/3, 3/2, 0) :- !.
score( 3/2, 3/1, 0) :- !.
score( 3/1, 2/1, 0) :- !.
score( 2/1, 1/1, 0) :- !.
score( 1/1, 1/2, 0) :- !.
score( 1/2, 1/3, 0) :- !.
score( _, _, 2). % Tiles out of sequence
goal( [2/2,1/3,2/3,3/3,3/2,3/1,2/1,1/1,1/2]).
% Starting positions for some puzzles
start1( [2/2,1/3,3/2,2/3,3/3,3/1,2/1,1/1,1/2]). % Requires 4 steps
start2( [2/1,1/2,1/3,3/3,3/2,3/1,2/2,1/1,2/3]). % 5 steps
start3( [3/3,1/3,2/2,2/3,3/2,3/1,2/1,1/1,1/2]). % 2 steps
start4( [2/2,2/3,1/3,3/1,1/2,2/1,3/3,1/1,3/2]). % 18 steps
start5( [1/2,3/3,3/1,1/3,3/2,1/1,2/3,2/1,2/2]). % 24 steps
% H = totdist + 3*seq finds solution 38 steps long
% Display a solution path as a list of board positions
showsol([]).
showsol([P|L]) :-
showsol(L),
nl, write('---'),
showpos(P).
% Display a board position
showpos( [S0,S1,S2,S3,S4,S5,S6,S7,S8]) :-
member( Y, [3,2,1]), % Order of Y-coordinates
nl, member( X, [1,2,3]), % Order of X-coordinates
member( Tile-X/Y, [' '-S0,1-S1,2-S2,3-S3,4-S4,5-S5,6-S6,7-S7,8-S8]),
write(Tile),
fail. % Backtrack to next square
showpos([_|_]).
tile(S, [S0, S1, S2, S3, S4, S5, S6, S7, S8], Tile) :-
member( Tile/S,
[' '/S0, 1/S1, 2/S2, 3/S3, 4/S4, 5/S5, 6/S6, 7/S7, 8/S8]).
% Specification of eight puzzle for IDA*
s( Depth:State, NewDepth:NewState) :-
s( State, NewState, _),
NewDepth is Depth + 1.
f( Depth:[Empty|Tiles], F) :-
goal( [Empty0|Tiles0]),
totdist( Tiles, Tiles0, Dist),
F is Depth + Dist. % Use total dist. as heuristic function
goal( _:[2/2,1/3,2/3,3/3,3/2,3/1,2/1,1/1,1/2]).
% Initial states for IDA* are of the form 0:State, where State
% is a start state for A*
showpos( Depth:State) :-
showpos( State).
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -