+
    )i7                        R t ^ RIHt ^ RIHtHt ^ RIt^ RIH	t	H
t
 . ROtRtRt]! ]4       U Uu/ uF  w  rV ]V^,
          ,          bK  	  upp tR t]	! R4      ]P"                  RR l4       4       t]P"                  R 4       t]	! R4      ]P"                  ! R	R
7      R 4       4       t]	! R4      ]P"                  R 4       4       t]	! R4      ]P"                  R 4       4       tR# u upp i )z*Functions for analyzing triads of a graph.)defaultdict)combinationspermutationsN)not_implemented_forpy_random_statec                V   a  W^3W!^3W^3W1^3W#^3W2^ 33p\        V 3R lV 4       4      # )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.

c              3   L   <"   T F  w  rq2SV,          9   g   K  Vx  K  	  R # 5iN ).0uvxGs   &   X/var/www/html/photoedit/myenv/lib/python3.14/site-packages/networkx/algorithms/triads.py	<genexpr>_tricode.<locals>.<genexpr>~   s     4WQ1qt)qqs   $
$)sum)r   r   r   wcomboss   f&&& r   _tricoder   u   s@     Qi!Q1Iay1*qRjQF4444    
undirectedc           	     
  aa a!a" \        V P                  V4      4      o!Ve%   \        V4      \        S!4      8w  d   \        R4      h\        V 4      oS\        S!4      ,
          p\	        S!4       UUu/ uF  w  r4WCbK	  	  pppV'       d8   V P
                  S!,
          pVP                  V3R l\	        V4       4       4       V  Uu/ uFJ  qDV P                  V,          P                  4       V P                  V,          P                  4       ,          bKL  	  ppV  Uu/ uFJ  qDV P                  V,          P                  4       V P                  V,          P                  4       ,          bKL  	  upo V'       d   X Uu/ uFJ  qDV P                  V,          P                  4       V P                  V,          P                  4       ,          bKL  	  upo"\        V!V"3R lV 4       4      pV^,          p	\        V V!3R lV 4       4      p
V
^,          p\         Uu/ uF  q^ bK  	  ppS! EFJ  pW~,          pS V,          pV'       d	   ^ ;p;p;ppV EF  pVV,          W^,          8:  d   K  VV,          pVV,          VV0,
          pV F}  pVV,          VV,          8  g9   W^,          VV,          u;8  d   VV,          8  g   K=  M KA  WV,          9  g   KP  \        WVV4      pV\        V,          ;;,          ^,          uu&   K  	  VV9   d.   VR;;,          S\        V4      ,
          ^,
          ,          uu&   M,VR;;,          S\        V4      ,
          ^,
          ,          uu&   V'       g   EK#  VS!9  g   EK-  S"V,          pX\        VVS!,
          ,          4      ,          pX\        VV,
          S!,
          4      ,          pS V,          pX\        VVS!,
          ,          4      ,          pX\        VV,
          S!,
          4      ,          pEK  	  V'       g   EK  VR;;,          X	XX^,          ,           ,
          ,          uu&   VR;;,          XXX^,          ,           ,
          ,          uu&   EKM  	  SS^,
          ,          S^,
          ,          ^,          pW"^,
          ,          V^,
          ,          ^,          pVV,
          pV\        VP                  4       4      ,
          VR&   V# u uppi u upi u upi u upi u upi )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.

Examples
--------
>>> G = nx.DiGraph([(1, 2), (2, 3), (3, 1), (3, 4), (4, 1), (4, 2)])
>>> triadic_census = nx.triadic_census(G)
>>> for key, value in triadic_census.items():
...     print(f"{key}: {value}")
003: 0
012: 0
102: 0
021D: 0
021U: 0
021C: 0
111D: 0
111U: 0
030T: 2
030C: 2
201: 0
120D: 0
120U: 0
120C: 0
210: 0
300: 0

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

For undirected graphs, the triadic census can be computed by first converting
the graph into a directed graph using the ``G.to_directed()`` method.
After this conversion, only the triad types 003, 102, 201 and 300 will be
present in the undirected scenario.

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

