示例#1
0
 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())
示例#2
0
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
示例#3
0
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
示例#4
0
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
示例#5
0
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