Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Prolog Heuristics

Status
Not open for further replies.

blundellp

Technical User
Apr 6, 2005
25
0
0
GB
Hey i'm currently fiddling with Prolog to complete the tower of hanoi puzzle game. I've managed to be able to represent the search space like this:

Code:
%   Initial State:
%          -8                   |                  |
%         ---7                  |                  |
%        -----6                 |                  |
%       -------5                |                  |
%      ---------4               |                  |
%     -----------3              |                  |
%    -------------2             |                  |
%   ---------------1____________|__________________|__________
%
%    (State = what pieces are upon what poles)
%
% use: hanoi_move([8,7,6,5,4,3,2,1],[],[],[],[],[8,7,6,5,4,3,2,1],X,Y,Z).

hanoi_move predicate is the current state([][][]), then the goal state([][][]) then (X Y Z)

I have been able to solve this problem using rules and facts then a depth first search and a next_node function. as shown:

Code:
hanoi_move([],[],[],A,B,C,_,_,_):-	(write('Please Enter Some Discs ([3,2,1],[],[] etc.)')). %No Variables Entered into Lists
hanoi_move(A,B,C,A,B,C,_,_,_):-	(write('DONE')).                   %If the Current state is the Goal state

hanoi_move([H1|T1],[],L3,Goal1,G2,G3,T1,[H1],L3).                  %Move from peg 1 - peg 2 when empty list	
hanoi_move([H1|T1],[H2|T2],L3,Goal1,G2,G3,T1,[H1,H2|T2],L3):-      %Move from peg 1 - peg 2		     
		   (H1 > H2).                   %Cannot put bigger discs upon smaller
										%Cannot move from an empty peg												   
									   
hanoi_move([H1|T1],L2,[],Goal1,G2,G3,T1,L2,[H1]).                  %Move from peg 1 - peg 3 when empty list													
hanoi_move([H1|T1],L2,[H3|T3],Goal1,G2,G3,T1,L2,[H1,H3|T3]):-      %Move from peg 1 - peg 3
		   (H1 > H3).

hanoi_move([],[H2|T2],L3,Goal1,G2,G3,[H2],T2,L3).                  %Move from peg 2 - peg 1	when empty list		   
hanoi_move([H1|T1],[H2|T2],L3,Goal1,G2,G3,[H2,H1|T1],T2,L3):-      %Move from peg 2 - peg 1
		   (H2 > H1).

hanoi_move(L1,[H2|T2],[],Goal1,G2,G3,L1,T2,[H2]).                  %Move from peg 2 - peg 3 when empty list	   
hanoi_move(L1,[H2|T2],[H3|T3],Goal1,G2,G3,L1,T2,[H2,H3|T3]):-      %Move from peg 2 - peg 3
		   (H2 > H3).
		   
hanoi_move([],L2,[H3|T3],Goal1,G2,G3,[H3],L2,T3).       		   %Move from peg 3 - peg 1 when empty list		   
hanoi_move([H1|T1],L2,[H3|T3],Goal1,G2,G3,[H3,H1|T1],L2,T3):-      %Move from peg 3 - peg 1
		   (H3 > H1).
		   
hanoi_move(L1,[],[H3|T3],Goal1,G2,G3,L1,[H3],T3).	   			   %Move from peg 3 - peg 2 when empty list   
hanoi_move(L1,[H2|T2],[H3|T3],Goal1,G2,G3,L1,[H3,H2|T2],T3):-      %Move from peg 3 - peg 2
		   (H3 > H2).		
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Predicate - next_node/9
% Arguments:
%    Current1,C2,C3 - the current position of the pieces%    
%    Path1,P2,P3    - the list of already visited states
%    Next1,N2,N3    - the Next state after current
%   
% use: next_node([4,3,2,1],[],[],[],[],[4,3,2,1],[4,3,2,1],[],[],A,B,C).
	  
next_node(Current1,C2,C3, Goal1,G2,G3, Path1,P2,P3, Next1,N2,N3):-    
		  hanoi_move(Current1,C2,C3, Goal1,G2,G3, Next1,N2,N3),		%Calls the facts to get the next nodes
		  not(member(Next1,N2,N3,Path1,P2,P3)). 					%Checks if the next nodes have already been visited
		  
%%%%%%%%%%%%%%%%%%%%%%%%%%
% GENERAL ROUTINES 

member(X,Y,Z,[X|_],[Y|_],[Z|_]).                              		%is a member if it is the head
member(X,Y,Z,[_|T],[_|T2],[_|T3]) :- member(X,Y,Z,T,T2,T3).   		%is a member if it is in the tail
	
	
%%%%%%%%%%%%%%%%%%%%%%
% DEPTH-FIRST SEARCH
% Predicate - depth_first/9
%     
% use - depth_first([4,3,2,1],[],[],[],[],[4,3,2,1],A,B,C).
 
depth_first(Start1,S2,S3, Goal1,G2,G3, Path1,P2,P3) :-
	depth_first1(Start1,S2,S3, Goal1,G2,G3, [Start1],[S2],[S3], Path1,P2,P3).

depth_first1(Goal1,G2,G3, Goal1,G2,G3, _,_,_, [Goal1],[G2],[G3]).  %Boundary Case
depth_first1(Start1,S2,S3, Goal1,G2,G3, Visited1,V2,V3, [Start1 | Path1], [S2 | P2], [S3 | P3]) :-
	next_node(Start1,S2,S3, Goal1,G2,G3, Visited1,V2,V3, Next_node1,Next_node2,Next_node3),
	/*write('Visited: '), write(Visited1),write(V2),write(V3), nl,*/
	depth_first1(Next_node1,Next_node2,Next_node3, Goal1,G2,G3, [Next_node1 | Visited1],[Next_node2 | V2],[Next_node3 | V3], Path1,P2,P3).

I was wondering what you think and if possible, a way to improve on this search using a heuristic? Something like a Drunk/Gambling search that can chose a random route but not loop on itself or an A* algorithm search, or other ideas.
Any help is much appreciated.

Any help and ideas are much appreciated.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top