z3nodelist includes duplicate nodes or nodes not in Gc              3   <   <"   T F  w  rW!S,           3x  K  	  R # 5ir	   r
   )r   inNs   &  r   r   !triadic_census.<locals>.<genexpr>   s     ?(>!U(>s   c              3   X   <"   T F  pSV,           F  q"S9  g   K  ^x  K  	  K!  	  R# 5i   Nr
   )r   r   nbrnodesetsgl_nbrss   &  r   r   r      &     V[HQKKSgCU!!K![   **c              3   X   <"   T F  pSV,           F  q"S9  g   K  ^x  K  	  K!  	  R# 5ir    r
   )r   r   r"   dbl_nbrsr#   s   &  r   r   r      r%   r&   102012003)setnbunch_iterlen
ValueError	enumeratenodesupdatepredkeyssuccr   TRIAD_NAMESr   TRICODE_TO_NAMEvalues)#r   nodelistNnotr   r   mnot_nodesetnbrssglsgl_edges_outsidedbldbl_edges_outsidenamecensusr   vnbrs	dbl_vnbrssgl_unbrs_bdysgl_unbrs_outdbl_unbrs_bdydbl_unbrs_outr   unbrs	neighborsr   code	sgl_unbrs	dbl_unbrstotal_trianglestriangles_without_nodesettotal_censusr   r(   r#   r$   s#   &&                             @@@@r   triadic_censusrR      s   P !--)*GHW =NOOAAs7|D $G,-,$!,A-gg'	?	+(>??
 =>>Aqqvvay~~!&&).."222AD>@AB1166!9>>#affQinn&666BHDOPKqqvvay~~'!&&)..*:::KPV[VV1HV[VV1H #..+$Ag+F.QK	LMMMMMMMMAtqt|GE1a&0IQ4!A$;14!A$#51#5#5!7:J#A!Q/D?401Q61  I~uS^!3a!77uS^!3a!77
 t($QK	Y%@!AAY%6%@!AA$QK	Y%@!AAY%6%@!AA5 8 45M.--STBT2TUUM5M.--STBT2TUUMK R AE{a!e,2O!%!2dQh!?A E"%>>L 3v}}#77F5MMK 	. ?B Q /s!   2S(AS.AS3:AS8S=c                f  a  \        S \        P                  4      '       d   S P                  4       ^8X  d{   \        P                  ! S 4      '       d_   \
        ;QJ d-    V 3R lS P                  4        4       F  '       g   K   RM"	  RM! V 3R lS P                  4        4       4      '       g   R# R# )a0  Returns 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

Examples
--------
>>> G = nx.DiGraph([(1, 2), (2, 3), (3, 1)])
>>> nx.is_triad(G)
True
>>> G.add_edge(0, 1)
>>> nx.is_triad(G)
False
c              3   L   <"   T F  qV3SP                  4       9   x  K  	  R # 5ir	   )edges)r   r   r   s   & r   r   is_triad.<locals>.<genexpr>2  s     >Iq1v*Is   !$TF)
isinstancenxGraphorderis_directedanyr1   )r   s   fr   is_triadr]     sd    . !RXX779>bnnQ//3>AGGI>333>AGGI>>>r   T)returns_graphc              #     "   \        V P                  4       ^4      pV F$  pV P                  V4      P                  4       x  K&  	  R# 5i)a  A 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)

Examples
--------
>>> G = nx.DiGraph([(1, 2), (2, 3), (3, 1), (3, 4), (4, 1), (4, 2)])
>>> for triad in nx.all_triads(G):
...     print(triad.edges)
[(1, 2), (2, 3), (3, 1)]
[(1, 2), (4, 1), (4, 2)]
[(3, 1), (3, 4), (4, 1)]
[(2, 3), (3, 4), (4, 2)]

