a
    J5d4                     @   s   d Z ddlmZ ddlmZmZ ddlmZ ddlZ	ddl
mZ g dZdZd	Zd
d eeD Zdd ZeddddZdd Zeddd Zeddd Zeddd Zeddd Zeddd ZdS )z*Functions for analyzing triads of a graph.    )defaultdict)combinationspermutations)sampleN)not_implemented_for)triadic_censusis_triadall_triplets
all_triadstriads_by_type
triad_typerandom_triad)@      r      r            r   r         r   r   r      r   r   r   r   r   	   r      r   
   r      r   r         r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r      )003012102021D021U021C111D111U030T030C201120D120U120C210300c                 C   s   i | ]\}}|t |d   qS )r   )TRIAD_NAMES).0icode r2   V/var/www/html/django/DPS/env/lib/python3.9/site-packages/networkx/algorithms/triads.py
<dictcomp>u       r4   c                    sJ   ||df||df||df||df||df||dff}t  fdd|D S )	zReturns the integer code of the given triad.

    This is some fancy magic that comes from Batagelj and Mrvar's paper. It
    treats each edge joining a pair of `v`, `u`, and `w` as a bit in
    the binary representation of an integer.

    r   r   r   r   r       c                 3   s$   | ]\}}}| | v r|V  qd S Nr2   )r/   uvxGr2   r3   	<genexpr>   r5   z_tricode.<locals>.<genexpr>)sum)r<   r9   r8   wZcombosr2   r;   r3   _tricodex   s    4r@   Z
undirectedc                    s.  t  ||dur.t|tkr.tdt t }dd tD }|r~ j }|fddt|D   fdd D } fdd D |r fd	d|D tfd
d|D }|d }tfdd|D }|d }	dd tD }
D ]}|| }| }|r6d } } }}|D ]^}|| || krVq:|| }||B ||h }|D ]p}|| || k s|| ||   k r|| k rrn n0||| vrrt	 |||}|
t
|   d7  < qr||v r|
d  t| d 7  < n|
d  t| d 7  < |r:|vr:| }|t|| @ 7 }|t||  7 }| }|t|| @ 7 }|t||  7 }q:|r
|
d  |||d   7  < |
d  |	||d   7  < q
d  d  d }||d  |d  d }|| }|t|
  |
d< |
S )a  Determines the triadic census of a directed graph.

    The triadic census is a count of how many of the 16 possible types of
    triads are present in a directed graph. If a list of nodes is passed, then
    only those triads are taken into account which have elements of nodelist in them.

    Parameters
    ----------
    G : digraph
       A NetworkX DiGraph
    nodelist : list
        List of nodes for which you want to calculate triadic census

    Returns
    -------
    census : dict
       Dictionary with triad type as keys and number of occurrences as values.

    Notes
    -----
    This algorithm has complexity $O(m)$ where $m$ is the number of edges in
    the graph.

    Raises
    ------
    ValueError
        If `nodelist` contains duplicate nodes or nodes not in `G`.
        If you want to ignore this you can preprocess with `set(nodelist) & G.nodes`

    See also
    --------
    triad_graph

    References
    ----------
    .. [1] Vladimir Batagelj and Andrej Mrvar, A subquadratic triad census
        algorithm for large sparse networks with small maximum degree,
        University of Ljubljana,
        http://vlado.fmf.uni-lj.si/pub/networks/doc/triads/triads.pdf

    Nz3nodelist includes duplicate nodes or nodes not in Gc                 S   s   i | ]\}}||qS r2   r2   r/   r0   nr2   r2   r3   r4      r5   z"triadic_census.<locals>.<dictcomp>c                 3   s   | ]\}}||  fV  qd S r7   r2   rA   )Nr2   r3   r=      r5   z!triadic_census.<locals>.<genexpr>c                    s*   i | ]"}| j |   j|  B qS r2   predkeyssuccr/   rB   r;   r2   r3   r4      r5   c                    s*   i | ]"}| j |   j|  @ qS r2   rD   rH   r;   r2   r3   r4      r5   c                    s*   i | ]"}| j |   j|  A qS r2   rD   rH   r;   r2   r3   r4      r5   c                 3   s(   | ] }| D ]}| vrd V  qqdS r   Nr2   r/   rB   Znbr)nodesetsgl_nbrsr2   r3   r=      r5   r   c                 3   s(   | ] } | D ]}|vrd V  qqdS rI   r2   rJ   )dbl_nbrsrK   r2   r3   r=      r5   c                 S   s   i | ]
}|d qS )r   r2   )r/   namer2   r2   r3   r4      r5   r   r   r    r   r   r   )setZnbunch_iterlen
ValueError	enumeratenodesupdater>   r.   r@   TRICODE_TO_NAMEvalues)r<   ZnodelistZNnotmZnot_nodesetZnbrsZsglZsgl_edges_outsideZdblZdbl_edges_outsideZcensusr9   ZvnbrsZ	dbl_vnbrsZsgl_unbrs_bdyZsgl_unbrs_outZdbl_unbrs_bdyZdbl_unbrs_outr8   ZunbrsZ	neighborsr?   r1   Z	sgl_unbrsZ	dbl_unbrsZtotal_trianglesZtriangles_without_nodesetZtotal_censusr2   )r<   rC   rM   rK   rL   r3   r      sd    +


