def test_extract(self): bh = BinaryHeap(compare=lambda a, b: a < b) bh.insert(4) bh.insert(1) bh.insert(1) bh.insert(3) bh.insert(3) bh.insert(2) bh.insert(2) self.assertEqual(4, bh.extract()) self.assertEqual(3, bh.extract()) self.assertEqual(3, bh.extract()) self.assertEqual(2, bh.extract()) self.assertEqual(2, bh.extract()) self.assertEqual(1, bh.extract()) self.assertEqual(1, bh.extract())
class Astar: def __init__(self, initial_state, heuristic, weight=1): self.expansions = 0 self.generated = 0 self.initial_state = initial_state self.weight = weight self.heuristic = heuristic def search(self): self.start_time = time.process_time() self.open = BinaryHeap() self.expansions = 0 initial_node = Node(self.initial_state) initial_node.g = 0 initial_node.h = self.heuristic(self.initial_state) initial_node.key = 10000 * self.weight * initial_node.h # asignamos el valor f self.open.insert(initial_node) # para cada estado alguna vez generado, generated almacena # el Node que le corresponde self.generated = {} self.generated[self.initial_state] = initial_node while not self.open.is_empty(): n = self.open.extract() # extrae n de la open if n.state.is_goal(): self.end_time = time.process_time() return n succ = n.state.successors() self.expansions += 1 for child_state, action, cost in succ: child_node = self.generated.get(child_state) is_new = child_node is None # es la primera vez que veo a child_state path_cost = n.g + cost # costo del camino encontrado hasta child_state if is_new or path_cost < child_node.g: # si vemos el estado child_state por primera vez o lo vemos por # un mejor camino, entonces lo agregamos a open if is_new: # creamos el nodo de child_state child_node = Node(child_state, n) child_node.h = self.heuristic(child_state) self.generated[child_state] = child_node child_node.action = action child_node.parent = n child_node.g = path_cost child_node.key = 10000 * ( child_node.g + self.weight * child_node.h ) - child_node.g # actualizamos el f de child_node self.open.insert( child_node ) # inserta child_node a la open si no esta en la open self.end_time = time.process_time( ) # en caso contrario, modifica la posicion de child_node en open return None
class PriorityQueue: def __init__(self): self.binary_heap = BinaryHeap(lambda a, b: a[1] < b[1]) def insert(self, element): self.binary_heap.insert(element) def multiple_insert(self, elements): for element in elements: self.insert(element) def extract(self): element = self.binary_heap.extract() return element[0] if element else element
class Astar: def __init__(self, initial_state, heuristic, weight=1): self.expansions = 0 self.generated = 0 self.initial_state = initial_state self.heuristic = heuristic self.weight = weight def estimate_suboptimality(self, result): costo = result.g mini = 1000000000 for n in self.open: f = n.h + n.g if f < mini: mini = f return costo / mini print(self.open) return 0 # este método debe ser implementado en la parte 1 def fvalue(self, g, h): return ( g + self.weight * h, h ) #Esto nos permite seleccionar primero los que tienen menor h si g+h spn iguales def search(self): self.start_time = time.process_time() self.open = BinaryHeap() self.expansions = 0 initial_node = Node(self.initial_state) initial_node.g = 0 initial_node.h = self.heuristic(self.initial_state) initial_node.key = self.fvalue(0, initial_node.h) # asignamos el valor f self.open.insert(initial_node) # para cada estado alguna vez generado, generated almacena # el Node que le corresponde self.generated = {} self.generated[self.initial_state] = initial_node while not self.open.is_empty(): n = self.open.extract() # extrae n de la open if n.state.is_goal(): self.end_time = time.process_time() return n succ = n.state.successors() self.expansions += 1 for child_state, action, cost in succ: child_node = self.generated.get(child_state) is_new = child_node is None # es la primera vez que veo a child_state path_cost = n.g + cost # costo del camino encontrado hasta child_state if is_new or path_cost < child_node.g: # si vemos el estado child_state por primera vez o lo vemos por # un mejor camino, entonces lo agregamos a open if is_new: # creamos el nodo de child_state child_node = Node(child_state, n) child_node.h = self.heuristic(child_state) self.generated[child_state] = child_node child_node.action = action child_node.parent = n child_node.g = path_cost child_node.key = self.fvalue( child_node.g, child_node.h) # actualizamos el valor f de child_node self.open.insert( child_node ) # inserta child_node a la open si no esta en la open self.end_time = time.process_time( ) # en caso contrario, modifica la posicion de child_node en open return None
class Ara: def __init__(self, initial_state, heuristic, weight, max_expansions): self.expansions = 0 self.generated = 0 self.initial_state = initial_state self.heuristic = heuristic self.weight = weight self.open = None self.cost = None self.max_expansions = max_expansions self.last_solution = None def estimate_suboptimality(self): cost = self.cost denominator = min(self.open, key=lambda x: x.g + x.h) denominator_num = denominator.h + denominator.g return cost / denominator_num def fvalue(self, g, h): return g + self.weight * h def adjust_weight(self): denominator = min(self.open, key=lambda x: x.g + x.h) denominator_num = denominator.h + denominator.g self.weight = self.last_solution.g / denominator_num def recalculate_open(self): for i in self.open: i.key = self.fvalue(i.g, i.h) self.open.reorder() def search(self): self.start_time = time.process_time() self.open = BinaryHeap() self.expansions = 0 initial_node = Node(self.initial_state) initial_node.g = 0 initial_node.h = self.heuristic(self.initial_state) initial_node.key = self.fvalue(0, initial_node.h) # asignamos el valor f self.open.insert(initial_node) self.generated = {} self.generated[self.initial_state] = initial_node while self.expansions <= self.max_expansions: while not self.open.is_empty(): if self.expansions >= self.max_expansions: return self.last_solution n = self.open.extract() if not self.open.is_empty() and self.open.top().key == n.key: tied_node = self.open.top() if tied_node.g < n.g: tied_node = self.open.extract() self.open.insert(n) n = tied_node if n.state.is_goal(): self.end_time = time.process_time() self.cost = n.g self.last_solution = n self.adjust_weight() self.recalculate_open() #print('aaa') yield n if not (self.last_solution is not None and n.g + n.h >= self.last_solution.g): succ = n.state.successors() self.expansions += 1 if self.expansions >= self.max_expansions: return self.last_solution for child_state, action, cost in succ: child_node = self.generated.get(child_state) is_new = child_node is None path_cost = n.g + cost if is_new or path_cost < child_node.g: if is_new: child_node = Node(child_state, n) child_node.h = self.heuristic(child_state) self.generated[child_state] = child_node child_node.action = action child_node.parent = n child_node.g = path_cost child_node.key = self.fvalue( child_node.g, child_node.h) self.open.insert(child_node) self.end_time = time.process_time() if self.open.is_empty(): #print("empty open") return self.last_solution #return None return self.last_solution