Example #1
0
    def get_path(self, goal):
        current_node = self.current_node
        if not current_node or not goal:
            return []
        elif current_node == goal:
            return [goal]
        if not self.last_target_node:
            self.last_target_node = goal
        if goal.unreachable:
            log.info('Goal unreachable: %s', goal)
            return [current_node]
        elif self.last_target_node == goal:
            if self.destination not in self.current_node.get_edges(self):
                pass
            else:
                log.info('Reusing last path: %s', self.path)
                return self.path
        else:
            self.last_target_node = goal

        start = current_node
        frontier = PriorityQueue()
        frontier.put(start, 0)
        came_from = {}
        cost_so_far = {}
        came_from[start] = None
        cost_so_far[start] = 0

        while not frontier.empty():
            current = frontier.get()
            if current is goal:
                break
            # Get current node edges
            for next in current.get_edges(self):
                new_cost = cost_so_far[current] + current.cost(next)
                if next not in cost_so_far or new_cost < cost_so_far[next]:
                    cost_so_far[next] = new_cost
                    priority = new_cost + self._heuristic(goal, next)
                    frontier.put(next, priority)
                    came_from[next] = current
        path = []
        path.append(goal)
        current = goal
        while True:
            try:
                current = came_from[current]
            except KeyError:
                log.warning('No available path to %s', current)
                current.unreachable = True
                break
            if not current:
                break
            path.append(current)
        # Pop current node from path
        path.pop()
        return path