H
 r   c                    sD   t  tjr@  dkr@t r@t fdd  D s@dS dS )zReturns True if the graph G is a triad, else False.

    Parameters
    ----------
    G : graph
       A NetworkX Graph

    Returns
    -------
    istriad : boolean
       Whether G is a valid triad
    r   c                 3   s   | ]}||f   v V  qd S r7   )edgesrH   r;   r2   r3   r=     r5   zis_triad.<locals>.<genexpr>TF)
isinstancenxZGraphorderZis_directedanyrS   r;   r2   r;   r3   r      s
    r   c                 C   s   t |  d}|S )zReturns a generator of all possible sets of 3 nodes in a DiGraph.

    Parameters
    ----------
    G : digraph
       A NetworkX DiGraph

    Returns
    -------
    triplets : generator of 3-tuples
       Generator of tuples of 3 nodes
    r   )r   rS   )r<   tripletsr2   r2   r3   r	     s    r	   c                 c   s,   t |  d}|D ]}| | V  qdS )zA generator of all possible triads in G.

    Parameters
    ----------
    G : digraph
       A NetworkX DiGraph

    Returns
    -------
    all_triads : generator of DiGraphs
       Generator of triads (order-3 DiGraphs)
    r   N)r   rS   subgraphcopy)r<   r]   tripletr2   r2   r3   r
   %  s    r
   c                 C   s4   t | }tt}|D ]}t|}|| | q|S )a  Returns a list of all triads for each triad type in a directed graph.

    Parameters
    ----------
    G : digraph
       A NetworkX DiGraph

    Returns
    -------
    tri_by_type : dict
       Dictionary with triad types as keys and lists of triads as values.
    )r
   r   listr   append)r<   Zall_triZtri_by_typeZtriadrN   r2   r2   r3   r   8  s    r   c                 C   st  t | stdt|  }|dkr*dS |dkr6dS |dkr|  \}}t|t|kr^dS |d |d krrdS |d |d krd	S |d |d ks|d |d krd
S n|dkrpt|  dD ]\}}}t|t|k r|d |v  r dS  dS t|t|t|kr|d |d |d h|d |d |d h  krZt|  krdn n dS  dS qƐn |dkrTt|  dD ]\}}}}t|t|krt|t|kr dS |d h|d h  krt|	t|krn n dS |d h|d h  kr,t|	t|kr6n n dS |d |d kr dS qn|dkrbdS |dkrpdS dS )aM  Returns the sociological triad type for a triad.

    Parameters
    ----------
    G : digraph
       A NetworkX DiGraph with 3 nodes

    Returns
    -------
    triad_type : str
       A string identifying the triad type

    Notes
    -----
    There can be 6 unique edges in a triad (order-3 DiGraph) (so 2^^6=64 unique
    triads given 3 nodes). These 64 triads each display exactly 1 of 16
    topologies of triads (topologies can be permuted). These topologies are
    identified by the following notation:

    {m}{a}{n}{type} (for example: 111D, 210, 102)

    Here:

    {m}     = number of mutual ties (takes 0, 1, 2, 3); a mutual tie is (0,1)
              AND (1,0)
    {a}     = number of assymmetric ties (takes 0, 1, 2, 3); an assymmetric tie
              is (0,1) BUT NOT (1,0) or vice versa
    {n}     = number of null ties (takes 0, 1, 2, 3); a null tie is NEITHER
              (0,1) NOR (1,0)
    {type}  = a letter (takes U, D, C, T) corresponding to up, down, cyclical
              and transitive. This is only used for topologies that can have
              more than one form (eg: 021D and 021U).

    References
    ----------
    .. [1] Snijders, T. (2012). "Transitivity and triads." University of
        Oxford.
        https://web.archive.org/web/20170830032057/http://www.stats.ox.ac.uk/~snijders/Trans_Triads_ha.pdf
    z"G is not a triad (order-3 DiGraph)r   r   r   r   r   r    r!   r"   r#   r   r%   r$   r'   r&   r   r(   r)   r*   r+   r   r,   r   r-   N)
r   rZ   ZNetworkXAlgorithmErrorrP   rX   rO   r   symmetric_differencerS   intersection)r<   Z	num_edgese1e2Ze3Ze4r2   r2   r3   r   P  sT    )
 
H
66

r   c                 C   s    t t|  d}| |}|S )zReturns a random triad from a directed graph.

    Parameters
    ----------
    G : digraph
       A NetworkX DiGraph

    Returns
    -------
    G2 : subgraph
       A randomly selected triad (order-3 NetworkX DiGraph)
    r   )r   ra   rS   r^   )r<   rS   ZG2r2   r2   r3   r     s    
r   )N)__doc__collectionsr   	itertoolsr   r   randomr   ZnetworkxrZ   Znetworkx.utilsr   __all__ZTRICODESr.   rR   rU   r@   r   r   r	   r
   r   r   r   r2   r2   r2   r3   <module>   s0   Ez



W
