Exemple #1
0
def compute_cost(node: Node, neighbour: Node, grid: Grid,
                 agent_characteristics: AgentCharacteristics) -> None:
    parent = node.parent or node
    mp_cost = euclidean(neighbour, parent)
    if line_of_sight(parent, neighbour, grid, agent_characteristics):
        if parent.g + mp_cost < neighbour.g:
            neighbour.parent = parent
            neighbour.g = parent.g + mp_cost

    else:
        m_cost = euclidean(neighbour, node)
        if node.g + m_cost < neighbour.g:
            neighbour.parent = node
            neighbour.g = node.g + m_cost
Exemple #2
0
def compute_cost(node: Node, neighbour: Node, grid: Grid,
                 agent_characteristics: AgentCharacteristics) -> None:
    m_cost = euclidean(
        neighbour, node
    )  # 1 if node.x == neighbour.x or node.y == neighbour.y else 1.41  # Cost of the connection
    if node.g + m_cost < neighbour.g:
        neighbour.parent = node
        neighbour.g = node.g + m_cost
Exemple #3
0
    def identifySuccessors(self, node, method):
        """
        Identify successors for the given node. Runs a jump point search in the
        direction of each available neighbor, adding any points found to the open
        list.
        """
        endX = self.endNode.x
        endY = self.endNode.y
        x = node.x
        y = node.y

        neighbors = self.findNeighbors(node, method)
        self.expendCount = self.expendCount + len(neighbors)
        for i in range(len(neighbors)):
            neighbor = neighbors[i]
            if method == 'A*':
                jumpPoint = neighbor
            else:
                jumpPoint = self.jump(neighbor[0], neighbor[1], x, y)
            # 找到跳点
            if jumpPoint:
                jx = jumpPoint[0]
                jy = jumpPoint[1]
                jumpNode = self.grid.getNodeAt(jx, jy)
                if jumpNode.closed:
                    continue
                if (method == 'A*') or (method == 'jps'):
                    d = heuristics.manhattan(abs(jx - x), abs(jy - y))
                else:
                    d = heuristics.diagonal(abs(jx - x), abs(jy - y))
                ng = node.g + d  # next `g` value

                if not jumpNode.opened or ng < jumpNode.g:
                    jumpNode.g = ng
                    jumpNode.h = heuristics.diagonal(abs(jx - endX), abs(jy - endY))
                    if (method == 'A*') or (method == 'jps'):
                        jumpNode.h = heuristics.manhattan(abs(jx - endX), abs(jy - endY))
                    else:
                        # todo: 使用改进优秀的启发函数
                        dx1 = abs(jx - endX)
                        dy1 = abs(jy - endY)
                        dx2 = abs(self.startNode.x - endX)
                        dy2 = abs(self.startNode.y - endY)
                        cross = abs(dx1 * dy2 - dx2 * dy1) / (heuristics.euclidean(dx2, dy2) + 1)
                        jumpNode.h = heuristics.diagonal(abs(jx - x), abs(jy - y)) + cross
                    jumpNode.f = jumpNode.g + jumpNode.h
                    jumpNode.parent = node
                    if not jumpNode.opened:
                        heapq.heappush(self.openList, (jumpNode.f, jumpNode))
                        jumpNode.opened = True
                    else:
                        for i in range(len(self.openList)):
                            if self.openList[i][1] == jumpNode:
                                self.openList[i] = (jumpNode.f, jumpNode)
Exemple #4
0
def identify_successors(
    node: Node,
    openlist: List[Node],
    agent_characteristics: AgentCharacteristics,
    end_node: Node,
    grid: Grid,
    options: SearchOptions,
    to_clear: Dict[Node, bool],
    heuristic: Heuristic,
) -> None:
    """
    Searches for successors of a given node in the direction of each of its neighbours.
    This is a generic translation of the algorithm 1 in the paper:
      http://users.cecs.anu.edu.au/~dharabor/data/papers/harabor-grastien-aaai11.pdf
    Also, we notice that processing neighbours in a reverse order producing a natural
    looking path, as the pathfinder tends to keep heading in the same direction.
    In case a jump point was found, and this node happened to be diagonal to the
    node currently expanded in a straight mode search, we skip this jump point.
    """
    neighbours = find_neighbours(grid, options, node, agent_characteristics)
    neighbours.reverse()
    for neighbour in neighbours:
        skip = False
        jump_node = jump(grid, neighbour, node, end_node,
                         agent_characteristics, options)

        if jump_node and not options.allow_diagonal:
            if jump_node.x != node.x and jump_node.y != node.y:
                skip = True

        # Perform regular A* on a set of jump points
        if jump_node and not skip and not jump_node.closed:
            # Update the jump node and move it in the closed list if it wasn't there
            extraG = euclidean(jump_node, node)
            new_g = node.g + extraG
            if not jump_node.opened or new_g < jump_node.g:
                to_clear[jump_node] = True
                jump_node.g = new_g
                jump_node.h = jump_node.h or heuristic(jump_node, end_node)
                jump_node.parent = node
                if not jump_node.opened:
                    heapq.heappush(openlist, jump_node)
                    jump_node.open()
                else:
                    heapq.heapify(openlist)
Exemple #5
0
    def length(self) -> int:
        path_length = 0
        for i in range(1, len(self.nodes)):
            path_length += euclidean(self.nodes[i], self.nodes[i - 1])

        return path_length