From 4924b4b7846ba5482c4d0d8e38a1f0242ef789ff Mon Sep 17 00:00:00 2001 From: mba Date: Thu, 27 Mar 2025 16:48:37 +0800 Subject: [PATCH 01/11] a --- assignment1.py | 147 +++++++++++++++++++++++++++++++++++++ assignment1aux.py | 51 +++++++++++++ assignment1config.txt | 3 + search.ipynb | 164 ++++++++++++++++++++++++------------------ 4 files changed, 295 insertions(+), 70 deletions(-) create mode 100644 assignment1.py create mode 100644 assignment1aux.py create mode 100644 assignment1config.txt diff --git a/assignment1.py b/assignment1.py new file mode 100644 index 000000000..2b6e8e949 --- /dev/null +++ b/assignment1.py @@ -0,0 +1,147 @@ +from time import time +from search import * +from assignment1aux import * + +def read_initial_state_from_file(filename): + # Task 1 + # Return an initial state constructed using a configuration in a file. + # Replace the line below with your code. + temTuple = () + with open(filename, 'r') as file: + lin = file.readlines() + lines = [line.strip() for line in lin] + height=int(lines[1]) + width=int(lines[0]) + map = [[''] * height for _ in range(width)] + for i in range(2,len(lines)): + temp=lines[i].split(',') + map[int(temp[0])][int(temp[1])] = 'rock' + tuple_map=tuple(tuple(row) for row in map) + temTuple = (tuple_map, None, None) + return temTuple + +class ZenPuzzleGarden(Problem): + def __init__(self, initial): + if type(initial) is str: + super().__init__(read_initial_state_from_file(initial)) + else: + super().__init__(initial) + + def actions(self, state): + # Task 2.1 + # Return a list of all allowed actions in a given state. + # Replace the line below with your code. + action=[] + + for i in range(len(state[0][0])): + if state[0][0][i]!='rock': + action.append(((0,i),'down')) + if state[0][len(state[0])-1][i]!='rock': + action.append(((len(state[0])-1,i),'up')) + for i in range(len(state[0])): + if state[0][i][0]!='rock': + action.append(((i,0),'right')) + if state[0][i][len(state[0][i])-1]!='rock': + action.append(((i,len(state[0][i])-1),'left')) + return action + + def result(self, state, action): + # Task 2.2 + # Return a new state resulting from a given action being applied to a given state. + # Replace the line below with your code. + listState = list(list(row) for row in state[0]) + point=list(action[0]) + direction=action[1] + while point[0]=0 and point[1]=0: + if direction=='down': + listState[point[0]][point[1]]='down' + point[0]+=1 + elif direction=='up': + listState[point[0]][point[1]]='up' + point[0]-=1 + elif direction=='right': + listState[point[0]][point[1]]='right' + point[1]+=1 + elif direction=='left': + listState[point[0]][point[1]]='left' + point[1]-=1 + if point[0]<0 or point[0]>=len(state[0]) or point[1]<0 or point[1]>=len(state[0][0]): + return (tuple(tuple(row) for row in listState), None, None) + else: + return (tuple(tuple(row) for row in state[0]), tuple(point), direction) + + + def goal_test(self, state): + # Task 2.3 + # Return a boolean value indicating if a given state is solved. + # Replace the line below with your code. + map=list(state[0]) + print(map) + for i in map: + if '' in i: + return False + return True + + +# Task 3 +# Implement an A* heuristic cost function and assign it to the variable below. +astar_heuristic_cost = None + +def beam_search(problem, f, beam_width): + # Task 4 + # Implement a beam-width version A* search. + # Return a search node containing a solved state. + # Experiment with the beam width in the test code to find a solution. + # Replace the line below with your code. + raise NotImplementedError + +if __name__ == "__main__": + + # Task 1 test code + + print('The loaded initial state is visualised below.') + visualise(read_initial_state_from_file('/Users/rtxon/Library/Mobile Documents/com~apple~CloudDocs/Python/Assignment1/aima-python/assignment1config.txt')) + + + # Task 2 test code + + garden = ZenPuzzleGarden('/Users/rtxon/Library/Mobile Documents/com~apple~CloudDocs/Python/Assignment1/aima-python/assignment1config.txt') + print('Running breadth-first graph search.') + before_time = time() + node = breadth_first_graph_search(garden) + after_time = time() + print(f'Breadth-first graph search took {after_time - before_time} seconds.') + if node: + print(f'Its solution with a cost of {node.path_cost} is animated below.') + animate(node) + else: + print('No solution was found.') + + + # Task 3 test code + ''' + print('Running A* search.') + before_time = time() + node = astar_search(garden, astar_heuristic_cost) + after_time = time() + print(f'A* search took {after_time - before_time} seconds.') + if node: + print(f'Its solution with a cost of {node.path_cost} is animated below.') + animate(node) + else: + print('No solution was found.') + ''' + + # Task 4 test code + ''' + print('Running beam search.') + before_time = time() + node = beam_search(garden, lambda n: n.path_cost + astar_heuristic_cost(n), 50) + after_time = time() + print(f'Beam search took {after_time - before_time} seconds.') + if node: + print(f'Its solution with a cost of {node.path_cost} is animated below.') + animate(node) + else: + print('No solution was found.') + ''' diff --git a/assignment1aux.py b/assignment1aux.py new file mode 100644 index 000000000..208247d6d --- /dev/null +++ b/assignment1aux.py @@ -0,0 +1,51 @@ +from os import system +from time import sleep + +def visualise(state): + map = state[0] + position = state[1] + move = state[2] + height = len(map) + width = len(map[0]) + print('\n ', *['\u2581' for _ in range(width)], ' ', sep='') + for i in range(height): + print('\u2595', end='') + for j in range(width): + if map[i][j] == 'rock': + print('\u2588', end='') + elif map[i][j] == 'left': + print('\u25c2', end='') + elif map[i][j] == 'up': + print('\u25b4', end='') + elif map[i][j] == 'right': + print('\u25b8', end='') + elif map[i][j] == 'down': + print('\u25be', end='') + elif position == (i, j): + if move == 'right': + print('\u2520', end='') + elif move == 'left': + print('\u2528', end='') + elif move == 'down': + print('\u252f', end='') + elif move == 'up': + print('\u2537', end='') + else: + print('\u25cb', end='') + elif not map[i][j]: + print(' ', end='') + else: + print() + print(f"Unexpected tile representation encountered: '{map[i][j]}'.") + print("Accepted tile representations are '', 'rock', 'left', 'right', 'up', and 'down'.") + raise ValueError(map[i][j]) + print('\u258f') + print(' ', *['\u2594' for _ in range(width)], ' \n', sep='') + +def animate(node): + for node_i in node.path()[:-1]: + visualise(node_i.state) + sleep(2) + for _ in range(len(node_i.state[0]) + 4): + system('tput cuu1') + visualise(node.state) diff --git a/assignment1config.txt b/assignment1config.txt new file mode 100644 index 000000000..2d3fc2cd8 --- /dev/null +++ b/assignment1config.txt @@ -0,0 +1,3 @@ +3 +3 +0,1 \ No newline at end of file diff --git a/search.ipynb b/search.ipynb index caf231dcc..a6026ba9d 100644 --- a/search.ipynb +++ b/search.ipynb @@ -123,33 +123,45 @@ "text/html": [ "\n", - "\n", + "\n", "\n", "\n", " \n", " \n", "