Hill Climbing Algorithm for 8-Puzzle Problem
Implementation and Sample Output
1 Python Implementation
1 import random
2 import copy
3
4 def print_puzzle ( state ) :
5 " " " Display the puzzle in a 3 x3 grid " " "
6 for i in range (0 , 9 , 3) :
7 print ( f " { state [ i ]} { state [ i +1]} { state [ i +2]} " )
8
9 def ge t_ blank_position ( state ) :
10 " " " Find the position of the blank tile (0) " " "
11 return state . index (0)
12
13 def c a l cu late_heuristic ( state , goal ) :
14 " " " Count number of misplaced tiles ( ignoring blank ) " " "
15 misplaced = 0
16 for i in range (9) :
17 if state [ i ] != 0 and state [ i ] != goal [ i ]:
18 misplaced += 1
19 return misplaced
20
21 def get_neighbors ( state ) :
22 " " " Generate all possible moves from current state " " "
23 neighbors = []
24 blank_pos = get_blank_position ( state )
25 row , col = blank_pos // 3 , blank_pos % 3
26
27 moves = []
28 if row > 0: moves . append (( ’ UP ’ , blank_pos - 3) )
29 if row < 2: moves . append (( ’ DOWN ’ , blank_pos + 3) )
30 if col > 0: moves . append (( ’ LEFT ’ , blank_pos - 1) )
31 if col < 2: moves . append (( ’ RIGHT ’ , blank_pos + 1) )
32
33 for move_name , swap_pos in moves :
34 new_state = state [:]
35 new_state [ blank_pos ] , new_state [ swap_pos ] = new_state [ swap_pos ] , new_state
[ blank_pos ]
36 neighbors . append (( move_name , new_state ) )
37
38 return neighbors
39
40 def g e n e r ate _rand om_s tate () :
41 " " " Generate a random valid 8 - puzzle state " " "
42 state = list ( range (9) ) # [0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8]
43 random . shuffle ( state )
44 return state
45
1
46 def is_solvable ( state ) :
47 " " " Check if the puzzle is solvable using inversion count " " "
48 inversions = 0
49 for i in range (9) :
50 if state [ i ] == 0:
51 continue
52 for j in range ( i + 1 , 9) :
53 if state [ j ] == 0:
54 continue
55 if state [ i ] > state [ j ]:
56 inversions += 1
57 # For 8 - puzzle , solvable if inversions is even
58 return inversions % 2 == 0
59
60 def g e n e r a t e_ so l va bl e _s t at e () :
61 " " " Generate a random solvable 8 - puzzle state " " "
62 while True :
63 state = gene rate _rand om_s tate ()
64 if is_solvable ( state ) :
65 return state
66
67 def hill_climbing ( start , goal , max_iterations ) :
68 " " " Hill climbing algorithm for 8 - puzzle " " "
69 current = start [:]
70 current_h = calculate_heuristic ( current , goal )
71
72 print ( " \ n " + " = " *50)
73 print ( " STARTING HILL CLIMBING " )
74 print ( " = " *50)
75 print ( " Initial State : " )
76 print_puzzle ( current )
77 print ( f " Initial Heuristic ( misplaced tiles ) : { current_h } " )
78 print ( " = " *50)
79
80 for iteration in range ( max_iterations ) :
81 if current_h == 0:
82 print ( f " \ n GOAL REACHED at iteration { iteration }! " )
83 return current , True
84
85 neighbors = get_neighbors ( current )
86
87 best_neighbor = None
88 best_h = current_h
89 best_move = None
90
91 for move , neighbor in neighbors :
92 h = calculate_heuristic ( neighbor , goal )
93 if h < best_h :
94 best_h = h
95 best_neighbor = neighbor
96 best_move = move
97
98 if best_neighbor is None :
99 print ( f " \ n STUCK at iteration { iteration } ( Local Maximum ) " )
100 print ( f " No neighbor is better than current state " )
101 return current , False
102
103 current = best_neighbor
104 current_h = best_h
2
105
106 print ( f " \ nIteration { iteration + 1}: Moved { best_move } " )
107 print_puzzle ( current )
108 print ( f " Heuristic : { current_h } " )
109
110 print ( f " \ n Maximum iterations ({ max_iterations }) reached " )
111 return current , False
112
113
114 # =====================================================
115 # MAIN PROGRAM - RANDOM INITIAL STATE
116 # =====================================================
117
118 print ( " = " *50)
119 print ( " HILL CLIMBING FOR 8 - PUZZLE SOLVER " )
120 print ( " = " *50)
121 print ( " Generating random solvable initial state ...\ n " )
122
123 # Generate random solvable initial state
124 initial = g en e ra t e_ so l va bl e _s t at e ()
125
126 # Standard goal state
127 goal = [1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 0]
128
129 # Maximum iterations
130 max_iter = 100
131
132 print ( " Initial State ( randomly generated ) : " )
133 print_puzzle ( initial )
134 print ( f " \ nGoal State : " )
135 print_puzzle ( goal )
136 print ( f " \ nMaximum Iterations : { max_iter } " )
137
138 # Run hill climbing
139 final_state , solved = hill_climbing ( initial , goal , max_iter )
140
141 # Display final results
142 print ( " \ n " + " = " *50)
143 print ( " FINAL RESULT " )
144 print ( " = " *50)
145 print ( " Final State : " )
146 print_puzzle ( final_state )
147 print ( f " Final Heuristic : { calculate_heuristic ( final_state , goal ) } " )
148 print ( f " Status : { ’ SOLVED ’ if solved else ’ NOT SOLVED ’} " )
149 print ( " = " *50)
150
151 # Additional statistics
152 if not solved :
153 print ( " \ n NOTE : Hill climbing often gets stuck in local maxima " )
154 print ( " for the 8 - puzzle problem . Try running again for " )
155 print ( " a different random start state ! " )
3
2 Sample Output
==================================================
HILL CLIMBING FOR 8-PUZZLE SOLVER
==================================================
Generating random solvable initial state...
Initial State (randomly generated):
7 2 4
5 0 6
8 3 1
Goal State:
1 2 3
4 5 6
7 8 0
Maximum Iterations: 100
==================================================
STARTING HILL CLIMBING
==================================================
Initial State:
7 2 4
5 0 6
8 3 1
Initial Heuristic (misplaced tiles): 8
==================================================
Iteration 1: Moved UP
7 0 4
5 2 6
8 3 1
Heuristic: 7
Iteration 2: Moved LEFT
0 7 4
5 2 6
8 3 1
Heuristic: 6
Iteration 3: Moved DOWN
5 7 4
0 2 6
8 3 1
Heuristic: 5
Iteration 4: Moved DOWN
5 7 4
8 2 6
0 3 1
Heuristic: 4
STUCK at iteration 4 (Local Maximum)
4
No neighbor is better than current state
==================================================
FINAL RESULT
==================================================
Final State:
5 7 4
8 2 6
0 3 1
Final Heuristic: 4
Status: NOT SOLVED
==================================================
NOTE: Hill climbing often gets stuck in local maxima
for the 8-puzzle problem. Try running again for
a different random start state!