+
    )iD                        R t ^ RIHt ^ RIHt ^ RIHt ^ RIt^ RI	H
t
 ^ RIHt RR.t]P                  ! R	R
7      RR l4       tRR ltRR lt]! R4      ]! R4      ]P                  ! R	R
7      R 4       4       4       tR tR tR tRR ltR# )z%Functions for generating line graphs.)defaultdict)partial)combinationsN)arbitrary_element)not_implemented_for
line_graphinverse_line_graphT)returns_graphc                j    V P                  4       '       d   \        WR7      pV# \        V RVR7      pV# )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   && V/var/www/html/photoedit/myenv/lib/python3.14/site-packages/networkx/generators/line.pyr   r      s6    L 	}}6 H 1LIH    c                H   \         P                  ! ^ WP                  R7      pV P                  4       '       d   \	        V P
                  RR7      MV P
                  pV! 4        F;  pVP                  V4       V! V^,          4       F  pVP                  WE4       K  	  K=  	  V# )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`.

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+aggI[		

9 1.GJJy* / ! Hr   c                  a \         P                  ! ^ W P                  R7      pV P                  4       '       d   \	        V P
                  RR7      MV P
                  pV'       d   ^ M^p\        V 4       UUu/ uF  w  rgWvbK	  	  uppoV3R lp\        4       p	V  F  p
V! V
4       Uu. uF8  p\        \        VR,          SP                  R7      4      VR,          ,           NK:  	  pp\        V4      ^8X  d   VP                  V^ ,          4       \        V4       FD  w  rmT	P                  WV,           R  Uu. uF  p\        \        W3VR7      4      NK  	  up4       KF  	  K  	  VP                  V	4       V# u uppi u upi u upi )	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   Tr   c                 D   < SV ^ ,          ,          SV ^,          ,          3# )     )edge
node_indexs   &r   edge_key_function)_lg_undirected.<locals>.edge_key_function   s     $q'"JtAw$777r   :N   N)key:r+   NNN)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      sO   0 	q,<A 01/@/@d+aggI AE $-Q<0<41!$<0J8 EE LUUV<X<avae89AbEAA<Xu:?JJuQx 
 e$DALL #u9;// &!->?@/ % * UH; 1 Ys   7E9'>E?7 Fdirected
multigraphc                  a
a V P                  4       ^ 8X  d   \        P                  ! ^4      # V P                  4       ^8X  d/   \        V 4      pV^ 3pV^3o\        P                  ! VS3.4      pV# V P                  4       ^8  d.   V P                  4       ^ 8X  d   Rp\        P                  ! V4      h\        P                  ! V 4      ^ 8w  d   Rp\        P                  ! V4      h\        V 4      p\        W4      pV P                   Uu/ uF  qw^ bK  	  upo
V F!  pV F  pS
V;;,          ^,          uu&   K  	  K#  	  \        S
P                  4       4      ^8  d   Rp\        P                  ! V4      h\        ;QJ d    . V
3R lS
 4       F  NK  	  5M! V
3R lS
 4       4      p	\        P                  ! 4       pVP                  V4       VP                  V	4       \        VP                  ^4       FZ  w  po\         ;QJ d    V3R lV 4       F  '       g   K   RM	  RM! V3R lV 4       4      '       g   KH  VP#                  VS4       K\  	  V# u upi )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>`_

zninverse_line_graph() doesn't work on an edgeless graph. Please use this function on each component separately.zA 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.zEG is not a line graph (vertex found in more than two partition cells)c              3   J   <"   T F  pSV,          ^8X  g   K  V3x  K  	  R# 5i)   Nr&   ).0r8   P_counts   & r   	<genexpr>%inverse_line_graph.<locals>.<genexpr>0  s     7GqwqzQdqdGs   ##c              3   ,   <"   T F	  qS9   x  K  	  R # 5iNr&   )rB   a_bitr<   s   & r   rD   rE   5  s     )qezqs   TF)number_of_nodesr   r   r   Graphnumber_of_edgesNetworkXErrornumber_of_selfloops_select_starting_cell_find_partitionr:   maxvaluesr/   add_nodes_fromr   anyr   )r   vr;   Hmsgstarting_cellPr8   pWrC   r<   s   &         @@r   r   r      s   j 	a~~a  	
				!a FFHHq!fX	
			q	 Q%6%6%8A%=E 	 s##	a A%T 	 s##)!,M)AWW%W!tW%GAAJ!OJ   7>>q Us##7G77G77A

