Lecture #6 – Informed search¶
Lecture notes¶
Slides: Lecture 6
- Related research articles:
Code¶
Problem example¶
We need to modify our definition of the route problem to use a heuristic function. We can also define a basic heurisitic function , the eucliean distance function.
class RouteProblem(Problem):
"""A problem to find a route between locations on a `Map`.
Create a problem with RouteProblem(start, goal, map=Map(...)}).
States are the vertexes in the Map graph; actions are destination states."""
def actions(self, state):
"""The places neighboring `state`."""
return self.map.neighbors[state]
def result(self, state, action):
"""Go to the `action` place, if the map says that is possible."""
return action if action in self.map.neighbors[state] else state
def action_cost(self, s, action, s1):
"""The distance (cost) to go from s to s1."""
return self.map.distances[s, s1]
def h(self, node):
if self.map.heuristic:
return self.map.heuristic[node.state, self.goal]
locs = self.map.locations
return euclidean_distance(locs[node.state], locs[self.goal])
def euclidean_distance(A, B):
"""Straight-line distance between two points."""
return sum(abs(a - b)**2 for (a, b) in zip(A, B)) ** 0.5
I also modified the class Map to accept a static heurisitic to match the example.
class Map:
"""A map of places in a 2D world: a graph with vertexes and links between them.
In `Map(links, locations)`, `links` can be either [(v1, v2)...] pairs,
or a {(v1, v2): distance...} dict. Optional `locations` can be {v1: (x, y)}
If `directed=False` then for every (v1, v2) link, we add a (v2, v1) link."""
def __init__(self, links, locations=None, directed=False, heuristic=None):
if not hasattr(links, 'items'): # Distances are 1 by default
links = {link: 1 for link in links}
if not directed:
for (v1, v2) in list(links):
links[v2, v1] = links[v1, v2]
self.distances = links
self.neighbors = multimap(links)
self.locations = locations or defaultdict(lambda: (0, 0))
self.heuristic = heuristic
if not directed and self.heuristic:
for (v1, v2) in list(self.heuristic):
self.heuristic[v2, v1] = self.heuristic[v1, v2]