ó
    †~i„D  ã                   ó  • S r SSKJr  SSKJr  SSKJr  SSKrSSK	J
r
  SSKJr  SS	/r\R                  " S
S9SS j5       rSS jrSS jr\" S5      \" S5      \R                  " S
S9S 5       5       5       rS rS rS rSS jrg)z%Functions for generating line graphs.é    )Údefaultdict)Úpartial)ÚcombinationsN)Úarbitrary_element)Únot_implemented_forÚ
line_graphÚinverse_line_graphT)Úreturns_graphc                 ó\   • U R                  5       (       a  [        XS9nU$ [        U SUS9nU$ )ab  Returns the line graph of the graph or digraph `G`.

The line graph of a graph `G` has a node for each edge in `G` and an
edge joining those nodes if the two edges in `G` share a common node. For
directed graphs, nodes are adjacent exactly when the edges they represent
form a directed path of length two.

The nodes of the line graph are 2-tuples of nodes in the original graph (or
3-tuples for multigraphs, with the key of the edge as the third element).

For information about self-loops and more discussion, see the **Notes**
section below.

Parameters
----------
G : graph
    A NetworkX Graph, DiGraph, MultiGraph, or MultiDigraph.
create_using : NetworkX graph constructor, optional (default=nx.Graph)
   Graph type to create. If graph instance, then cleared before populated.

Returns
-------
L : graph
    The line graph of G.

Examples
--------
>>> G = nx.star_graph(3)
>>> L = nx.line_graph(G)
>>> print(sorted(map(sorted, L.edges())))  # makes a 3-clique, K3
[[(0, 1), (0, 2)], [(0, 1), (0, 3)], [(0, 2), (0, 3)]]

Edge attributes from `G` are not copied over as node attributes in `L`, but
attributes can be copied manually:

>>> G = nx.path_graph(4)
>>> G.add_edges_from((u, v, {"tot": u + v}) for u, v in G.edges)
>>> G.edges(data=True)
EdgeDataView([(0, 1, {'tot': 1}), (1, 2, {'tot': 3}), (2, 3, {'tot': 5})])
>>> H = nx.line_graph(G)
>>> H.add_nodes_from((node, G.edges[node]) for node in H)
>>> H.nodes(data=True)
NodeDataView({(0, 1): {'tot': 1}, (2, 3): {'tot': 5}, (1, 2): {'tot': 3}})

Notes
-----
Graph, node, and edge data are not propagated to the new graph. For
undirected graphs, the nodes in G must be sortable, otherwise the
constructed line graph may not be correct.

*Self-loops in undirected graphs*

For an undirected graph `G` without multiple edges, each edge can be
written as a set `\{u, v\}`.  Its line graph `L` has the edges of `G` as
its nodes. If `x` and `y` are two nodes in `L`, then `\{x, y\}` is an edge
in `L` if and only if the intersection of `x` and `y` is nonempty. Thus,
the set of all edges is determined by the set of all pairwise intersections
of edges in `G`.

Trivially, every edge in G would have a nonzero intersection with itself,
and so every node in `L` should have a self-loop. This is not so
interesting, and the original context of line graphs was with simple
graphs, which had no self-loops or multiple edges. The line graph was also
meant to be a simple graph and thus, self-loops in `L` are not part of the
standard definition of a line graph. In a pairwise intersection matrix,
this is analogous to excluding the diagonal entries from the line graph
definition.

Self-loops and multiple edges in `G` add nodes to `L` in a natural way, and
do not require any fundamental changes to the definition. It might be
argued that the self-loops we excluded before should now be included.
However, the self-loops are still "trivial" in some sense and thus, are
usually excluded.

*Self-loops in directed graphs*

For a directed graph `G` without multiple edges, each edge can be written
as a tuple `(u, v)`. Its line graph `L` has the edges of `G` as its
nodes. If `x` and `y` are two nodes in `L`, then `(x, y)` is an edge in `L`
if and only if the tail of `x` matches the head of `y`, for example, if `x
= (a, b)` and `y = (b, c)` for some vertices `a`, `b`, and `c` in `G`.

Due to the directed nature of the edges, it is no longer the case that
every edge in `G` should have a self-loop in `L`. Now, the only time
self-loops arise is if a node in `G` itself has a self-loop.  So such
self-loops are no longer "trivial" but instead, represent essential
features of the topology of `G`. For this reason, the historical
development of line digraphs is such that self-loops are included. When the
graph `G` has multiple edges, once again only superficial changes are
required to the definition.

References
----------
* Harary, Frank, and Norman, Robert Z., "Some properties of line digraphs",
  Rend. Circ. Mat. Palermo, II. Ser. 9 (1960), 161--168.
* Hemminger, R. L.; Beineke, L. W. (1978), "Line graphs and line digraphs",
  in Beineke, L. W.; Wilson, R. J., Selected Topics in Graph Theory,
  Academic Press Inc., pp. 271--305.

)Úcreate_usingF)Ú	selfloopsr   )Úis_directedÚ_lg_directedÚ_lg_undirected)ÚGr   ÚLs      ÚU/home/mande/repo/quber/.venv/lib/python3.13/site-packages/networkx/generators/line.pyr   r      s6   € ðL 	‡}�}‡�Ü˜Ñ6ˆð €Hô ˜1¨¸LÑIˆØ€Hó    c                 ó2  • [         R                  " SXR                  S9nU R                  5       (       a  [	        U R
                  SS9OU R
                  nU" 5        H7  nUR                  U5        U" US   5       H  nUR                  XE5        M     M9     U$ )a
  Returns the line graph L of the (multi)digraph G.