N)r   r1   subgraphcopy)r   tripletstriplets   &  r   
all_triadsrd   7  s;     4 AGGIq)Hjj!&&(( s   AA	c                    \        V 4      p\        \        4      pV F%  p\        V4      pW$,          P	                  V4       K'  	  V# )aR  Returns a list of all triads for each triad type in a directed graph.
There are exactly 16 different types of triads possible. Suppose 1, 2, 3 are three
nodes, they will be classified as a particular triad type if their connections
are as follows:

- 003: 1, 2, 3
- 012: 1 -> 2, 3
- 102: 1 <-> 2, 3
- 021D: 1 <- 2 -> 3
- 021U: 1 -> 2 <- 3
- 021C: 1 -> 2 -> 3
- 111D: 1 <-> 2 <- 3
- 111U: 1 <-> 2 -> 3
- 030T: 1 -> 2 -> 3, 1 -> 3
- 030C: 1 <- 2 <- 3, 1 -> 3
- 201: 1 <-> 2 <-> 3
- 120D: 1 <- 2 -> 3, 1 <-> 3
- 120U: 1 -> 2 <- 3, 1 <-> 3
- 120C: 1 -> 2 -> 3, 1 <-> 3
- 210: 1 -> 2 <-> 3, 1 <-> 3
- 300: 1 <-> 2 <-> 3, 1 <-> 3

Refer to the :doc:`example gallery </auto_examples/graph/plot_triad_types>`
for visual examples of the triad types.

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

Returns
-------
tri_by_type : dict
   Dictionary with triad types as keys and lists of triads as values.

Examples
--------
>>> G = nx.DiGraph([(1, 2), (1, 3), (2, 3), (3, 1), (5, 6), (5, 4), (6, 7)])
>>> dict = nx.triads_by_type(G)
>>> dict["120C"][0].edges()
OutEdgeView([(1, 2), (1, 3), (2, 3), (3, 1)])
>>> dict["012"][0].edges()
OutEdgeView([(1, 2)])

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
)rd   r   list
triad_typeappend)r   all_tritri_by_typetriadrB   s   &    r   triads_by_typerl   V  sE    n mGd#K%   '  r   c                   \        V 4      '       g   \        P                  ! R4      h\        V P	                  4       4      pV^ 8X  d   R# V^8X  d   R# V^8X  d   V P	                  4       w  r#\        V4      \        V4      8X  d   R# V^ ,          V^ ,          8X  d   R# V^,          V^,          8X  d   R# V^,          V^ ,          8X  g   V^,          V^ ,          8X  d   R# R# V^8X  d   \        V P	                  4       ^4       F  w  r#p\        V4      \        V4      8X  d   V^ ,          V9   d    R#  R	# \        V4      P                  \        V4      4      \        V4      8X  g   Kf  V^ ,          V^ ,          V^ ,          0V^ ,          V^ ,          V^ ,          0u;8X  d"   \        V P                  4       4      8X  d	     R
#   R#  R# 	  R# V^8X  Ed    \        V P	                  4       ^4       F  w  r#rE\        V4      \        V4      8X  g   K!  \        V4      \        V4      8X  d    R# V^ ,          0V^ ,          0u;8X  d,   \        V4      P                  \        V4      4      8X  d     R#  V^,          0V^,          0u;8X  d,   \        V4      P                  \        V4      4      8X  d     R#  V^,          V^ ,          8X  g   K   R# 	  R# V^8X  d   R# V^8X  d   R# R# )a\  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

Examples
--------
>>> G = nx.DiGraph([(1, 2), (2, 3), (3, 1)])
>>> nx.triad_type(G)
'030C'
>>> G.add_edge(1, 3)
>>> nx.triad_type(G)
'120C'

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 asymmetric ties (takes 0, 1, 2, 3); an asymmetric 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)   021D021U021C111U111D030C030T201120D120U120C210300N)
r]   rX   NetworkXAlgorithmErrorr.   rU   r,   r   symmetric_differencer1   intersection)r   	num_edgese1e2e3e4s   &     r   rg   rg     s>   f A;;''(LMMAGGIIA~	a	ar7c"gUbe^Ube^Ube^r!u1~  .	a&qwwy!4JBB2w#b'!a5B;!R--c"g6#b'AqE2a5"Q%(RUBqE2a5,ASS^S! T  5 
a*1779a8NBB2w#b'!r7c"g% qE7r!ugFR)=)=c"g)FF! GqE7r!ugFR)=)=c"g)FF! Ga5BqE>! 9 
a	a 
r   )rR   r]   rd   rl   rg   )@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   r      )r+   r*   r)   rn   ro   rp   rr   rq   rt   rs   ru   rv   rw   rx   ry   rz   r	   )__doc__collectionsr   	itertoolsr   r   networkxrX   networkx.utilsr   r   __all__TRICODESr6   r0   r7   r   _dispatchablerR   r]   rd   rl   rg   )r   rL   s   00r   <module>r      s(  
 1 # 0  ?AJ* <EX;NO;N1k$(++;NO	5 \"S  #Sl  : \"%) & #): \":  #:z \"]  #]K	 Ps   C$