AQQQWWa(13)q)333)q)))JJq! ) H &s   
Ic                   Vw  r#W 9  d   \         P                  ! RV R24      hW0V,          9  d   \         P                  ! RV RV R24      h. pW,           F%  pWPV,          9   g   K  VP                  W#V34       K'  	  V# )z.Return list of all triangles containing edge eVertex  not in graphEdge (, ) not in graph)r   rL   append)r   er8   rT   triangle_listr9   s   &&    r   
_trianglesrd   :  s    DAz=9::!}s"QC~>??MTT!9  !+  r   c                2  a V F1  pW P                  4       9  g   K  \        P                  ! RV R24      h	  \        \	        V^4      4       FI  pV^ ,          W^,          ,          9  g   K   \        P                  ! RV^ ,           RV^,           R24      h	  \        \        4      oV F/  pW,           F   pWQ9  g   K  SV;;,          ^,          uu&   K"  	  K1  	  \        ;QJ d    V3R lS 4       F  '       g   K   R# 	  R# ! V3R lS 4       4      # )	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`   c              3   <   <"   T F  pSV,          R9   x  K  	  R# 5i)rA   N)rA      r&   )rB   rT   T_nbrss   & r   rD    _odd_triangle.<locals>.<genexpr>m  s     3FqvayF"Fs   TF)r:   r   rL   listr   r   intrS   )r   Tr8   rb   trT   rh   s   &&    @r   _odd_trianglern   H  s    2 GGI""WQC}#=>>  ,q!$%Q4q1w""VAaD6AaD6#HII & FAzq	Q	   33F33333333F333r   c                H   V P                  4       pV.pVP                  \        \        V^4      4      4       \        V4      pVP	                  4       ^ 8  d   VP                  4       p\        W%,          4      pV^ 8w  g   K?  V.\        W%,          4      ,           pV F9  pV F0  pWX8w  g   K  WV,          9  g   K  Rp	\        P                  ! V	4      h	  K;  	  VP                  \        V4      4       VP                  \        \        V^4      4      4       WG,          pK  V# )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
z>G is not a line graph (partition cell not a complete subgraph))copyremove_edges_fromrj   r   rK   popr2   r   rL   ra   r/   )
r   rW   G_partitionrX   partitioned_verticesr8   deg_unew_cellrT   rV   s
   &&        r   rO   rO   p  s    " &&(K	A!!$|M1'E"FG.

%
%
'!
+ $$&KN#A: sT+.11H!AQ!n%<G  !..s33 "  HHU8_%))$|Ha/H*IJ , Hr   c                \   Vf   \        V P                  4       4      pMTpV^ ,          V P                  4       9  d"   \        P                  ! RV^ ,           R24      hV^,          W^ ,          ,          9  d.   RV^ ,           RV^,           R2p\        P                  ! V4      h\        W4      p\        V4      pV^ 8X  d   TpV# V^8X  di   V^ ,          pVw  rp
\        \        WV
34      4      p\        \        W	V
34      4      pV^8X  d   V^8X  d   TpV# \        W	V
3R7      # \        WV
3R7      # ^ p. pV F0  p\        W4      '       g   K  V^,          pVP                  V4       K2  	  V^8X  d   V^ 8X  d   XpV# V^,
          Tu;8:  d   V8:  d   M M{\        4       pV F  pV F  pVP                  V4       K  	  K  	  V F;  pV F2  pVV8w  g   K  VV V,          9  g   K  Rp\        P                  ! V4      h	  K=  	  \        V4      pV# Rp\        P                  ! V4      h)	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]   zstarting_edge (r_   z) is not in the Graph)starting_edgezCG 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   r2   rN   rn   ra   r.   addr/   )r   rx   rb   rV   e_trianglesrrW   rl   r;   r<   cac_edgesbc_edgessodd_trianglestriangle_nodesr9   r8   rT   s   &&                 r   rN   rN     s<   0 aggi(Q4qwwy ""WQqTF-#@AAQ4q1w#AaD6AaD61FGC""3''Q"KKAAvf e 
a Naz!V,-z!V,-q=1} !P M -Q!fEE(a&AA AQ""Q$$Q'  6a1fM2 1 Ua_1_ UN"A"&&q)  # $'AAv1AaD==  !..s33 ( $ ".1M 	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%4P*ZXr   