Compare commits

..

No commits in common. "2d498eb23162177eb833879081e7b075caea4a51" and "7f5313608ec0b988da0e37a4c9c7b387e65c8f13" have entirely different histories.

2 changed files with 125 additions and 161 deletions

View File

@ -1,130 +1,119 @@
#
# Module: cidades
#
# Implements a SearchDomain for find paths between cities
# using the tree_search module
#
# (c) Luis Seabra Lopes
# Introducao a Inteligencia Artificial, 2012-2020
# Inteligência Artificial, 2014-2023
#
from tree_search import *
class Cidades(SearchDomain):
def __init__(self,connections, coordinates):
self.connections = connections
self.coordinates = coordinates
def actions(self,city):
actlist = []
for (C1,C2,D) in self.connections:
if (C1==city):
actlist += [(C1,C2)]
elif (C2==city):
actlist += [(C2,C1)]
return actlist
def result(self,city,action):
(C1,C2) = action
if C1==city:
return C2
def cost(self, city, action):
(C1,C2) = action
for (X,Y,D) in self.connections:
if X==C1 and Y==C2:
return D
if X==C2 and Y==C1:
return D
def heuristic(self, city, goal_city):
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
cidades_portugal = Cidades(
# Ligacoes por estrada
[
('Coimbra', 'Leiria', 73),
('Aveiro', 'Agueda', 35),
('Porto', 'Agueda', 79),
('Agueda', 'Coimbra', 45),
('Viseu', 'Agueda', 78),
('Aveiro', 'Porto', 78),
('Aveiro', 'Coimbra', 65),
('Figueira', 'Aveiro', 77),
('Braga', 'Porto', 57),
('Viseu', 'Guarda', 75),
('Viseu', 'Coimbra', 91),
('Figueira', 'Coimbra', 52),
('Leiria', 'Castelo Branco', 169),
('Figueira', 'Leiria', 62),
('Leiria', 'Santarem', 78),
('Santarem', 'Lisboa', 82),
('Santarem', 'Castelo Branco', 160),
('Castelo Branco', 'Viseu', 174),
('Santarem', 'Evora', 122),
('Lisboa', 'Evora', 132),
('Evora', 'Beja', 105),
('Lisboa', 'Beja', 178),
('Faro', 'Beja', 147),
# extra
('Braga', 'Guimaraes', 25),
('Porto', 'Guimaraes', 44),
('Guarda', 'Covilha', 46),
('Viseu', 'Covilha', 57),
('Castelo Branco', 'Covilha', 62),
('Guarda', 'Castelo Branco', 96),
('Lamego','Guimaraes', 88),
('Lamego','Viseu', 47),
('Lamego','Guarda', 64),
('Portalegre','Castelo Branco', 64),
('Portalegre','Santarem', 157),
('Portalegre','Evora', 194) ],
# City coordinates
{ 'Aveiro': (41,215),
'Figueira': ( 24, 161),
'Coimbra': ( 60, 167),
'Agueda': ( 58, 208),
'Viseu': ( 104, 217),
'Braga': ( 61, 317),
'Porto': ( 45, 272),
'Lisboa': ( 0, 0),
'Santarem': ( 38, 59),
'Leiria': ( 28, 115),
'Castelo Branco': ( 140, 124),
'Guarda': ( 159, 204),
'Evora': (120, -10),
'Beja': (125, -110),
'Faro': (120, -250),
#extra
'Guimaraes': ( 71, 300),
'Covilha': ( 130, 175),
'Lamego' : (125,250),
'Portalegre': (130,170) }
)
p = SearchProblem(cidades_portugal,'Braga','Faro')
t = SearchTree(p,'breadth')
print(t.search())
# Atalho para obter caminho de c1 para c2 usando strategy:
def search_path(c1,c2,strategy):
my_prob = SearchProblem(cidades_portugal,c1,c2)
my_tree = SearchTree(my_prob)
my_tree.strategy = strategy
return my_tree.search()
# Module: cidades
#
# Implements a SearchDomain for find paths between cities
# using the tree_search module
#
# (c) Luis Seabra Lopes
# Introducao a Inteligencia Artificial, 2012-2020
# Inteligência Artificial, 2014-2023
#
from tree_search import *
class Cidades(SearchDomain):
def __init__(self,connections, coordinates):
self.connections = connections
self.coordinates = coordinates
def actions(self,city):
actlist = []
for (C1,C2,D) in self.connections:
if (C1==city):
actlist += [(C1,C2)]
elif (C2==city):
actlist += [(C2,C1)]
return actlist
def result(self,city,action):
(C1,C2) = action
if C1==city:
return C2
def cost(self, city, action):
pass
def heuristic(self, city, goal_city):
pass
def satisfies(self, city, goal_city):
return goal_city==city
cidades_portugal = Cidades(
# Ligacoes por estrada
[
('Coimbra', 'Leiria', 73),
('Aveiro', 'Agueda', 35),
('Porto', 'Agueda', 79),
('Agueda', 'Coimbra', 45),
('Viseu', 'Agueda', 78),
('Aveiro', 'Porto', 78),
('Aveiro', 'Coimbra', 65),
('Figueira', 'Aveiro', 77),
('Braga', 'Porto', 57),
('Viseu', 'Guarda', 75),
('Viseu', 'Coimbra', 91),
('Figueira', 'Coimbra', 52),
('Leiria', 'Castelo Branco', 169),
('Figueira', 'Leiria', 62),
('Leiria', 'Santarem', 78),
('Santarem', 'Lisboa', 82),
('Santarem', 'Castelo Branco', 160),
('Castelo Branco', 'Viseu', 174),
('Santarem', 'Evora', 122),
('Lisboa', 'Evora', 132),
('Evora', 'Beja', 105),
('Lisboa', 'Beja', 178),
('Faro', 'Beja', 147),
# extra
('Braga', 'Guimaraes', 25),
('Porto', 'Guimaraes', 44),
('Guarda', 'Covilha', 46),
('Viseu', 'Covilha', 57),
('Castelo Branco', 'Covilha', 62),
('Guarda', 'Castelo Branco', 96),
('Lamego','Guimaraes', 88),
('Lamego','Viseu', 47),
('Lamego','Guarda', 64),
('Portalegre','Castelo Branco', 64),
('Portalegre','Santarem', 157),
('Portalegre','Evora', 194) ],
# City coordinates
{ 'Aveiro': (41,215),
'Figueira': ( 24, 161),
'Coimbra': ( 60, 167),
'Agueda': ( 58, 208),
'Viseu': ( 104, 217),
'Braga': ( 61, 317),
'Porto': ( 45, 272),
'Lisboa': ( 0, 0),
'Santarem': ( 38, 59),
'Leiria': ( 28, 115),
'Castelo Branco': ( 140, 124),
'Guarda': ( 159, 204),
'Evora': (120, -10),
'Beja': (125, -110),
'Faro': (120, -250),
#extra
'Guimaraes': ( 71, 300),
'Covilha': ( 130, 175),
'Lamego' : (125,250),
'Portalegre': (130,170) }
)
p = SearchProblem(cidades_portugal,'Braga','Faro')
t = SearchTree(p,'breadth')
print(t.search())
# Atalho para obter caminho de c1 para c2 usando strategy:
def search_path(c1,c2,strategy):
my_prob = SearchProblem(cidades_portugal,c1,c2)
my_tree = SearchTree(my_prob)
my_tree.strategy = strategy
return my_tree.search()

View File

@ -62,16 +62,12 @@ class SearchProblem:
# Nos de uma arvore de pesquisa
class SearchNode:
def __init__(self,state,parent, depth, cost=0, heuristic=0):
def __init__(self,state,parent, depth):
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) + ")"
def __repr__(self):
return str(self)
@ -87,8 +83,6 @@ 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):
@ -98,10 +92,6 @@ class SearchTree:
def avg_branching(self):
return ((self.terminals + self.non_terminals) - 1) / self.non_terminals if self.non_terminals > 0 else None
@property
def cost(self):
return self.solution.cost if self.solution else None
# obter o caminho (sequencia de estados) da raiz ate um no
def get_path(self,node):
if node.parent == None:
@ -115,10 +105,8 @@ 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
@ -126,22 +114,13 @@ 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),
self.problem.domain.heuristic(newstate,self.problem.goal)
)
if not (limit != None and self.strategy == 'depth' and newnode.depth > limit):
newnode = SearchNode(newstate,node,node.depth+1)
if limit != None and self.strategy == 'depth':
if newnode.depth <= limit:
lnewnodes.append(newnode)
else:
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
@ -151,9 +130,5 @@ class SearchTree:
elif self.strategy == 'depth':
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)
pass