2010-07-27 5 views
2
%(SWI-Prolog)You can run the program by: ?- bestfs([8,1,3,7,0,2,6,5,4],P). 

initial([8,1,3,7,0,2,6,5,4]). 

goal([1,2,3,8,0,4,7,6,5]). 

operators([left, right, up, down]). 

% 8-puzzle solution 
% initial([8,1,3,7,0,2,6,5,4]). 
% goal([1,2,3,8,0,4,7,6,5]). 

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
% Best-first Search % 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
bestfs(Start,Path):- 
heuristic(Start, Distance), 
bestfs_path([ node(Start, Distance, []) ], Path). 
bestfs_path([node(Goal, _, Path)| _], Path):- 
goal(Goal). 
bestfs_path([node(Current, _, Path) | Queue], 
GoalPath) :- 
findall(node(Child, Distance, PathToChild), 
(
    apply(Operator, Current, Child), 
    heuristic(Child, Distance), 
    append(Path, [Operator], PathToChild) 
), ChildNodes), 
add_to_list(ChildNodes, Queue, NewQueue), 
bestfs_path(NewQueue, GoalPath). 

% add_to_list adds a new list into an old (ordered) list 
% by recursively adding members of the new list at their 
% appropriate position in the old list. The returned list 
% is also ordered. 

add_to_list([], L, L). 
add_to_list([H|T], OldList, NewList):- 
insert_at_place(H, OldList, TempList), 
add_to_list(T, TempList, NewList). 

% insert_at_place simply adds a new element at the right 
% place of an ordered list so as to return another 
% ordered list (provisions have been made for the node 
% datastructure that is used in out implementation of 
% best-first search) 
insert_at_place(X, [], [X]). 
insert_at_place(node(NodeX, X, PathX), 
     [node(NodeY, Y, PathY) | L], 
      [node(NodeX, X, PathX), 
      node(NodeY, Y, PathY) | L]) :- 
X =< Y. 

insert_at_place(node(NodeX, X, PathX), 
       [node(Node, Y, PathY) | L], 
       [node(Node, Y, PathY) | NewL]) :- 
X > Y, 
insert_at_place(node(NodeX, X, PathX), L, NewL). 
% Of course, we need to choose our heuristic 
% change this to use any other heuristic, such as 
% manhattan distance 
heuristic(X, Y) :- 
displaced(X, Y). 
% manhattan(X,Y). 

%===================================================================== 

%Implementation of 8-Puzzle Operators 

%==================================================================== 

% move_left in the top row 
move_left([X1,0,X3, X4,X5,X6, X7,X8,X9], [0,X1,X3, X4,X5,X6, X7,X8,X9]). 
move_left([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_left([X1,X2,X3, X4,0,X6, X7,X8,X9], [X1,X2,X3, 0,X4,X6, X7,X8,X9]). 
move_left([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_left([X1,X2,X3, X4,X5,X6, X7,0,X9], [X1,X2,X3, X4,X5,X6, 0,X7,X9]). 
move_left([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_right([0,X2,X3, X4,X5,X6, X7,X8,X9], [X2,0,X3, X4,X5,X6, X7,X8,X9]). 
move_right([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_right([X1,X2,X3, 0,X5,X6, X7,X8,X9], [X1,X2,X3, X5,0,X6, X7,X8,X9]). 
move_right([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_right([X1,X2,X3, X4,X5,X6, 0,X8,X9], [X1,X2,X3, X4,X5,X6, X8,0,X9]). 
move_right([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_up([X1,X2,X3, 0,X5,X6, X7,X8,X9], [0,X2,X3, X1,X5,X6, X7,X8,X9]). 
move_up([X1,X2,X3, X4,0,X6, X7,X8,X9], [X1,0,X3, X4,X2,X6, X7,X8,X9]). 
move_up([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_up([X1,X2,X3, X4,X5,X6, 0,X8,X9], [X1,X2,X3, 0,X5,X6, X4,X8,X9]). 
move_up([X1,X2,X3, X4,X5,X6, X7,0,X9], [X1,X2,X3, X4,0,X6, X7,X5,X9]). 
move_up([X1,X2,X3, X4,X5,X6, X7,X8,0], [X1,X2,X3, X4,X5,0, X7,X8,X6]). 

% move_down from the top row 
move_down([0,X2,X3, X4,X5,X6, X7,X8,X9], [X4,X2,X3, 0,X5,X6, X7,X8,X9]). 
move_down([X1,0,X3, X4,X5,X6, X7,X8,X9], [X1,X5,X3, X4,0,X6, X7,X8,X9]). 
move_down([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_down([X1,X2,X3, 0,X5,X6, X7,X8,X9], [X1,X2,X3, X7,X5,X6, 0,X8,X9]). 
move_down([X1,X2,X3, X4,0,X6, X7,X8,X9], [X1,X2,X3, X4,X8,X6, X7,0,X9]). 
move_down([X1,X2,X3, X4,X5,0, X7,X8,X9], [X1,X2,X3, X4,X5,X9, X7,X8,0]). 

% Applying an operator 
apply(left,S1,S2) :- move_left(S1,S2). 
apply(right,S1,S2) :- move_right(S1,S2). 
apply(up,S1,S2) :- move_up(S1,S2). 
apply(down,S1,S2) :- move_down(S1,S2). 

%====================================================================== 

%Implementation of 8-Puzzle Heuristic Functions 

%====================================================================== 


% displacement heuristic 

displaced(State, Number) :-         
    goal(Goal),            
    misplaced(State,Goal,Number).        

% misplaced returns the number of tiles found in the wrong position 

misplaced([],[],0).           
misplaced([0|T1],[0|T2],Number) :- !,      
    misplaced(T1,T2,Number).         
misplaced([H|T1],[H|T2],Number) :- !,      
    misplaced(T1,T2,Number).         
misplaced([H1|T1],[H2|T2],Number) :- !,      
    H1\==H2,             
    misplaced(T1,T2,N),          
    Number is N+1.           


% Manhattan Distance heuristic 

manhattan(State, Number) :- 
    manh(State,State,0,Number). 

manh([], _, X, X). 

manh([H|T], State, Acc, Result) :- 
    nth1(Position, State, H), 
    NewPos is Position - 1, 
    Xaux1 is NewPos mod 3, 
    X1 is integer(Xaux1), 
    Y1 is NewPos // 3, 
    goal(Goal), 
    nth1(GoalPosition, Goal, H), 
    NewGPos is GoalPosition - 1, 
    Xaux2 is NewGPos mod 3, 
    X2 is integer(Xaux2), 
    Y2 is NewGPos // 3, 
    S1 is abs(X1-X2), 
    S2 is abs(Y1-Y2), 
    N is S1+S2, 
    NewAcc is Acc+N, 
    manh(T, State, NewAcc, Result). 
+0

On dirait que vous avez un débordement de pile! Voici un lien pour augmenter la taille de votre pile http://old.nabble.com/How-to-solve-the-erro-out-of-global-stack-in-JPL-td13975597.html –

Répondre

0

La raison pour laquelle vous obtenez une erreur vous informant que vous êtes hors de l'espace de la pile est parce que ...

Attendez ... il

Vous n'avez plus d'espace dans la pile. Ceci est dû au fait que le solveur de Prolog rend très facile une récurrence très profonde. Essayez une pile plus grande ou essayez de limiter vos variables avec plus de contraintes pour faciliter la recherche de mauvais Prolog.

Questions connexes