Compare commits

...

2 Commits

Author SHA1 Message Date
8fa4eccf04
feat: complete cornerProblem setup 2024-03-22 03:49:37 +08:00
c80783c695
feat: A* algorithm 2024-03-22 02:50:48 +08:00
2 changed files with 65 additions and 11 deletions

View File

@ -4,7 +4,6 @@ Pacman agents (in searchAgents.py).
Please only change the parts of the file you are asked to. Look for the lines Please only change the parts of the file you are asked to. Look for the lines
that say that say
"*** YOUR CODE HERE ***" "*** YOUR CODE HERE ***"
Follow the project description for details. Follow the project description for details.
@ -88,7 +87,7 @@ def depthFirstSearch(problem: SearchProblem):
curr_state = problem.getStartState() curr_state = problem.getStartState()
isGoal = problem.isGoalState(curr_state) isGoal = problem.isGoalState(curr_state)
visited = set([curr_state]) visited = list([curr_state])
stack = util.Stack() stack = util.Stack()
while not isGoal: while not isGoal:
@ -107,7 +106,7 @@ def depthFirstSearch(problem: SearchProblem):
else: else:
obj = stack.pop() obj = stack.pop()
(curr_state, direction, cost) = obj['state'] (curr_state, direction, cost) = obj['state']
visited.add(curr_state) visited.append(curr_state)
actions = obj['actions'] + [ direction ] actions = obj['actions'] + [ direction ]
isGoal = problem.isGoalState(curr_state) isGoal = problem.isGoalState(curr_state)
@ -123,15 +122,16 @@ def breadthFirstSearch(problem: SearchProblem):
curr_state = problem.getStartState() curr_state = problem.getStartState()
isGoal = problem.isGoalState(curr_state) isGoal = problem.isGoalState(curr_state)
visited = set([curr_state]) visited = list([curr_state])
queue = util.Queue() queue = util.Queue()
while not isGoal: while not isGoal:
print(curr_state)
# push in the Stack # push in the Stack
successors = problem.getSuccessors(curr_state) successors = problem.getSuccessors(curr_state)
for (state, direction, cost) in successors: for (state, direction, cost) in successors:
if state not in visited: if state not in visited:
visited.add(state) visited.append(state)
queue.push({ queue.push({
'state': (state, direction, cost), 'state': (state, direction, cost),
'actions': actions 'actions': actions
@ -158,7 +158,7 @@ def uniformCostSearch(problem: SearchProblem):
isGoal = problem.isGoalState(curr_state) isGoal = problem.isGoalState(curr_state)
costs = 0 costs = 0
visited = set([curr_state]) visited = list([curr_state])
queue = util.PriorityQueue() queue = util.PriorityQueue()
while not isGoal: while not isGoal:
@ -178,7 +178,7 @@ def uniformCostSearch(problem: SearchProblem):
else: else:
obj = queue.pop() obj = queue.pop()
(curr_state, direction, cost) = obj['state'] (curr_state, direction, cost) = obj['state']
visited.add(curr_state) visited.append(curr_state)
actions = obj['actions'] + [ direction ] actions = obj['actions'] + [ direction ]
costs = obj['costs'] + cost costs = obj['costs'] + cost
@ -197,7 +197,41 @@ def nullHeuristic(state, problem=None):
def aStarSearch(problem: SearchProblem, heuristic=nullHeuristic): def aStarSearch(problem: SearchProblem, heuristic=nullHeuristic):
"""Search the node that has the lowest combined cost and heuristic first.""" """Search the node that has the lowest combined cost and heuristic first."""
"*** YOUR CODE HERE ***" "*** YOUR CODE HERE ***"
util.raiseNotDefined() actions = []
curr_state = problem.getStartState()
isGoal = problem.isGoalState(curr_state)
costs = 0
visited = list([curr_state])
queue = util.PriorityQueue()
while not isGoal:
# push in the P Queue
successors = problem.getSuccessors(curr_state)
for (state, direction, cost) in successors:
if state not in visited:
queue.push({
'state': (state, direction, cost),
'actions': actions,
'costs': costs
}, costs + cost + heuristic(state, problem)) # if visited this successor node, how much cost will the agent need
# check whether reachable
if queue.isEmpty():
return []
else:
obj = queue.pop()
(curr_state, direction, cost) = obj['state']
visited.append(curr_state)
actions = obj['actions'] + [ direction ]
costs = obj['costs'] + cost
isGoal = problem.isGoalState(curr_state)
return actions
# Abbreviations # Abbreviations

View File

@ -281,14 +281,17 @@ class CornersProblem(search.SearchProblem):
space) space)
""" """
"*** YOUR CODE HERE ***" "*** YOUR CODE HERE ***"
util.raiseNotDefined() return {
'position': self.startingPosition,
'target_corners': self.corners,
}
def isGoalState(self, state: Any): def isGoalState(self, state: Any):
""" """
Returns whether this search state is a goal state of the problem. Returns whether this search state is a goal state of the problem.
""" """
"*** YOUR CODE HERE ***" "*** YOUR CODE HERE ***"
util.raiseNotDefined() return len(state['target_corners']) == 0
def getSuccessors(self, state: Any): def getSuccessors(self, state: Any):
""" """
@ -311,7 +314,24 @@ class CornersProblem(search.SearchProblem):
# hitsWall = self.walls[nextx][nexty] # hitsWall = self.walls[nextx][nexty]
"*** YOUR CODE HERE ***" "*** YOUR CODE HERE ***"
x, y = state['position']
dx, dy = Actions.directionToVector(action)
nextx, nexty = int(x + dx), int(y + dy)
hitsWall = self.walls[nextx][nexty]
if not hitsWall:
# new state (position, corners)
if (nextx, nexty) in state['target_corners']:
new_corners = tuple( i for i in state['target_corners'] if i != (nextx, nexty) ) # remove the corner which reached
else:
new_corners = state['target_corners']
new_state = {
'position': (nextx, nexty),
'target_corners': new_corners,
}
successors.append((new_state, action, 1))
self._expanded += 1 # DO NOT CHANGE self._expanded += 1 # DO NOT CHANGE
return successors return successors
@ -403,4 +423,4 @@ class FoodSearchProblem:
if self.walls[x][y]: if self.walls[x][y]:
return 999999 return 999999
cost += 1 cost += 1
return cost return cost