o
    3ήcN                     @   sT   d Z ddlmZmZ ddlmZ ddlZddlm	Z	 ddgZ
dd	dZdd
dZdS )zCShortest paths and path lengths using the A* ("A star") algorithm.
    )heappopheappush)countN)_weight_function
astar_pathastar_path_lengthweightc                 C   s  || vs|| vrd| d| d}t ||du rdd }t}t}t| |}t }dt||ddfg}	i }
i }|	r||	\}}}}}||krc|g}|}|dur]|| || }|dusP|  |S ||v ry|| du rnq8|
| \}}||k ryq8|||< | | 	 D ]5\}}||||| }||
v r|
| \}}||krqn|||}||f|
|< ||	|| t||||f q|	s:t 
d| d	| )
ab  Returns a list of nodes in a shortest path between source and target
    using the A* ("A-star") algorithm.

    There may be more than one shortest path.  This returns only one.

    Parameters
    ----------
    G : NetworkX graph

    source : node
       Starting node for path

    target : node
       Ending node for path

    heuristic : function
       A function to evaluate the estimate of the distance
       from the a node to the target.  The function takes
       two nodes arguments and must return a number.
       If the heuristic is inadmissible (if it might
       overestimate the cost of reaching the goal from a node),
       the result may not be a shortest path.
       The algorithm does not support updating heuristic
       values for the same node due to caching the first
       heuristic calculation per node.

    weight : string or function
       If this is a string, then edge weights will be accessed via the
       edge attribute with this key (that is, the weight of the edge
       joining `u` to `v` will be ``G.edges[u, v][weight]``). If no
       such edge attribute exists, the weight of the edge is assumed to
       be one.
       If this is a function, the weight of an edge is the value
       returned by the function. The function must accept exactly three
       positional arguments: the two endpoints of an edge and the
       dictionary of edge attributes for that edge. The function must
       return a number.

    Raises
    ------
    NetworkXNoPath
        If no path exists between source and target.

    Examples
    --------
    >>> G = nx.path_graph(5)
    >>> print(nx.astar_path(G, 0, 4))
    [0, 1, 2, 3, 4]
    >>> G = nx.grid_graph(dim=[3, 3])  # nodes are two-tuples (x,y)
    >>> nx.set_edge_attributes(G, {e: e[1][0] * 2 for e in G.edges()}, "cost")
    >>> def dist(a, b):
    ...     (x1, y1) = a
    ...     (x2, y2) = b
    ...     return ((x1 - x2) ** 2 + (y1 - y2) ** 2) ** 0.5
    >>> print(nx.astar_path(G, (0, 0), (2, 2), heuristic=dist, weight="cost"))
    [(0, 0), (0, 1), (0, 2), (1, 2), (2, 2)]


    See Also
    --------
    shortest_path, dijkstra_path

    Either source  or target  is not in GNc                 S   s   dS )Nr    )uvr   r   O/tmp/pip-target-vg8gfxp4/lib/python/networkx/algorithms/shortest_paths/astar.py	heuristicR   s   zastar_path.<locals>.heuristicr   zNode z not reachable from )nxNodeNotFoundr   r   r   r   nextappendreverseitemsNetworkXNoPath)Gsourcetargetr   r   msgpushpopcqueueenqueuedexplored___curnodedistparentpathnodeqcosthneighborwncostr   r   r   r      sT   @



(c                    st   | vs| vrd| d| d}t |t t |||}t fddt|dd |dd D S )	a  Returns the length of the shortest path between source and target using
    the A* ("A-star") algorithm.

    Parameters
    ----------
    G : NetworkX graph

    source : node
       Starting node for path

    target : node
       Ending node for path

    heuristic : function
       A function to evaluate the estimate of the distance
       from the a node to the target.  The function takes
       two nodes arguments and must return a number.
       If the heuristic is inadmissible (if it might
       overestimate the cost of reaching the goal from a node),
       the result may not be a shortest path.
       The algorithm does not support updating heuristic
       values for the same node due to caching the first
       heuristic calculation per node.

    weight : string or function
       If this is a string, then edge weights will be accessed via the
       edge attribute with this key (that is, the weight of the edge
       joining `u` to `v` will be ``G.edges[u, v][weight]``). If no
       such edge attribute exists, the weight of the edge is assumed to
       be one.
       If this is a function, the weight of an edge is the value
       returned by the function. The function must accept exactly three
       positional arguments: the two endpoints of an edge and the
       dictionary of edge attributes for that edge. The function must
       return a number.
    Raises
    ------
    NetworkXNoPath
        If no path exists between source and target.

    See Also
    --------
    astar_path

    r	   r
   r   c                 3   s(    | ]\}}|| | | V  qd S )Nr   ).0r   r   r   r   r   r   	<genexpr>   s   & z$astar_path_length.<locals>.<genexpr>N   )r   r   r   r   sumzip)r   r   r   r   r   r   r'   r   r/   r   r      s   .

.)Nr   )__doc__heapqr   r   	itertoolsr   networkxr   +networkx.algorithms.shortest_paths.weightedr   __all__r   r   r   r   r   r   <module>   s    
 