From e278e5d94055af2f04b15599b553d4dc94ffcf90 Mon Sep 17 00:00:00 2001 From: SasankYadati Date: Tue, 13 Feb 2018 22:38:35 +0530 Subject: [PATCH 1/3] Fix EightPuzzle class implementation --- search.py | 160 +++++++++++++++++++++++++++++------------------------- 1 file changed, 87 insertions(+), 73 deletions(-) diff --git a/search.py b/search.py index b705d6f28..f5ad215d0 100644 --- a/search.py +++ b/search.py @@ -404,12 +404,84 @@ def astar_search(problem, h=None): # ______________________________________________________________________________ # A* heuristics -class EightPuzzle(): +class EightPuzzle(Problem): - def __init__(self): - self.path = [] - self.final = [] + """The problem of sliding tiles numbered from 1 to 8 on a 3x3 board, + where one of the squares is a blank. A state is represented as a 3x3 list, + where element at index i,j represents the tile number (0 if it's an empty square).""" + + def __init__(self, initial, goal=None): + if goal: + self.goal = goal + else: + self.goal = [ [0,1,2], + [3,4,5], + [6,7,8] ] + Problem.__init__(self, initial, goal) + def find_blank_square(self, state): + """Return the index of the blank square in a given state.""" + for row in len(state): + for column in len(row): + if state[row][column]==0: + index_blank_square = (row,column) + return index_blank_square + + def actions(self, state): + """Return the actions that can be executed in the given state. + The result would be a list, since there are only four possible actions + in any given state of the environment.""" + + possible_actions = list() + index_blank_square = self.find_blank_square(state) + + if index_blank_square(0)==0: + possible_actions += ['DOWN'] + elif index_blank_square(0)==1: + possible_actions += ['UP','DOWN'] + elif index_blank_square(0)==2: + possible_actions += ['UP'] + + if index_blank_square(1)==0: + possible_actions += ['RIGHT'] + elif index_blank_square(1)==1: + possible_actions += ['LEFT','RIGHT'] + elif index_blank_square(1)==2: + possible_actions += ['LEFT'] + + return possible_actions + + def result(self, state, action): + """Given state and action, return a new state that is the result of the action. + Action is assumed to be a valid action.""" + + blank_square = self.find_blank_square(state) + new_state = [row[:] for row in state] + + if action=='UP': + new_state[blank_square(0)][blank_square(1)] = new_state[blank_square(0)-1][blank_square(1)] + new_state[blank_square(0)-1][blank_square(1)] = 0 + elif action=='LEFT': + new_state[blank_square(0)][blank_square(1)] = new_state[blank_square(0)][blank_square(1)-1] + new_state[blank_square(0)][blank_square(1)-1] = 0 + elif action=='DOWN': + new_state[blank_square(0)][blank_square(1)] = new_state[blank_square(0)+1][blank_square(1)] + new_state[blank_square(0)+1][blank_square(1)] = 0 + elif action=='RIGHT': + new_state[blank_square(0)][blank_square(1)] = new_state[blank_square(0)][blank_square(1)+1] + new_state[blank_square(0)][blank_square(1)+1] = 0 + else: + print("Invalid Action!") + return new_state + + def goal_test(self, state): + """Given a state, return True if state is a goal state or False, otherwise.""" + for row in len(state): + for column in len(row): + if state[row][col]!=self.goal[row][column]: + return False + return True + def checkSolvability(self, state): inversion = 0 for i in range(len(state)): @@ -420,75 +492,17 @@ def checkSolvability(self, state): if inversion%2 != 0: check = False print(check) - - def getPossibleMoves(self,state,heuristic,goal,moves): - move = {0:[1,3], 1:[0,2,4], 2:[1,5], 3:[0,6,4], 4:[1,3,5,7], 5:[2,4,8], 6:[3,7], 7:[4,6,8], 8:[7,5]} # create a dictionary of moves - index = state[0].index(0) - possible_moves = [] - for i in range(len(move[index])): - conf = list(state[0][:]) - a = conf[index] - b = conf[move[index][i]] - conf[move[index][i]] = a - conf[index] = b - possible_moves.append(conf) - scores = [] - for i in possible_moves: - scores.append(heuristic(i,goal)) - scores = [x+moves for x in scores] - allowed_state = [] - for i in range(len(possible_moves)): - node = [] - node.append(possible_moves[i]) - node.append(scores[i]) - node.append(state[0]) - allowed_state.append(node) - return allowed_state - - - def create_path(self,goal,initial): - node = goal[0] - self.final.append(goal[0]) - if goal[2] == initial: - return reversed(self.final) - else: - parent = goal[2] - for i in self.path: - if i[0] == parent: - parent = i - self.create_path(parent,initial) - - def show_path(self,initial): - move = [] - for i in range(0,len(self.path)): - move.append(''.join(str(x) for x in self.path[i][0])) - - print("Number of explored nodes by the following heuristic are: ", len(set(move))) - print(initial) - for i in reversed(self.final): - print(i) - - del self.path[:] - del self.final[:] - return - - def solve(self,initial,goal,heuristic): - root = [initial,heuristic(initial,goal),''] - nodes = [] # nodes is a priority Queue based on the state score - nodes.append(root) - moves = 0 - while len(nodes) != 0: - node = nodes[0] - del nodes[0] - self.path.append(node) - if node[0] == goal: - soln = self.create_path(self.path[-1],initial ) - self.show_path(initial) - return - moves +=1 - opened_nodes = self.getPossibleMoves(node,heuristic,goal,moves) - nodes = sorted(opened_nodes+nodes, key=itemgetter(1)) - + + def h(self, state): + """Return the heuristic value for a given state. Heuristic function used is + h(n) = number of misplaced tiles.""" + num_misplaced_tiles = 0 + + for row in len(state): + for column in len(row): + if state[row][col]!=self.goal[row][column]: + num_misplaced_tiles+=1 + return num_misplaced_tiles # ______________________________________________________________________________ # Other search algorithms From 0850239b01bf16fb386c46ffda7e62b6ec9c79ed Mon Sep 17 00:00:00 2001 From: SasankYadati Date: Tue, 13 Feb 2018 22:47:30 +0530 Subject: [PATCH 2/3] Fix EightPuzzle class implementation (#710) --- search.py | 1 - 1 file changed, 1 deletion(-) diff --git a/search.py b/search.py index f5ad215d0..45d79d677 100644 --- a/search.py +++ b/search.py @@ -497,7 +497,6 @@ def h(self, state): """Return the heuristic value for a given state. Heuristic function used is h(n) = number of misplaced tiles.""" num_misplaced_tiles = 0 - for row in len(state): for column in len(row): if state[row][col]!=self.goal[row][column]: From afe3a5a8c0de8a006bdd9ee8f3413b739f16a838 Mon Sep 17 00:00:00 2001 From: SasankYadati Date: Wed, 14 Feb 2018 04:01:34 +0530 Subject: [PATCH 3/3] Address style issues (#710) --- search.py | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/search.py b/search.py index 45d79d677..14388c684 100644 --- a/search.py +++ b/search.py @@ -420,11 +420,11 @@ def __init__(self, initial, goal=None): Problem.__init__(self, initial, goal) def find_blank_square(self, state): - """Return the index of the blank square in a given state.""" + """Return the index of the blank square in a given state""" for row in len(state): for column in len(row): - if state[row][column]==0: - index_blank_square = (row,column) + if state[row][column] == 0: + index_blank_square = (row, column) return index_blank_square def actions(self, state): @@ -435,25 +435,25 @@ def actions(self, state): possible_actions = list() index_blank_square = self.find_blank_square(state) - if index_blank_square(0)==0: + if index_blank_square(0) == 0: possible_actions += ['DOWN'] - elif index_blank_square(0)==1: - possible_actions += ['UP','DOWN'] - elif index_blank_square(0)==2: + elif index_blank_square(0) == 1: + possible_actions += ['UP', 'DOWN'] + elif index_blank_square(0) == 2: possible_actions += ['UP'] - if index_blank_square(1)==0: + if index_blank_square(1) == 0: possible_actions += ['RIGHT'] - elif index_blank_square(1)==1: - possible_actions += ['LEFT','RIGHT'] - elif index_blank_square(1)==2: + elif index_blank_square(1) == 1: + possible_actions += ['LEFT', 'RIGHT'] + elif index_blank_square(1) == 2: possible_actions += ['LEFT'] return possible_actions def result(self, state, action): """Given state and action, return a new state that is the result of the action. - Action is assumed to be a valid action.""" + Action is assumed to be a valid action in the state.""" blank_square = self.find_blank_square(state) new_state = [row[:] for row in state] @@ -475,18 +475,18 @@ def result(self, state, action): return new_state def goal_test(self, state): - """Given a state, return True if state is a goal state or False, otherwise.""" + """Given a state, return True if state is a goal state or False, otherwise""" for row in len(state): for column in len(row): - if state[row][col]!=self.goal[row][column]: + if state[row][col] != self.goal[row][column]: return False return True def checkSolvability(self, state): inversion = 0 for i in range(len(state)): - for j in range(i,len(state)): - if (state[i]>state[j] and state[j]!=0): + for j in range(i, len(state)): + if (state[i] > state[j] and state[j] != 0): inversion += 1 check = True if inversion%2 != 0: @@ -499,8 +499,8 @@ def h(self, state): num_misplaced_tiles = 0 for row in len(state): for column in len(row): - if state[row][col]!=self.goal[row][column]: - num_misplaced_tiles+=1 + if state[row][col] != self.goal[row][column]: + num_misplaced_tiles += 1 return num_misplaced_tiles # ______________________________________________________________________________ pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy