Ë
    D^(h{D  ã                   ó  — d Z ddlmZ ddlmZ ddlmZ ddlZddl	m
Z
 ddlmZ dd	gZ ej                  d
¬«      dd„«       Zdd„Zdd„Z ed«       ed«       ej                  d
¬«      d„ «       «       «       Zd„ Zd„ Zd„ Zdd„Zy)z%Functions for generating line graphs.é    )Údefaultdict)Úpartial)ÚcombinationsN)Úarbitrary_element)Únot_implemented_forÚ
line_graphÚinverse_line_graphT)Úreturns_graphc                 ó`   — | j                  «       rt        | |¬«      }|S t        | d|¬«      }|S )a¦  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/skyplay_api_hub/venv/lib/python3.12/site-packages/networkx/generators/line.pyr   r      s6   € ðL 	‡}�}„Ü˜¨Ô6ˆð €Hô ˜1¨¸LÔIˆØ€Hó    c                 ó.  — t        j                  d|| j                  ¬«      }| j                  «       rt	        | j
                  d¬«      n| j
                  } |«       D ]5  }|j                  |«        ||d   «      D ]  }|j                  ||«       Œ Œ7 |S )a6  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   {   s…   € ô  	�‰�q˜,°·±Ô<€Að 01¯©Ô/@”˜Ÿ™ dÕ+ÀaÇgÁg€Iá“[ò +ˆ	à	�
‰
�9ÔÙ  ¨1¡Ó.ò 	+ˆGØ�J‰J�y 'Õ*ñ	+ð+ð €Hr   c                 óÂ  ‡— t        j                  d|| j                  ¬«      }| j                  «       rt	        | j
                  d¬«      n| j
                  }|rdnd}t        | «      D ��ci c]  \  }}||“Œ
 c}}Šˆfd„}t        «       }	| D ]®  }
 ||
«      D �cg c]+  }t        t        |dd ‰j                  ¬	«      «      |dd z   ‘Œ- }}t        |«      dk(  r|j                  |d   «       t        |«      D ]@  \  }}|	j                  |||z   d D �cg c]  }t        t        ||f|¬	«      «      ‘Œ c}«       ŒB Œ° |j                  |	«       |S c c}}w c c}w c c}w )
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                 ó$   •— ‰| d      ‰| d      fS )Nr   r   © )ÚedgeÚ
node_indexs    €r   ú<lambda>z _lg_undirected.<locals>.<lambda>½   s   ø€  j°°a±Ñ&9¸:ÀdÈ1ÁgÑ;NÐ%O€ r   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ÚnÚedge_key_functionr   ÚuÚxÚnodesÚaÚbr)   s                  @r   r   r   ™   s[  ø€ ô0 	�‰�q˜,°·±Ô<€Að 01¯©Ô/@”˜Ÿ™ dÕ+ÀaÇgÁg€Iñ ‰A €Eô $-¨Q£<×0™4˜1˜a�!�Q‘$Ó0€Jó PÐä‹E€EØò ˆñ LUÐUVË<ÖXÀa””v˜a  ˜e¨¯©Ô8Ó9¸A¸a¸b¸EÓAÐXˆÐXäˆu‹:˜Š?à�J‰J�u˜Q‘xÔ ô
 ˜eÓ$ò 	‰DˆAˆqØ�L‰Lð # 1 u¡9 ;Ð/öàô œ& ! Q Ð->Ô?Õ@òõñ	ðð* ×Ñ�UÔØ€Hùó9 1ùò Yùòs   Á+EÂ0EÄEÚdirectedÚ
multigraphc                 óÚ  ‡
‡— | j                  «       dk(  rt        j                  d«      S | j                  «       dk(  r-t        | «      }|df}|dfŠt        j                  |‰fg«      }|S | j                  «       dkD  r*| j                  «       dk(  rd}t        j                  |«      ‚t        j                  | «      dk7  rd}t        j                  |«      ‚t        | «      }t        | |«      }| j                  D �ci c]  }|d“Œ c}Š
|D ]  }|D ]  }‰
|xx   dz  cc<   Œ Œ t        ‰
j                  «       «      dkD  rd}t        j                  |«      ‚t        ˆ
fd„‰
D «       «      }	t        j                  «       }|j                  |«       |j                  |	«       t        |j                  d«      D ],  \  }Št!        ˆfd„|D «       «      sŒ|j#                  |‰«       Œ. |S c c}w )	af  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   ó6   •K  — | ]  }‰|   d k(  sŒ|f–— Œ y­w)r   Nr'   )Ú.0r9   ÚP_counts     €r   ú	<genexpr>z%inverse_line_graph.<locals>.<genexpr>/  s   øè ø€ Ò7�q w¨q¡z°Q£ˆqŒdÑ7ùs   ƒ‘c              3   ó&   •K  — | ]  }|‰v –— Œ
 y ­w©Nr'   )rB   Úa_bitr=   s     €r   rD   z%inverse_line_graph.<locals>.<genexpr>4  s   øè ø€ Ò)˜eˆu˜ŒzÑ)ùs   ƒ)Ú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Ú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Ö%˜ˆq�!‰tÒ%€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   Ã<
G(c                 óà   — |\  }}|| vrt        j                  d|› d�«      ‚|| |   vrt        j                  d|› d|› d�«      ‚g }| |   D ]  }|| |   v sŒ|j                  |||f«       Œ  |S )z.Return list of all triangles containing edge eúVertex ú not in graphúEdge (ú, ú) not in graph)r   rK   Úappend)r   Úer9   rS   Útriangle_listr:   s         r   Ú
_trianglesrc   9  s–   € à�D€A€qØ��zÜ×Ñ ¨¨¨=Ð9Ó:Ð:Ø��!‘�}Ü×Ñ ¨ s¨"¨Q¨C¨~Ð>Ó?Ð?Ø€MØˆq‰Tò ,ˆØ��!‘Š9Ø× Ñ  ! Q¨ Õ+ð,ð Ðr   c                 ó†  ‡— |D ]-  }|| j                  «       vsŒt        j                  d|› d�«      ‚ t        t	        |d«      «      D ]1  }|d   | |d      vsŒt        j                  d|d   › d|d   › d�«      ‚ t        t        «      Š|D ]  }| |   D ]  }||vsŒ‰|xx   dz  cc<   Œ Œ  t        ˆfd	„‰D «       «      S )
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   ó,   •K  — | ]  }‰|   d v –— Œ y­w))r   é   Nr'   )rB   rS   ÚT_nbrss     €r   rD   z _odd_triangle.<locals>.<genexpr>l  s   øè ø€ Ò3 qˆv�a‰y˜FÔ"Ñ3ùs   ƒ)r;   r   rK   Úlistr   r   ÚintrR   )r   ÚTr9   ra   ÚtrS   rg   s         @r   Ú_odd_trianglerl   G  sì   ø€ ð2 ò ?ˆØ�A—G‘G“IÒÜ×"Ñ" W¨Q¨C¨}Ð#=Ó>Ð>ð?ô ”,˜q !Ó$Ó%ò JˆØˆQ‰4�q˜˜1™‘wÒÜ×"Ñ" V¨A¨a©D¨6°°A°a±D°6¸Ð#HÓIÐIðJô œÓ€FØò ˆØ�1‘ò 	ˆAØ˜ŠzØ�q“	˜Q‘”	ñ	ðô Ó3¨FÔ3Ó3Ð3r   c                 ó,  — | j                  «       }|g}|j                  t        t        |d«      «      «       t        |«      }|j	                  «       dkD  r¾|j                  «       }t        ||   «      }|dk7  r‡|gt        ||   «      z   }|D ]-  }|D ]&  }||k7  sŒ	|||   vsŒd}	t        j                  |	«      ‚ Œ/ |j                  t        |«      «       |j                  t        t        |d«      «      «       ||z  }|j	                  «       dkD  rŒ¾|S )ai  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_fromrh   r   rJ   Úpopr2   r   rK   r`   r/   )
r   rV   ÚG_partitionrW   Úpartitioned_verticesr9   Údeg_uÚnew_cellrS   rU   s
             r   rN   rN   o  s%  € ð" —&‘&“(€KØ	ˆ€AØ×!Ñ!¤$¤|°MÀ1Ó'EÓ"FÔGä Ó.ÐØ
×
%Ñ
%Ó
'¨!Ò
+à ×$Ñ$Ó&ˆÜ�K ‘NÓ#ˆØ�AŠ:ð �sœT +¨a¡.Ó1Ñ1ˆHØò 4�Ø!ò 4�AØ˜Q› Q¨k¸!©nÒ%<ðGð ô !×.Ñ.¨sÓ3Ð3ñ4ð4ð �H‰H”U˜8“_Ô%Ø×)Ñ)¬$¬|¸HÀaÓ/HÓ*IÔJØ  HÑ,Ð ð' ×
%Ñ
%Ó
'¨!Ó
+ð( €Hr   c                 ó®  — |€t        | j                  «       «      }nd|}|d   | j                  «       vrt        j                  d|d   › d�«      ‚|d   | |d      vr$d|d   › d|d   › d�}t        j                  |«      ‚t        | |«      }t        |«      }|dk(  r|}|S |dk(  re|d   }|\  }}	}
t        t        | ||
f«      «      }t        t        | |	|
f«      «      }|dk(  r|dk(  r|}|S t        | |	|
f¬«      S t        | ||
f¬«      S d}g }|D ]%  }t        | |«      sŒ|dz  }|j                  |«       Œ' |d	k(  r	|dk(  r}|S |dz
  |cxk  r|k  rkn nht        «       }|D ]  }|D ]  }|j                  |«       Œ Œ |D ]-  }|D ]&  }||k7  sŒ	|| |   vsŒd
}t        j                  |«      ‚ Œ/ t        |«      }|S d}t        j                  |«      ‚)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   rK   rc   r2   rM   rl   r`   r.   Úaddr/   )r   rv   ra   rU   Úe_trianglesÚrrV   rj   r<   r=   ÚcÚac_edgesÚbc_edgesÚsÚodd_trianglesÚtriangle_nodesr:   r9   rS   s                      r   rM   rM   œ  sb  € ð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ˆØ‰ˆˆ1ˆaä”z ! a¨ VÓ,Ó-ˆÜ”z ! a¨ VÓ,Ó-ˆØ�qŠ=Ø˜1Š}Ø !�ðP ÐôM -¨Q¸qÀ!¸fÔEÐEä(¨¸1¸a¸&ÔAÐAð ˆØˆØò 	(ˆAÜ˜Q Õ"Ø�Q‘�Ø×$Ñ$ QÕ'ð	(ð �Š6�a˜1’fàˆMð2 Ðð1 �‰U�aŒ_˜1�_ä ›UˆNØ"ò *�Øò *�AØ"×&Ñ& qÕ)ñ*ð*ð $ò 4�Ø'ò 4�AØ˜A“v 1¨A¨a©D¢=ð=ð ô !×.Ñ.¨sÓ3Ð3ñ4ð4ô " .Ó1ˆMð Ðð	6ð ô ×"Ñ" 3Ó'Ð'r   rF   )FN)Ú__doc__Úcollectionsr   Ú	functoolsr   Ú	itertoolsr   Únetworkxr   Únetworkx.utilsr   Únetworkx.utils.decoratorsr   Ú__all__Ú_dispatchabler   r   r   r	   rc   rl   rN   rM   r'   r   r   ú<module>r‰      s©   ðÙ +å #Ý Ý "ã Ý ,Ý 9àÐ-Ð
.€ð €×Ñ Ô%òió &ðióXó<=ñ@ �ZÓ Ù�\Ó"Ø€×Ñ Ô%ñZó &ó #ó !ðZòzò%4òP*ôZXr   