ó
 ,µ[c           @   sŸ   d  Z  d d l Z d d l m Z d d l m Z d j d d g ƒ Z d	 d
 d d g Z	 d „  Z
 d „  Z e d d ƒ d „  ƒ Z e d d ƒ d „  ƒ Z d S(   sI   
=======================
Distance-regular graphs
=======================
iÿÿÿÿN(   t   not_implemented_fori   (   t   diameters   
s"   Dheeraj M R <dheerajrav@gmail.com>s%   Aric Hagberg <aric.hagberg@gmail.com>t   is_distance_regulart   is_strongly_regulart   intersection_arrayt   global_parametersc         C   s.   y t  |  ƒ t SWn t j k
 r) t SXd S(   s  Returns True if the graph is distance regular, False otherwise.

    A connected graph G is distance-regular if for any nodes x,y
    and any integers i,j=0,1,...,d (where d is the graph
    diameter), the number of vertices at distance i from x and
    distance j from y depends only on i,j and the graph distance
    between x and y, independently of the choice of x and y.

    Parameters
    ----------
    G: Networkx graph (undirected)

    Returns
    -------
    bool
      True if the graph is Distance Regular, False otherwise

    Examples
    --------
    >>> G=nx.hypercube_graph(6)
    >>> nx.is_distance_regular(G)
    True

    See Also
    --------
    intersection_array, global_parameters

    Notes
    -----
    For undirected and simple graphs only

    References
    ----------
    .. [1] Brouwer, A. E.; Cohen, A. M.; and Neumaier, A.
        Distance-Regular Graphs. New York: Springer-Verlag, 1989.
    .. [2] Weisstein, Eric W. "Distance-Regular Graph."
        http://mathworld.wolfram.com/Distance-RegularGraph.html

    N(   R   t   Truet   nxt   NetworkXErrort   False(   t   G(    (    sC   lib/python2.7/site-packages/networkx/algorithms/distance_regular.pyR      s
    (
c            s+   ‡  f d †  t  ˆ  d g d g | ƒ Dƒ S(   sƒ  Return global parameters for a given intersection array.

    Given a distance-regular graph G with integers b_i, c_i,i = 0,....,d
    such that for any 2 vertices x,y in G at a distance i=d(x,y), there
    are exactly c_i neighbors of y at a distance of i-1 from x and b_i
    neighbors of y at a distance of i+1 from x.

    Thus, a distance regular graph has the global parameters,
    [[c_0,a_0,b_0],[c_1,a_1,b_1],......,[c_d,a_d,b_d]] for the
    intersection array  [b_0,b_1,.....b_{d-1};c_1,c_2,.....c_d]
    where a_i+b_i+c_i=k , k= degree of every vertex.

    Parameters
    ----------
    b : list

    c : list

    Returns
    -------
    iterable
       An iterable over three tuples.

    Examples
    --------
    >>> G = nx.dodecahedral_graph()
    >>> b, c = nx.intersection_array(G)
    >>> list(nx.global_parameters(b, c))
    [(0, 0, 3), (1, 0, 2), (1, 1, 1), (1, 1, 1), (2, 0, 1), (3, 0, 0)]

    References
    ----------
    .. [1] Weisstein, Eric W. "Global Parameters."
       From MathWorld--A Wolfram Web Resource.
       http://mathworld.wolfram.com/GlobalParameters.html

    See Also
    --------
    intersection_array
    c         3   s0   |  ]& \ } } | ˆ  d  | | | f Vq d S(   i    N(    (   t   .0t   xt   y(   t   b(    sC   lib/python2.7/site-packages/networkx/algorithms/distance_regular.pys	   <genexpr>o   s    i    (   t   zip(   R   t   c(    (   R   sC   lib/python2.7/site-packages/networkx/algorithms/distance_regular.pyR   F   s    )t   directedt
   multigraphc         C   s*  t  |  j ƒ  ƒ } t | ƒ \ } } x8 | D]0 \ } } | | k rU t j d ƒ ‚ n  | } q+ Wt t j |  ƒ ƒ } t g  | D] } t | | j ƒ  ƒ ^ q~ ƒ } i  } i  }	 x |  D]}
 x|  D]} y | |
 | } Wn  t	 k
 rý t j d ƒ ‚ n Xt
 g  |  | D]$ } | | |
 | d k r| ^ qƒ } t
 g  |  | D]$ } | | |
 | d k rG| ^ qGƒ } |	 j | | ƒ | k s¤| j | | ƒ | k r¶t j d ƒ ‚ n  | | | <| |	 | <qÃ Wq¶ Wg  t | ƒ D] } | j | d ƒ ^ qßg  t | ƒ D] } |	 j | d d ƒ ^ qf S(   sŽ  Returns the intersection array of a distance-regular graph.

    Given a distance-regular graph G with integers b_i, c_i,i = 0,....,d
    such that for any 2 vertices x,y in G at a distance i=d(x,y), there
    are exactly c_i neighbors of y at a distance of i-1 from x and b_i
    neighbors of y at a distance of i+1 from x.

    A distance regular graph's intersection array is given by,
    [b_0,b_1,.....b_{d-1};c_1,c_2,.....c_d]

    Parameters
    ----------
    G: Networkx graph (undirected)

    Returns
    -------
    b,c: tuple of lists

    Examples
    --------
    >>> G=nx.icosahedral_graph()
    >>> nx.intersection_array(G)
    ([5, 2, 1], [1, 2, 5])

    References
    ----------
    .. [1] Weisstein, Eric W. "Intersection Array."
       From MathWorld--A Wolfram Web Resource.
       http://mathworld.wolfram.com/IntersectionArray.html

    See Also
    --------
    global_parameters
    s   Graph is not distance regular.i   s   Graph is not distance regulari    (   t   itert   degreet   nextR   R   t   dictt   all_pairs_shortest_path_lengtht   maxt   valuest   KeyErrort   lent   gett   range(   R
   R   t   _t   kt   knextt   path_lengtht   nR   t   bintt   cintt   ut   vt   iR   R   t   j(    (    sC   lib/python2.7/site-packages/networkx/algorithms/distance_regular.pyR   r   s0    %
/;;0
(c         C   s   t  |  ƒ o t |  ƒ d k S(   s=  Returns True if and only if the given graph is strongly
    regular.

    An undirected graph is *strongly regular* if

    * it is regular,
    * each pair of adjacent vertices has the same number of neighbors in
      common,
    * each pair of nonadjacent vertices has the same number of neighbors
      in common.

    Each strongly regular graph is a distance-regular graph.
    Conversely, if a distance-regular graph has diameter two, then it is
    a strongly regular graph. For more information on distance-regular
    graphs, see :func:`is_distance_regular`.

    Parameters
    ----------
    G : NetworkX graph
        An undirected graph.

    Returns
    -------
    bool
        Whether `G` is strongly regular.

    Examples
    --------

    The cycle graph on five vertices is strongly regular. It is
    two-regular, each pair of adjacent vertices has no shared neighbors,
    and each pair of nonadjacent vertices has one shared neighbor::

        >>> import networkx as nx
        >>> G = nx.cycle_graph(5)
        >>> nx.is_strongly_regular(G)
        True

    i   (   R   R   (   R
   (    (    sC   lib/python2.7/site-packages/networkx/algorithms/distance_regular.pyR   µ   s    4(   t   __doc__t   networkxR   t   networkx.utilsR    t   distance_measuresR   t   joint
   __author__t   __all__R   R   R   R   (    (    (    sC   lib/python2.7/site-packages/networkx/algorithms/distance_regular.pyt   <module>
   s   		/	,C