diff --git a/cidades.py b/cidades.py index df7921b..a2d1381 100644 --- a/cidades.py +++ b/cidades.py @@ -38,8 +38,13 @@ class Cidades(SearchDomain): return D if X==C2 and Y==C1: return D + def heuristic(self, city, goal_city): - pass + coords_city = cidades_portugal.coordinates[city] + coords_goal_city = cidades_portugal.coordinates[goal_city] + + return ((coords_city[0] - coords_goal_city[0])**2 + (coords_city[1] - coords_goal_city[1])**2)**0.5 + def satisfies(self, city, goal_city): return goal_city==city diff --git a/tree_search.py b/tree_search.py index c243000..21b1865 100644 --- a/tree_search.py +++ b/tree_search.py @@ -62,11 +62,12 @@ class SearchProblem: # Nos de uma arvore de pesquisa class SearchNode: - def __init__(self,state,parent, depth, cost=0): + def __init__(self,state,parent, depth, cost=0, heuristic=0): self.state = state self.parent = parent self.depth = depth self.cost = cost + self.heuristic = heuristic def __str__(self): return "no(" + str(self.state) + "," + str(self.parent) + ")" @@ -86,6 +87,8 @@ class SearchTree: self.solution = None self.terminals = 0 self.non_terminals = 0 + self.highest_cost_nodes = [root] + self.average_depth = 0 @property def length(self): @@ -112,8 +115,10 @@ class SearchTree: while self.open_nodes != []: self.terminals = len(self.open_nodes) node = self.open_nodes.pop(0) + if self.problem.goal_test(node.state): self.solution = node + self.average_depth = self.average_depth / (self.terminals + self.non_terminals) return self.get_path(node) self.non_terminals += 1 @@ -121,10 +126,22 @@ class SearchTree: for a in self.problem.domain.actions(node.state): newstate = self.problem.domain.result(node.state,a) if newstate not in self.get_path(node): - newnode = SearchNode(newstate,node,node.depth+1,node.cost+self.problem.domain.cost(node.state,a)) + newnode = SearchNode( + newstate, + node, + node.depth+1, + node.cost+self.problem.domain.cost(node.state,a), + self.problem.domain.heuristic(newstate,self.problem.goal) + ) if not (limit != None and self.strategy == 'depth' and newnode.depth > limit): lnewnodes.append(newnode) + if newnode.cost > self.highest_cost_nodes[0].cost: + self.highest_cost_nodes = [newnode] + elif newnode.cost == self.highest_cost_nodes[0].cost: + self.highest_cost_nodes.append(newnode) + self.average_depth += newnode.depth self.add_to_open(lnewnodes) + return None # juntar novos nos a lista de nos abertos de acordo com a estrategia @@ -135,4 +152,8 @@ class SearchTree: self.open_nodes[:0] = lnewnodes elif self.strategy == 'uniform': self.open_nodes = sorted(self.open_nodes + lnewnodes, key=lambda node: node.cost) + elif self.strategy == 'greedy': + self.open_nodes = sorted(self.open_nodes + lnewnodes, key=lambda node: node.heuristic) + elif self.strategy == 'a*': + self.open_nodes = sorted(self.open_nodes + lnewnodes, key=lambda node: node.cost + node.heuristic)