forked from inosjarv/GTU-AI-Practicals
-
Notifications
You must be signed in to change notification settings - Fork 0
/
node.py
121 lines (100 loc) · 3.22 KB
/
node.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
import heapq
class Node(object):
"""For state representation"""
n = 0
def __init__(self, board,prev_state = None):
assert len(board) == 9
self.board = board[:];
self.prev = prev_state
self.step = 0
Node.n += 1
if self.prev:
self.step = self.prev.step + 1
def __eq__(self,other):
return self.board == other.board
def __hash__(self):
h = [0,0,0]
h[0] = self.board[0] << 6 | self.board[1] << 3 | self.board[2]
h[1] = self.board[3] << 6 | self.board[4] << 3 | self.board[5]
h[2] = self.board[6] << 6 | self.board[7] << 3 | self.board[8]
h_val = 0
for h_i in h:
h_val = h_val *31 + h_i
return h_val
def __str__(self):
string_list = [str(i) for i in self.board]
sub_list = (string_list[:3],string_list[3:6],string_list[6:])
return "\n".join(["".join(l)for l in sub_list ])
def manhattan_distance(self):
distance = 0
goal = [1,2,3,4,5,6,7,8,0]
for i in range(1,9):
xs,ys = self.pos(self.board.index(i))
xg,yg = self.pos(goal.index(i))
distance += abs(xs-xg) + abs(ys-yg)
return distance
def hamming_distance(self):
distance = 0
goal = [1,2,3,4,5,6,7,8,0]
for i in range(9):
if goal[i] != self.board[i]: distance += 1
return distance
def next(self):
next_moves = []
i = self.board.index(0)
next_moves = (self.moveUp(i),self.moveDown(i),self.moveRight(i),self.moveLeft(i))
return [s for s in next_moves if s]
def moveLeft(self,i):
x,y = self.pos(i)
if y > 0:
left_state = Node(self.board,self)
left = self.sop(x,y-1)
left_state.swap(i,left)
return left_state
def moveRight(self,i):
x,y = self.pos(i)
if y < 2 :
right_state = Node(self.board,self)
right = self.sop(x,y+1)
right_state.swap(i,right)
return right_state
def moveUp(self,i):
x,y = self.pos(i)
if x > 0:
up_state = Node(self.board,self)
up = self.sop(x-1,y)
up_state.swap(i,up)
return up_state
def moveDown(self , i):
x,y = self.pos(i)
if x < 2 :
down_state = Node(self.board,self)
down = self.sop(x+1,y)
down_state.swap(i,down)
return down_state
def swap(self,i,j):
self.board[j],self.board[i] = self.board[i],self.board[j]
def pos(self,index):
return (int(index/3),index%3)
def sop(self,x,y):
return x * 3 + y
class PriorityQueue:
def __init__(self):
self.heap = []
self.count = 0
def push(self, item, priority):
entry = (priority, self.count, item)
heapq.heappush(self.heap, entry)
self.count += 1
def pop(self):
(_, _, item) = heapq.heappop(self.heap)
return item
def isEmpty(self):
return len(self.heap) == 0
def printPath(state):
path = []
while state:
path.append(state)
state = state.prev
path.reverse()
print("\n \n".join([str(state) for state in path]))