Edges in G appear as nodes in L, represented as tuples of the form (u,v)
or (u,v,key) if G is a multidigraph. A node in L corresponding to the edge
(u,v) is connected to every node corresponding to an edge (v,w).

Parameters
----------
G : digraph
    A directed graph or directed multigraph.
create_using : NetworkX graph constructor, optional
   Graph type to create. If graph instance, then cleared before populated.
   Default is to use the same graph class as `G`.

r   ©ÚdefaultT©Úkeysé   )ÚnxÚempty_graphÚ	__class__Úis_multigraphr   ÚedgesÚadd_nodeÚadd_edge)r   r   r   Ú	get_edgesÚ	from_nodeÚto_nodes         r   r   r   {   sz   € ô  	�Š�q˜,·±Ñ<€Að 01¯©×/@Ñ/@”˜Ÿ™ dÒ+ÀaÇgÁg€Iá–[ˆ	à	�
‰
�9ÔÙ  ¨1¡Ö.ˆGØ�J‰J�yÖ*ó /ñ !ð €Hr   c                 óÒ  ^• [         R                  " SX R                  S9nU R                  5       (       a  [	        U R
                  SS9OU R
                  nU(       a  SOSn[        U 5       VVs0 s H  u  pgXv_M	     snnmU4S jn[        5       n	U  H¯  n
U" U
5       Vs/ s H)  n[        [        USS TR                  S	95      USS -   PM+     nn[        U5      S:X  a  UR                  US   5        [        U5       H>  u  pmU	R                  XÆU-   S  Vs/ s H  n[        [        XÞ4US	95      PM     sn5        M@     M±     UR                  U	5        U$ s  snnf s  snf s  snf )
aÏ  Returns the line graph L of the (multi)graph G.

Edges in G appear as nodes in L, represented as sorted tuples of the form
(u,v), or (u,v,key) if G is a multigraph. A node in L corresponding to
the edge {u,v} is connected to every node corresponding to an edge that
involves u or v.

Parameters
----------
G : graph
    An undirected graph or multigraph.
selfloops : bool
    If `True`, then self-loops are included in the line graph. If `False`,
    they are excluded.
create_using : NetworkX graph constructor, optional (default=nx.Graph)
   Graph type to create. If graph instance, then cleared before populated.

Notes
-----
The standard algorithm for line graphs of undirected graphs does not
produce self-loops.

r   r   Tr   r   c                 ó$   >• TU S      TU S      4$ )Nr   r   © )ÚedgeÚ
node_indexs    €r   Úedge_key_functionÚ)_lg_undirected.<locals>.edge_key_function½   s    ø€ Ø˜$˜q™'Ñ" J¨t°A©wÑ$7Ð7Ð7r   Né   )Úkey)r   r   r   r   r   r   Ú	enumerateÚsetÚtupleÚsortedÚgetÚlenr    ÚupdateÚadd_edges_from)r   r   r   r   r"   ÚshiftÚiÚnr*   r   ÚuÚxÚnodesÚaÚbr)   s                  @r   r   r   ™   sP  ø€ ô0 	�Š�q˜,·±Ñ<€Að 01¯©×/@Ñ/@”˜Ÿ™ dÒ+ÀaÇgÁg€Iö ‰A €Eô $-¨Q¤<Ô0¢<™4˜1�!’$¡<Ò0€Jõ8ô ‹E€EÛˆñ LUÐUVÌ<ÓXÊ<Àa””v˜a  ˜e¨¯©Ñ8Ó9¸A¸a¸b¸EÔAÉ<ˆÐXäˆu‹:˜‹?à�J‰J�u˜Q‘xÔ ô
 ˜eÖ$‰DˆAØ�L‰Lð # u¡9 ;Ñ/óâ/˜ô œ& ! Ð->Ñ?Ö@Ù/ñöó %ñ ð* ×Ñ�UÔØ€Hùó; 1ùò Yùòs   Á/EÂ 0EÄE$ÚdirectedÚ
multigraphc                 ó  ^
^• U R                  5       S:X  a  [        R                  " S5      $ U R                  5       S:X  a.  [        U 5      nUS4nUS4m[        R                  " UT4/5      nU$ U R                  5       S:”  a,  U R                  5       S:X  a  Sn[        R                  " U5      e[        R                  " U 5      S:w  a  Sn[        R                  " U5      e[        U 5      n[        X5      nU R                   Vs0 s H  owS_M     snm
U H  nU H  nT
U==   S-  ss'   M     M     [        T
R                  5       5      S:”  a  Sn[        R                  " U5      e[        U
4S jT
 5       5      n	[        R                  " 5       nUR                  U5        UR                  U	5        [        UR                  S5       H4  u  nm[!        U4S jU 5       5      (       d  M"  UR#                  UT5        M6     U$ s  snf )	aÒ  Returns the inverse line graph of graph G.

If H is a graph, and G is the line graph of H, such that G = L(H).
Then H is the inverse line graph of G.

Not all graphs are line graphs and these do not have an inverse line graph.
In these cases this function raises a NetworkXError.

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

Returns
-------
H : graph
    The inverse line graph of G.

Raises
------
NetworkXNotImplemented
    If G is directed or a multigraph

NetworkXError
    If G is not a line graph

Notes
-----
This is an implementation of the Roussopoulos algorithm[1]_.

If G consists of multiple components, then the algorithm doesn't work.
You should invert every component separately:

>>> K5 = nx.complete_graph(5)
>>> P4 = nx.Graph([("a", "b"), ("b", "c"), ("c", "d")])
>>> G = nx.union(K5, P4)
>>> root_graphs = []
>>> for comp in nx.connected_components(G):
...     root_graphs.append(nx.inverse_line_graph(G.subgraph(comp)))
>>> len(root_graphs)
2

References
----------
.. [1] Roussopoulos, N.D. , "A max {m, n} algorithm for determining the graph H from
   its line graph G", Information Processing Letters 2, (1973), 108--112, ISSN 0020-0190,
   `DOI link <https://doi.org/10.1016/0020-0190(73)90029-X>`_

r   r   zninverse_line_graph() doesn't work on an edgeless graph. Please use this function on each component separately.z‰A line graph as generated by NetworkX has no selfloops, so G has no inverse line graph. Please remove the selfloops from G and try again.r,   zEG is not a line graph (vertex found in more than two partition cells)c              3   ó@   >#   • U  H  nTU   S :X  d  M  U4v •  M     g7f)r   Nr'   )Ú.0r9   ÚP_counts     €r   Ú	<genexpr>Ú%inverse_line_graph.<locals>.<genexpr>0  s   øé € Ð7šG�q w¨q¡z°Q¡‹dˆq�dšGùs   ƒ”
c              3   ó,   >#   • U  H	  oT;   v •  M     g 7f©Nr'   )rB   Úa_bitr=   s     €r   rD   rE   5  s   øé € Ð)¢q˜e˜Žz¢qùs   ƒ)Únumber_of_nodesr   r   r   ÚGraphÚnumber_of_edgesÚNetworkXErrorÚnumber_of_selfloopsÚ_select_starting_cellÚ_find_partitionr;   ÚmaxÚvaluesr0   Úadd_nodes_fromr   Úanyr!   )r   Úvr<   ÚHÚmsgÚstarting_cellÚPr9   ÚpÚWrC   r=   s             @@r   r	   r	   Ú   sÒ  ù€ ðj 	×ÑÓ˜aÓÜ�~Š~˜aÓ Ð Ø	
×	Ñ	Ó	 Ó	!Ü˜aÓ ˆØ�ˆFˆØ�ˆFˆÜ�HŠH�q˜!�f�XÓˆØˆØ	
×	Ñ	Ó	˜qÓ	  Q×%6Ñ%6Ó%8¸AÓ%=ðEð 	ô ×Ò˜sÓ#Ð#ä	×Ò˜aÓ  AÓ%ðTð 	ô ×Ò˜sÓ#Ð#ä)¨!Ó,€MÜ˜Ó)€AàŸWšWÓ%šW˜�!Št™WÑ%€GÛˆÛˆAØ�A‹J˜!‰O�Jó ñ ô ˆ7�>‰>ÓÓ˜qÓ ØUˆÜ×Ò˜sÓ#Ð#ÜÔ7™GÓ7Ó7€AÜ
�Š‹
€AØ×Ñ�QÔØ×Ñ�QÔÜ˜QŸW™W aÖ(‰ˆˆ1ÜÔ)¡qÓ)×)Ó)Ø�J‰J�q˜!Öñ )ð €Hùò &s   ÄHc                 óê   • Uu  p#X ;  a  [         R                  " SU S35      eX0U   ;  a  [         R                  " SU SU S35      e/ nX    H   nXPU   ;   d  M  UR                  X#U45        M"     U$ )z.Return list of all triangles containing edge eúVertex ú not in graphúEdge (ú, ú) not in graph)r   rL   Úappend)r   Úer9   rT   Útriangle_listr:   s         r   Ú
_trianglesrd   :  s…   € à�D€AØƒzÜ×Ò ¨¨¨=Ð9Ó:Ð:Ø�!‘ƒ}Ü×Ò ¨ s¨"¨Q¨C¨~Ð>Ó?Ð?Ø€MØŒTˆØ�!‘�9Ø× Ñ  !¨ Ö+ñ ð Ðr   c                 ó¢  ^• U H0  nX R                  5       ;  d  M  [        R                  " SU S35      e   [        [	        US5      5       H4  nUS   XS      ;  d  M  [        R                  " SUS    SUS    S35      e   [        [        5      mU H"  nX    H  nXQ;  d  M
  TU==   S-  ss'   M     M$     [        U4S	 jT 5       5      $ )
a¤  Test whether T is an odd triangle in G

Parameters
----------
G : NetworkX Graph
T : 3-tuple of vertices forming triangle in G

Returns
-------
True is T is an odd triangle
False otherwise

Raises
------
NetworkXError
    T is not a triangle in G

Notes
-----
An odd triangle is one in which there exists another vertex in G which is
adjacent to either exactly one or exactly all three of the vertices in the
triangle.

r\   r]   r,   r   r   r^   r_   r`   c              3   ó4   >#   • U  H  nTU   S ;   v •  M     g7f))r   é   Nr'   )rB   rT   ÚT_nbrss     €r   rD   Ú _odd_triangle.<locals>.<genexpr>m  s   øé € Ð3ªF qˆv�a‰y˜FÖ"ªFùs   ƒ)r;   r   rL   Úlistr   r   ÚintrS   )r   ÚTr9   rb   ÚtrT   rh   s         @r   Ú_odd_trianglern   H  sÎ   ø€ ó2 ˆØ—G‘G“IÕÜ×"Ò" W¨Q¨C¨}Ð#=Ó>Ð>ñ ô ”,˜q !Ó$Ö%ˆØˆQ‰4�q˜1™‘wÕÜ×"Ò" V¨A¨a©D¨6°°A°a±D°6¸Ð#HÓIÐIñ &ô œÓ€FÛˆØ”ˆAØ�zØ�q“	˜Q‘•	ó ñ ô Ô3©FÓ3Ó3Ð3r   c                 ó<  • U R                  5       nU/nUR                  [        [        US5      5      5        [        U5      nUR	                  5       S:”  aÅ  UR                  5       n[        X%   5      nUS:w  aŒ  U/[        X%   5      -   nU H3  nU H*  nXX:w  d  M
  X‚U   ;  d  M  Sn	[        R                  " U	5      e   M5     UR                  [        U5      5        UR                  [        [        US5      5      5        XG-  nUR	                  5       S:”  a  MÅ  U$ )a9  Find a partition of the vertices of G into cells of complete graphs

Parameters
----------
G : NetworkX Graph
starting_cell : tuple of vertices in G which form a cell

Returns
-------
List of tuples of vertices of G

Raises
------
NetworkXError
    If a cell is not a complete subgraph then G is not a line graph
r,   r   z>G is not a line graph (partition cell not a complete subgraph))ÚcopyÚremove_edges_fromrj   r   rK   Úpopr3   r   rL   ra   r0   )
r   rW   ÚG_partitionrX   Úpartitioned_verticesr9   Údeg_uÚnew_cellrT   rV   s
             r   rO   rO   p  s  € ð" —&‘&“(€KØ	ˆ€AØ×!Ñ!¤$¤|°MÀ1Ó'EÓ"FÔGä Ó.ÐØ
×
%Ñ
%Ó
'¨!Ó
+à ×$Ñ$Ó&ˆÜ�K‘NÓ#ˆØ�A‹:ð �sœT +¡.Ó1Ñ1ˆHÛ�Û!�AØ� Q¸!©nÕ%<ðGð ô !×.Ò.¨sÓ3Ð3ó "ñ ð �H‰H”U˜8“_Ô%Ø×)Ñ)¬$¬|¸HÀaÓ/HÓ*IÔJØ Ñ,Ð ð' ×
%Ñ
%Ó
'¨!Õ
+ð( €Hr   c                 óÜ  • Uc  [        U R                  5       5      nOiUnUS   U R                  5       ;  a  [        R                  " SUS    S35      eUS   XS      ;  a%  SUS    SUS    S3n[        R                  " U5      e[        X5      n[        U5      nUS:X  a  UnU$ US:X  a\  US   nUu  p‰n
[        [        XU
45      5      n[        [        X	U
45      5      nUS:X  a  US:X  a  UnU$ [        X	U
4S9$ [        XU
4S9$ Sn/ nU H+  n[        X5      (       d  M  US-  nUR                  U5        M-     US	:X  a
  US:X  a  WnU$ US-
  Us=::  a  U::  ax  O  Ou[        5       nU H  nU H  nUR                  U5        M     M     U H5  nU H,  nUU:w  d  M  UU U   ;  d  M  S
n[        R                  " U5      e   M7     [        U5      nU$ Sn[        R                  " U5      e)a  Select a cell to initiate _find_partition

Parameters
----------
G : NetworkX Graph
starting_edge: an edge to build the starting cell from

Returns
-------
Tuple of vertices in G

Raises
------
NetworkXError
    If it is determined that G is not a line graph

Notes
-----
If starting edge not specified then pick an arbitrary edge - doesn't
matter which. However, this function may call itself requiring a
specific starting edge. Note that the r, s notation for counting
triangles is the same as in the Roussopoulos paper cited above.
r   r\   r]   r   zstarting_edge (r_   z) is not in the Graph)Ústarting_edger,   zCG is not a line graph (odd triangles do not form complete subgraph)zNG is not a line graph (incorrect number of odd triangles around starting edge))r   r   r;   r   rL   rd   r3   rN   rn   ra   r/   Úaddr0   )r   rx   rb   rV   Úe_trianglesÚrrW   rl   r<   r=   ÚcÚac_edgesÚbc_edgesÚsÚodd_trianglesÚtriangle_nodesr:   r9   rT   s                      r   rN   rN   �  s<  € ð0 ÑÜ˜aŸg™g›iÓ(‰àˆØˆQ‰4�q—w‘w“yÓ Ü×"Ò" W¨Q¨q©T¨F°-Ð#@ÓAÐAØˆQ‰4�q˜1™‘wÓØ# A a¡D 6¨¨A¨a©D¨6Ð1FÐGˆCÜ×"Ò" 3Ó'Ð'Ü˜QÓ"€KÜˆKÓ€AØˆAƒvàˆðf Ððe 
ˆa‹ð ˜‰NˆØ‰ˆˆaä”z !¨ VÓ,Ó-ˆÜ”z !¨ VÓ,Ó-ˆØ�q‹=Ø˜1‹}Ø !�ðP ÐôM -¨QÀ!¸fÑEÐEä(¨¸a¸&ÑAÐAð ˆØˆÛˆAÜ˜Q×"Ó"Ø�Q‘�Ø×$Ñ$ QÖ'ñ ð �‹6�a˜1“fàˆMð2 Ðð1 �‰U�a�_˜1Ž_ä ›UˆNÛ"�Û�AØ"×&Ñ& qÖ)ó ñ #ó $�Û'�AØ˜A•v 1¨A¨a©D¥=ð=ð ô !×.Ò.¨sÓ3Ð3ó (ñ $ô " .Ó1ˆMð Ðð	6ð ô ×"Ò" 3Ó'Ð'r   rG   )FN)Ú__doc__Úcollectionsr   Ú	functoolsr   Ú	itertoolsr   Únetworkxr   Únetworkx.utilsr   Únetworkx.utils.decoratorsr   Ú__all__Ú_dispatchabler   r   r   r	   rd   rn   rO   rN   r'   r   r   Ú<module>r‹      s¥   ðÙ +å #Ý Ý "ã Ý ,Ý 9àÐ-Ð
.€ð ×Ò Ñ%óió &ðiôXô<>ñB �ZÓ Ù�\Ó"Ø×Ò Ñ%ñZó &ó #ó !ðZòzò%4òP*õZXr   