How to uniquely Identify objects in Python so that we can Insert Nodes in a Queue?

Viewed 27

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
0 Answers
Related