Currently I was trying to solve the 8 Tile Problem using the A* Algorithm, the heuristic function was the number of inversions in the Matrix provided, As I am adding the Nodes and their states to a queue I need to be able to uniquely identify them for this purpose I am using the __eq__() function in the Node Class. However the program seems to not be able to separate two similar instances and enters into an infinite loop.
The central issue according to me is the fact that I am not able to correctly identify the values and see the difference between them. I am using a queue instead of a pq as I am new to them currently.
So could you please help me understand where I am going wrong.
import random
cols = 3;
rows = 3;
l = [i for i in range(9)];
random.shuffle(l);
initial = [[0 for i in range(cols)] for j in range(rows)];
k = 0;
for i in range(3):
for j in range(3):
initial[i][j] = l[k];
k += 1;
print(initial);
arr = [[0 for i in range(cols)] for j in range(rows)]
for i in range(3):
for j in range(3):
arr[i][j] = 3*i + j;
class Node:
def __init__(self,s,p,d):
self.state = s.copy();
self.parent = p;
self.g = 0;
self.isDummy = d;
if(p is not None):
self.g = p.g + 1;
def __eq__(self,other):
l = self.state.copy()
k= other.state.copy()
for i in range(3):
for j in range(3):
if(l[i][j] != k[i][j]):
return False;
return True;
def checkInversion(self):
invert = 0;
l = [];
for i in range(3):
for j in range(3):
l.append(self.state[i][j]);
for i in range(len(l)):
for j in range(i+1,len(l)):
if(l[j] != 0 and l[i] > l[j]):
invert += 1;
return invert;
def isViable(self):
return self.checkInversion()%2 == 0;
def createChild(self,move1,move2,index):
x = 0;
y = 0;
global rows;
global cols;
l = self.state.copy()
for i in range(3):
for j in range(3):
if(l[i][j] == 0):
x = i;
y = j;
j = x + move1[index];
k = y + move2[index];
lis = [[0 for i in range(cols)] for j in range(rows)];
for i in range(3):
for j in range(3):
lis[i][j] = self.state[i][j];
if(j < 0 or j > 2):
return Node(lis,self,True);
if (k < 0 or k > 2):
return Node(lis,self,True);
temp = lis[x][y];
lis[x][y] = lis[j][k];
lis[j][k] = temp;
return Node(lis,self,False);
def h(self):
return self.checkInversion();
def f(self):
return self.g + self.h();
def isGoal(self):
global Goal
if(self.state == Goal.state):
return True;
return False;
def checkExplored(self,l):
n = len(l);
for i in range(n):
if(l[i] == self):
return False;
return True;
def show(self):
print(self.state);
Goal = Node(arr,None,False);
def AStar(source):
if(source.isGoal()):
return True;
q = [];
move1 = [1,0,-1,0];
move2 = [0,1,0,-1];
q.append(source);
explored = [];
while(q):
cur = q[0];
mi = 0;
for i in range(len(q)):
if(q[i].f() < cur.f()):
cur = q[i];
mi = i;
a = q.pop(mi);
a.show();
if(a.isGoal()):
return a;
explored.append(a);
for i in range(4):
child = a.createChild(move1,move2,i);
if(child.isDummy):
continue;
flag = False;
flag2 = False;
for j in range(len(explored)):
if(child == explored[j]):
flag2 = True;
if(not flag2):
for j in range(len(q)):
if(child == q[j]):
flag = True;
if(child.g < q[j].g):
q[j].g = child.g;
if(not flag):
q.append(child);
k = Node(initial,None,False);
#print(k.isGoal());
print(k.checkInversion());
a = Node(initial,None,False);
if(k.checkInversion()%2 == 0):
a = AStar(k);
#print(a);
a.show()
enter code here