
    hC                        S r SSKrSSKJr  / SQrS r\" S5      S)S j5       rS*S
 jrS+S jr	 S,S jr
\" S5                S-S j5       r\r\" S5       S.S j5       r\" S5       S.S j5       r S/S jrS rS rS0S jrS1S jrS1S jrS*S jrS2S jrS3S jr\" S5            S4SS.S jj5       r\" S5       S5S S!S"S!SSSSSSSSSS#.S$ jj5       rS6S% jrS6S& jrSS	SS'.S( jrg)7a  
******
Layout
******

Node positioning algorithms for graph drawing.

For `random_layout()` the possible resulting shape
is a square of side [0, scale] (default: [0, 1])
Changing `center` shifts the layout by that amount.

For the other layout routines, the extent is
[center - scale, center + scale] (default: [-1, 1]).

Warning: Most layout routines have only been tested in 2-dimensions.

    N)np_random_state)bipartite_layoutcircular_layoutforceatlas2_layoutkamada_kawai_layoutrandom_layoutrescale_layoutrescale_layout_dictshell_layoutspring_layoutspectral_layoutplanar_layoutfruchterman_reingold_layoutspiral_layoutmultipartite_layout
bfs_layout
arf_layoutc                 "   SS K n[        U [        R                  5      (       d(  [        R                  " 5       nUR	                  U 5        Un Uc  UR                  U5      nOUR                  U5      n[        U5      U:w  a  Sn[        U5      eX4$ )Nr   z;length of center coordinates must match dimension of layout)	numpy
isinstancenxGraphadd_nodes_fromzerosasarraylen
ValueError)Gcenterdimnpempty_graphmsgs         I/var/www/html/env/lib/python3.13/site-packages/networkx/drawing/layout.py_process_paramsr%   *   sw    a""hhj""1%~#F#
6{cKo9          c                     SSK n[        XU5      u  pUR                  [        U 5      U5      U-   nUR	                  UR
                  5      n[        [        X5      5      nU$ )a  Position nodes uniformly at random in the unit square.

For every node, a position is generated by choosing each of dim
coordinates uniformly at random on the interval [0.0, 1.0).

NumPy (http://scipy.org) is required for this function.

Parameters
----------
G : NetworkX graph or list of nodes
    A position will be assigned to every node in G.

center : array-like or None
    Coordinate pair around which to center the layout.

dim : int
    Dimension of layout.

seed : int, RandomState instance or None  optional (default=None)
    Set the random state for deterministic node layouts.
    If int, `seed` is the seed used by the random number generator,
    if numpy.random.RandomState instance, `seed` is the random
    number generator,
    if None, the random number generator is the RandomState instance used
    by numpy.random.

Returns
-------
pos : dict
    A dictionary of positions keyed by node

Examples
--------
>>> G = nx.lollipop_graph(4, 3)
>>> pos = nx.random_layout(G)

r   N)r   r%   randr   astypefloat32dictzip)r   r   r    seedr!   poss         r$   r   r   ?   sT    N 3/IA
))CFC
 6
)C
**RZZ
 C
s1{
CJr&      c           	      f   SSK nUS:  a  [        S5      e[        XU5      u  p[        SUS-
  5      n[	        U 5      S:X  a  0 nU$ [	        U 5      S:X  a#  [
        R                  R                  U 5      U0nU$ UR                  SS[	        U 5      S-   5      SS S-  UR                  -  nUR                  UR                  5      nUR                  UR                  U5      UR                  U5      UR                  [	        U 5      U45      /5      n[!        XaS9U-   n[#        [%        X5      5      nU$ )a  Position nodes on a circle.

Parameters
----------
G : NetworkX graph or list of nodes
    A position will be assigned to every node in G.

scale : number (default: 1)
    Scale factor for positions.

center : array-like or None
    Coordinate pair around which to center the layout.

dim : int
    Dimension of layout.
    If dim>2, the remaining dimensions are set to zero
    in the returned positions.
    If dim<2, a ValueError is raised.

Returns
-------
pos : dict
    A dictionary of positions keyed by node

Raises
------
ValueError
    If dim < 2

Examples
--------
>>> G = nx.path_graph(4)
>>> pos = nx.circular_layout(G)

Notes
-----
This algorithm currently only works in two dimensions and does not
try to minimize edge crossings.

r   Nr(   zcannot handle dimensions < 2r1   scale)r   r   r%   maxr   r   utilsarbitrary_elementlinspacepir+   r,   column_stackcossinr   r	   r-   r.   )r   r5   r   r    r!   paddimsr0   thetas           r$   r   r   p   s   T 
Qw7883/IA!cAgG
1v{ J 
Q1xx))!,f5 J Aq#a&1*-cr2Q6>RZZ(ooVVE]BFF5M288SVW4E+FG
 S.73q;Jr&   c           	         SSK nUS:w  a  [        S5      e[        XU5      u  p[        U 5      S:X  a  0 $ [        U 5      S:X  a!  [        R
                  R                  U 5      U0$ Uc  [        U 5      /nU[        U5      -  n[        US   5      S:X  a  SnOUnUc  UR                  [        U5      -  nUn	0 n
U H  nUR                  SSUR                  -  [        U5      SUR                  S9U	-   nXR                  UR                  U5      UR                  U5      /5      -  U-   nU
R                  [        X5      5        X-  nX-  n	M     U
$ )	a  Position nodes in concentric circles.

Parameters
----------
G : NetworkX graph or list of nodes
    A position will be assigned to every node in G.

nlist : list of lists
   List of node lists for each shell.

rotate : angle in radians (default=pi/len(nlist))
   Angle by which to rotate the starting position of each shell
   relative to the starting position of the previous shell.
   To recreate behavior before v2.5 use rotate=0.

scale : number (default: 1)
    Scale factor for positions.

center : array-like or None
    Coordinate pair around which to center the layout.

dim : int
    Dimension of layout, currently only dim=2 is supported.
    Other dimension values result in a ValueError.

Returns
-------
pos : dict
    A dictionary of positions keyed by node

Raises
------
ValueError
    If dim != 2

Examples
--------
>>> G = nx.path_graph(4)
>>> shells = [[0], [1, 2, 3]]
>>> pos = nx.shell_layout(G, shells)

Notes
-----
This algorithm currently only works in two dimensions and does not
try to minimize edge crossings.

r   Nr(   can only handle 2 dimensionsr1           F)endpointdtype)r   r   r%   r   r   r7   r8   listr:   r9   r,   r;   r<   r=   updater.   )r   nlistrotater5   r   r    r!   radius_bumpradiusfirst_thetanposnodesr?   r0   s                 r$   r   r      sL   ` 
ax7883/IA
1v{	
1v{**1-v66}a	#e*$K
58} ~U#KD KK1ruu9c%j5

KS 	 urvve}'EFFOCO$  Kr&   verticalc                    SSK nUS;  a  Sn[        U5      e[        XSS9u  p[        U 5      S:X  a  0 $ SnXX-  n	U	S-  US-  4n
[        R                  U5      nU  Vs/ s H  oU;  d  M
  UPM     nn[        U5      U-   nUR                  S[        U5      5      nUR                  U	[        U5      5      nUR                  SU[        U5      5      nUR                  SU[        U5      5      nUR                  UU/5      U
-
  nUR                  UU/5      U
-
  nUR                  UU/5      n[        UUS9U-   nUS	:X  a  USS2SSS
24   n[	        [        UU5      5      nU$ s  snf )a  Position nodes in two straight lines.

Parameters
----------
G : NetworkX graph or list of nodes
    A position will be assigned to every node in G.

nodes : list or container
    Nodes in one node set of the bipartite graph.
    This set will be placed on left or top.

align : string (default='vertical')
    The alignment of nodes. Vertical or horizontal.

scale : number (default: 1)
    Scale factor for positions.

center : array-like or None
    Coordinate pair around which to center the layout.

aspect_ratio : number (default=4/3):
    The ratio of the width to the height of the layout.

Returns
-------
pos : dict
    A dictionary of positions keyed by node.

Examples
--------
>>> G = nx.bipartite.gnmk_random_graph(3, 5, 10, seed=123)
>>> top = nx.bipartite.sets(G)[0]
>>> pos = nx.bipartite_layout(G, top)

Notes
-----
This algorithm currently only works in two dimensions and does not
try to minimize edge crossings.

r   NrN   
horizontal,align must be either vertical or horizontal.r(   r   r    r1   r4   rQ   r3   )r   r   r%   r   r-   fromkeysrE   repeatr9   r;   concatenater	   r.   )r   rM   alignr5   r   aspect_ratior!   r#   heightwidthoffsettopvbottomleft_xsright_xsleft_ysright_ystop_pos
bottom_posr0   s                        r$   r   r     sl   X ..<oa8IA
1v{	F!Eai!$F
--
C+AslaF+IEii3s8$GyyF,Hkk!VSX.G{{1fc&k2Hoow01F:G(H!56?J
..':.
/C
E
*V
3C!TrT'l
s5#
CJ! ,s   	E$+E$
   c                    SSK n[        XU	5      u  pUbq  Uc  [        S5      eU H  nX;  d  M
  [        S5      e   [        U 5       VVs0 s H  u  pX_M	     nnnUR	                  U Vs/ s H  oU;   d  M
  X   PM     sn5      nUb~  [        S UR                  5        5       5      nUS:X  a  SnU
R                  [        U 5      U	5      U-  U-   n[        U 5       H%  u  nnUU;   d  M  UR	                  UU   5      UU'   M'     OSnSn[        U 5      S:X  a  0 $ [        U 5      S:X  a/  [        R                  R                  U R                  5       5      U0$  [        U 5      S:  a  [        e[        R                  " XSS9nUc%  Ub"  UR                  u  nnXR                  U5      -  n[!        UUUX4XYU
5      nUc  Ub  ['        X'S
9U-   n[)        [+        X5      5      nU$ s  snnf s  snf ! [         aO    [        R"                  " XS	9nUc%  Ub"  UR                  u  nnXR                  U5      -  n[%        UUUX4XYU
5      n Nf = f)a  Position nodes using Fruchterman-Reingold force-directed algorithm.

The algorithm simulates a force-directed representation of the network
treating edges as springs holding nodes close, while treating nodes
as repelling objects, sometimes called an anti-gravity force.
Simulation continues until the positions are close to an equilibrium.

There are some hard-coded values: minimal distance between
nodes (0.01) and "temperature" of 0.1 to ensure nodes don't fly away.
During the simulation, `k` helps determine the distance between nodes,
though `scale` and `center` determine the size and place after
rescaling occurs at the end of the simulation.

Fixing some nodes doesn't allow them to move in the simulation.
It also turns off the rescaling feature at the simulation's end.
In addition, setting `scale` to `None` turns off rescaling.

Parameters
----------
G : NetworkX graph or list of nodes
    A position will be assigned to every node in G.

k : float (default=None)
    Optimal distance between nodes.  If None the distance is set to
    1/sqrt(n) where n is the number of nodes.  Increase this value
    to move nodes farther apart.

pos : dict or None  optional (default=None)
    Initial positions for nodes as a dictionary with node as keys
    and values as a coordinate list or tuple.  If None, then use
    random initial positions.

fixed : list or None  optional (default=None)
    Nodes to keep fixed at initial position.
    Nodes not in ``G.nodes`` are ignored.
    ValueError raised if `fixed` specified and `pos` not.

iterations : int  optional (default=50)
    Maximum number of iterations taken

threshold: float optional (default = 1e-4)
    Threshold for relative error in node position changes.
    The iteration stops if the error is below this threshold.

weight : string or None   optional (default='weight')
    The edge attribute that holds the numerical value used for
    the edge weight.  Larger means a stronger attractive force.
    If None, then all edge weights are 1.

scale : number or None (default: 1)
    Scale factor for positions. Not used unless `fixed is None`.
    If scale is None, no rescaling is performed.

center : array-like or None
    Coordinate pair around which to center the layout.
    Not used unless `fixed is None`.

dim : int
    Dimension of layout.

seed : int, RandomState instance or None  optional (default=None)
    Used only for the initial positions in the algorithm.
    Set the random state for deterministic node layouts.
    If int, `seed` is the seed used by the random number generator,
    if numpy.random.RandomState instance, `seed` is the random
    number generator,
    if None, the random number generator is the RandomState instance used
    by numpy.random.

Returns
-------
pos : dict
    A dictionary of positions keyed by node

Examples
--------
>>> G = nx.path_graph(4)
>>> pos = nx.spring_layout(G)

# The same using longer but equivalent function name
>>> pos = nx.fruchterman_reingold_layout(G)
r   Nz'nodes are fixed without positions givenc              3   6   #    U  H  o  H  o"v   M     M     g 7fN ).0pos_tupcoords      r$   	<genexpr> spring_layout.<locals>.<genexpr>  s     NLgUuguLs   r1     fweightrD   rr   r4   )r   r%   r   	enumerater   r6   valuesr*   r   r   r7   r8   rM   to_scipy_sparse_arrayshapesqrt_sparse_fruchterman_reingoldto_numpy_array_fruchterman_reingoldr	   r-   r.   )r   kr0   fixed
iterations	thresholdrr   r5   r   r    r/   r!   nodeinfixeddom_sizepos_arrnAnnodes_s                        r$   r   r   ]  sC   @ 3/IA;FGGD !JKK  *316ga$'6

UMUTfnLFLUMN
NCJJLNNq=H))CFC(83f<aLDAqCxZZA/
 ! 
1v{	
1v{**17795v>>
q6C<$$QSA9*IFA776?*A*q'5id
 }*S.7
s1{
CJ] 7MB  
a/9*IFA776?*A#q'5id

s&   G&+	G,8G,A"G1 1AI
	I
   c                    SS K n U R                  u  pUc*  UR                  UR                  X5      U R                  S9nOUR                  U R                  5      nUc  UR                  SU	-  5      n[        [        UR                  S   5      [        UR                  S   5      -
  [        UR                  S   5      [        UR                  S   5      -
  5      S-  nXS-   -  nUR                  UR                  S   UR                  S   UR                  S   4U R                  S9n[        U5       H  nUS S 2UR                  S S 24   X(R                  S S 2S S 24   -
  nUR                   R#                  USS9nUR%                  US	S US
9  UR'                  SXU-  US-  -  U U-  U-  -
  5      nUR                   R#                  USS9nUR)                  US	:  SU5      nUR'                  SUUU-  5      nUb  SUU'   UU-  nX-  nUR                   R#                  U5      U	-  U:  d  M    U$    U$ ! [         a  nSn[        R                  " U5      UeS nAff = f)Nr   9fruchterman_reingold() takes an adjacency matrix as inputrD         ?r1   皙?r3   axis{Gz?)outz
ijk,ij->ikr(   zij,i->ijrB   )r   rw   AttributeErrorr   NetworkXErrorr   r*   rD   r+   rx   r6   Tminr   rangenewaxislinalgnormclipeinsumwhere)r   r|   r0   r}   r~   r   r    r/   r!   r   r   errr#   tdtdelta	iterationdistancedisplacementlength	delta_poss                        r$   r{   r{     sD    -GG	
 {jj6/qwwj? jj! 	yGGC&L!
 	CaMCaM)3suuQx=3suuQx=+HICOA 
1n	BHHciilCIIaL#))A,?qwwHOE :&	Arzz1$%JJ1,<(==99>>%b>1
$(3yy%a%(A+"5Hq8H"H
 26&4-f5IIj,F
C	"Iey	IINN9%.);J/ '. Jc  -Is#,-s   H7 7
IIIc           	         SS K nSS Kn	 U R                  u  p U R                  5       n Uc*  UR                  UR                  X5      U R                  S9nOUR                  U R                  5      nUc  / nUc  UR                  SU
-  5      n[        [        UR                  S   5      [!        UR                  S   5      -
  [        UR                  S   5      [!        UR                  S   5      -
  5      S-  nXS-   -  nUR#                  Xj45      n[%        U5       GHA  nUS-  n[%        U R                  S   5       H  nUU;   a  M  UU   U-
  R                  nUR                  US-  R'                  SS95      nUR)                  US	:  S	U5      nU R+                  U5      R-                  5       nUS S 2U4==   UX-  US-  -  UU-  U-  -
  -  R'                  SS9-  ss'   M     UR                  US-  R'                  SS95      nUR)                  US	:  SU5      nUU-  U-  R                  nUU-  nX-  nUR.                  R1                  U5      U
-  U:  d  GMA    U$    U$ ! [         a  nSn[        R
                  " U5      UeS nAff = f! [         a-    U	R                  R                  U 5      R                  5       n  GNf = f)
Nr   r   r   r   r1   r   r(   r   r   )r   scipyrw   r   r   r   tolilsparse	coo_arrayr   r*   rD   r+   rx   r6   r   r   r   r   sumr   
getrowviewtoarrayr   r   )r   r|   r0   r}   r~   r   r    r/   r!   spr   r   r   r#   r   r   r   r   r   r   r   Air   r   s                           r$   ry   ry   9  s    -GG	
-GGI {jj6/qwwj? jj! } 	yGGC&L! 	CaMCaM)3suuQx=3suuQx=+HICOA 
1n	B88SM*L:&	qwwqz"AEzVc\$$Ewwq~~1~56Hxx4x@Ha((*BA1,rH}q/@@Acqck #  ,/..A.67&4-f5!A%.11	y	IINN9%.);J7 '6 Ju  -Is#,-  -YY  #**,-s(   I& J &
J0J		J3KKc                    SSK n[        XU5      u  p[        U 5      nUS:X  a  0 $ Uc  [        [        R
                  " XS95      nSUR                  X45      -  n	[        U 5       H4  u  pX;  a  M  X   n[        U 5       H  u  pX;  a  M  X   X   U'   M     M6     UcN  US:  a
  [        XS9nO>US:X  a
  [        XS9nO.[        [        XR                  SS[        U 5      5      5      5      nUR                  U  Vs/ s H  oU   PM	     sn5      n[        U	UU5      n[        X$S	9U-   n[        [        X5      5      $ s  snf )
ak  Position nodes using Kamada-Kawai path-length cost-function.

Parameters
----------
G : NetworkX graph or list of nodes
    A position will be assigned to every node in G.

dist : dict (default=None)
    A two-level dictionary of optimal distances between nodes,
    indexed by source and destination node.
    If None, the distance is computed using shortest_path_length().

pos : dict or None  optional (default=None)
    Initial positions for nodes as a dictionary with node as keys
    and values as a coordinate list or tuple.  If None, then use
    circular_layout() for dim >= 2 and a linear layout for dim == 1.

weight : string or None   optional (default='weight')
    The edge attribute that holds the numerical value used for
    the edge weight.  If None, then all edge weights are 1.

scale : number (default: 1)
    Scale factor for positions.

center : array-like or None
    Coordinate pair around which to center the layout.

dim : int
    Dimension of layout.

Returns
-------
pos : dict
    A dictionary of positions keyed by node

Examples
--------
>>> G = nx.path_graph(4)
>>> pos = nx.kamada_kawai_layout(G)
r   Nrs   g    .Ar'   )r    r(   r1   r4   )r   r%   r   r-   r   shortest_path_lengthonesrt   r   r   r.   r9   array_kamada_kawai_solver	   )r   distr0   rr   r5   r   r    r!   nNodesdist_mtxrownrrdistcolncr   r   s                    r$   r   r     s9   V 3/IAVF{	|B++A=>RWWf-..HQ<> |GC!&HM# $	   {!8+CAX!!-Cs1kk!QA789Chh*1A*+G
h
5C

*V
3CA +s   >E c                     SS K nSS KnSnUSXR                  U R                  S   5      S-  -   -  XR4nUR                  R                  [        UR                  5       SUSS9nUR                  R                  SU45      $ )Nr   MbP?r1   zL-BFGS-BT)methodargsjacr3   )
r   r   eyerw   optimizeminimize_kamada_kawai_costfnravelxreshape)r   r   r    r!   r   meanwtcostargs	optresults           r$   r   r     s    
 FAFF8>>!+<$=$DDEvSH$$ % I ;;Cy))r&   c           	      ^   UR                   S   nU R                  XT45      nUS S 2UR                  S S 24   XaR                  S S 2S S 24   -
  nUR                  R	                  USS9nUR                  SUSXR                  U5      S-  -   -  5      n	X-  S-
  n
SXR                  U5      '   SUR                  U
S	-  5      -  nUR                  S
X*U	5      UR                  SX*U	5      -
  nUR                  USS9nUSU-  UR                  US	-  5      -  -  nXU-  -  nXR                  5       4$ )Nr   r3   r   zijk,ij->ijkr1   r   r         ?r(   zij,ij,ijk->ikzij,ij,ijk->jk)
rw   r   r   r   r   r   r   diag_indicesr   r   )pos_vecr!   invdist
meanweightr    r   r   r   nodesep	directionr[   costgradsumposs                 r$   r   r     s6   ]]1Foovm,GArzz1$%

Aq0@(AAEiinnUn,G		-Wvvf~PT?T5T0UVI$F&'F??6"#	""D99_gyABII)E D
 VVG!V$FC*rvvfai000DD**,r&   c                 
   SSK n[        XU5      u  p[        U 5      S::  a  [        U 5      S:X  a  UR                  / 5      nOV[        U 5      S:X  a  UR                  U/5      nO4UR                  UR	                  U5      UR                  U5      S-  /5      n[        [        X5      5      $  [        U 5      S:  a  [        e[        R                  " XSS9nU R                  5       (       a  XuR                  U5      -   n[        Xt5      n[#        XbS
9U-   n[        [        X5      5      nU$ ! [        [        4 aE    [        R                  " XS	9nU R                  5       (       a  XwR                  -  n[!        Xt5      n Nvf = f)a  Position nodes using the eigenvectors of the graph Laplacian.

Using the unnormalized Laplacian, the layout shows possible clusters of
nodes which are an approximation of the ratio cut. If dim is the number of
dimensions then the positions are the entries of the dim eigenvectors
corresponding to the ascending eigenvalues starting from the second one.

Parameters
----------
G : NetworkX graph or list of nodes
    A position will be assigned to every node in G.

weight : string or None   optional (default='weight')
    The edge attribute that holds the numerical value used for
    the edge weight.  If None, then all edge weights are 1.

scale : number (default: 1)
    Scale factor for positions.

center : array-like or None
    Coordinate pair around which to center the layout.

dim : int
    Dimension of layout.

Returns
-------
pos : dict
    A dictionary of positions keyed by node

Examples
--------
>>> G = nx.path_graph(4)
>>> pos = nx.spectral_layout(G)

Notes
-----
Directed graphs will be considered as undirected graphs when
positioning the nodes.

For larger graphs (>500 nodes) this will use the SciPy sparse
eigenvalue solver (ARPACK).
r   Nr(   r1          @ro   drq   rs   r4   )r   r%   r   r   r   r-   r.   r   r   rv   is_directed	transpose_sparse_spectralImportErrorrz   r   	_spectralr	   )r   rr   r5   r   r    r!   r0   r   s           r$   r   r     sC   Z 3/IA
1v{q6Q;((2,CVq[((F8$C((BHHSM288F+;c+ABCCCK   q6C<$$QSA==??LLO#Aq& 
*V
3C
s1{
CJ $  a/==??HA s   .AD- -AFFc                 r   SS K n U R                  u  p4UR                  X0R                  S9UR                  U SS9-  nXp-
  nUR                  R                  U5      u  pUR                  U	5      SUS-    nUR                  U
S S 2U4   5      $ ! [         a  nSn[        R                  " U5      UeS nAff = f)Nr   z-spectral() takes an adjacency matrix as inputr   r1   r   )r   rw   r   r   r   identityrD   r   r   eigargsortreal)r   r    r!   r   r   r   r#   DLeigenvalueseigenvectorsindexs               r$   r   r   M  s     -GG	 	F''*RVVAAV->>A	A "		a 0KJJ{#Aa0E77<5)**  -=s#,-s   B 
B6B11B6c                    SS K nSS Kn U R                  u  pEUR                  R                  UR                  R                  U R                  SS9SXD5      5      nX-
  n	US-   n
[        SU
-  S-   [        UR                  U5      5      5      nUR                  R                  R                  XSUS9u  pUR                  U5      SU
 nUR!                  US S 2U4   5      $ ! [         a  nSn[        R
                  " U5      UeS nAff = f)Nr   z4sparse_spectral() takes an adjacency matrix as inputr1   r   r(   SM)whichncv)r   r   rw   r   r   r   r   	csr_arrayspdiagsr   r6   intrx   r   eigshr   r   )r   r    r!   r   r   r   r   r#   r   r   r|   r   r   r   r   s                  r$   r   r   b  s     -GG	 			BII--aeeemQOPA	AaA
a!eaiRWWV_-
.C "		 0 0 6 6q4S 6 QKJJ{#Aa(E77<5)**  -Ds#,-s   C! !
D	+DD	c                 "   SSK nUS:w  a  [        S5      e[        XU5      u  p[        U 5      S:X  a  0 $ [	        U [
        R                  5      (       a  U nO5[
        R                  " U 5      u  peU(       d  [
        R                  " S5      e[
        R                  " U5      n[        U5      nUR                  U V	s/ s H  oU	   PM	     sn	5      nUR                  UR                  5      n[        XqS9U-   n[        [!        X5      5      $ s  sn	f )ai  Position nodes without edge intersections.

Parameters
----------
G : NetworkX graph or list of nodes
    A position will be assigned to every node in G. If G is of type
    nx.PlanarEmbedding, the positions are selected accordingly.

scale : number (default: 1)
    Scale factor for positions.

center : array-like or None
    Coordinate pair around which to center the layout.

dim : int
    Dimension of layout.

Returns
-------
pos : dict
    A dictionary of positions keyed by node

Raises
------
NetworkXException
    If G is not planar

Examples
--------
>>> G = nx.path_graph(4)
>>> pos = nx.planar_layout(G)
r   Nr(   rA   zG is not planar.r4   )r   r   r%   r   r   r   PlanarEmbeddingcheck_planarityNetworkXExceptioncombinatorial_embedding_to_posrE   vstackr+   float64r	   r-   r.   )
r   r5   r   r    r!   	embedding	is_planarr0   	node_listr   s
             r$   r   r   }  s    B 
ax7883/IA
1v{	!R''((	!11!4	&&'9::

+
+I
6CYI
))Y/YVY/
0C
**RZZ
 C

*V
3CI#$$ 0s   <DFc           	         SSK nUS:w  a  [        S5      e[        XU5      u  p[        U 5      S:X  a  0 $ [        U 5      S:X  a!  [        R
                  R                  U 5      U0$ / nU(       am  SnSn	Un
XX-  -  -  n
[        [        U 5      5       HE  nX-  nXU-  -  n
UR                  UR                  U
5      U-  UR                  U
5      U-  /5        MG     OcUR                  [        U 5      [        S9nXM-  nUR                  XR                  UR                  U5      UR                  U5      /5      -  5      n[        UR                  U5      US9U-   n[!        [#        X5      5      nU$ )	aW  Position nodes in a spiral layout.

Parameters
----------
G : NetworkX graph or list of nodes
    A position will be assigned to every node in G.
scale : number (default: 1)
    Scale factor for positions.
center : array-like or None
    Coordinate pair around which to center the layout.
dim : int, default=2
    Dimension of layout, currently only dim=2 is supported.
    Other dimension values result in a ValueError.
resolution : float, default=0.35
    The compactness of the spiral layout returned.
    Lower values result in more compressed spiral layouts.
equidistant : bool, default=False
    If True, nodes will be positioned equidistant from each other
    by decreasing angle further from center.
    If False, nodes will be positioned at equal angles
    from each other by increasing separation further from center.

Returns
-------
pos : dict
    A dictionary of positions keyed by node

Raises
------
ValueError
    If dim != 2

Examples
--------
>>> G = nx.path_graph(4)
>>> pos = nx.spiral_layout(G)
>>> nx.draw(G, pos=pos)

Notes
-----
This algorithm currently only works in two dimensions.

r   Nr(   rA   r1   r   r   r4   )r   r   r%   r   r   r7   r8   r   appendr<   r=   arangefloatr   r   r	   r-   r.   )r   r5   r   r    
resolutionequidistantr!   r0   chordstepr?   r   rr   angles                  r$   r   r     sO   X 
ax7883/IA
1v{	
1v{**1-v66
C$,''s1vAAQYEJJu)266%=1+<=>  yyQuy-!ll4((BFF5M266%=+I"JJK
#e
4v
=C
s1{
CJr&   c                    SSK nUS;  a  Sn[        U5      e[        XSS9u  p[        U 5      S:X  a  0 $  [        U 5      [	        S UR                  5        5       5      :w  a  [        R                  " S5      e  [        [        UR                  5       5      5      nSn	/ n
[        U5      n[!        UR                  5       5       H  u  p[        U5      nUR#                  X5      nUR%                  SU[&        S
9nUS-
  S-  US-
  S-  4nUR)                  UU/5      U-
  nU	c  Un	OUR+                  U	U/5      n	U
R-                  U5        M     [/        XS9U-   n	US:X  a  U	SS2SSS24   n	[        [1        X5      5      n	U	$ ! [         aj    [        R                  " X5      n[        U5      [        U 5      :w  a  [        R                  " S	U 35      e[        R                  R                  U5      n GN|f = f! [         a    Un GNlf = f)a  Position nodes in layers of straight lines.

Parameters
----------
G : NetworkX graph or list of nodes
    A position will be assigned to every node in G.

subset_key : string or dict (default='subset')
    If a string, the key of node data in G that holds the node subset.
    If a dict, keyed by layer number to the nodes in that layer/subset.

align : string (default='vertical')
    The alignment of nodes. Vertical or horizontal.

scale : number (default: 1)
    Scale factor for positions.

center : array-like or None
    Coordinate pair around which to center the layout.

Returns
-------
pos : dict
    A dictionary of positions keyed by node.

Examples
--------
>>> G = nx.complete_multipartite_graph(28, 16, 10)
>>> pos = nx.multipartite_layout(G)

or use a dict to provide the layers of the layout

>>> G = nx.Graph([(0, 1), (1, 2), (1, 3), (3, 4)])
>>> layers = {"a": [0], "b": [1], "c": [2, 3], "d": [4]}
>>> pos = nx.multipartite_layout(G, subset_key=layers)

Notes
-----
This algorithm currently only works in two dimensions and does not
try to minimize edge crossings.

Network does not need to be a complete multipartite graph. As long as nodes
have subset_key data, they will be placed in the corresponding layers.

r   NrP   rR   r(   rS   c              3   8   #    U  H  n[        U5      v   M     g 7frh   r   rj   rM   s     r$   rm   &multipartite_layout.<locals>.<genexpr>?  s     E1DU1D   z4all nodes must be in one subset of `subset_key` dictz'all nodes need a subset_key attribute: r   r1   r4   rQ   r3   )r   r   r%   r   r   ru   r   r   r   get_node_attributesr7   groupsr-   sorteditems	TypeErrorrt   rU   r   r   r;   rV   extendr	   r.   )r   
subset_keyrW   r5   r   r!   r#   node_to_subsetlayersr0   rM   rZ   r   layerrY   xsysr[   	layer_poss                      r$   r   r     s   \ ..<oa8IA
1v{	5q6SE1B1B1DEEE""F  FfZ--/01 CEKEfmmo.UYYq!YYq&Y.19/FQJ!#34OORH-6	;C..#y!12CU / 
*V
3C!TrT'l
s5
CJC  5//>~#a&(""9*F  XX__^4
5  s%   AF ;"G: A0G76G7:H
	H
r/   r/   c                  ^ SSK nSSKn	US::  a  Sn
[        U
5      e[        R                  " XS9nUc  UnO2U R                  5        H  nX;  d  M
  X   R                  5       X'   M      [        U 5      nUS:X  a  U$ U	R                  X45      U	R                  U5      -
  n[        U 5       VVs0 s H  u  pX_M	     snnmU R                  5        H%  u  nnUU:w  d  M  U4S jUU4 5       u  nnX>UU4'   M'     U	R                  [        UR                  5       5      5      nX)R                  U5      -  nUS-   nSnUU:  a  USS2U	R                   4   UU	R                      -
  nU	R"                  R%                  USS9S	U	R                   4   nUR'                  5          UR)                  S
5        US	U	R                   4   U-  UU-  U-  -
  nSSS5        U	R+                  WSS9nUUU-  -  nU	R"                  R%                  USS9R-                  5       nUU:  a  OUS-  nUU:  a  M  [/        [1        U R                  5       U5      5      $ s  snnf ! , (       d  f       N= f)a/  Arf layout for networkx

The attractive and repulsive forces (arf) layout [1]
improves the spring layout in three ways. First, it
prevents congestion of highly connected nodes due to
strong forcing between nodes. Second, it utilizes the
layout space more effectively by preventing large gaps
that spring layout tends to create. Lastly, the arf
layout represents symmetries in the layout better than
the default spring layout.

Parameters
----------
G : nx.Graph or nx.DiGraph
    Networkx graph.
pos : dict
    Initial  position of  the nodes.  If set  to None  a
    random layout will be used.
scaling : float
    Scales the radius of the circular layout space.
a : float
    Strength of springs between connected nodes. Should be larger than 1. The greater a, the clearer the separation ofunconnected sub clusters.
etol : float
    Gradient sum of spring forces must be larger than `etol` before successful termination.
dt : float
    Time step for force differential equation simulations.
max_iter : int
    Max iterations before termination of the algorithm.
seed : int, RandomState instance or None  optional (default=None)
    Set the random state for deterministic node layouts.
    If int, `seed` is the seed used by the random number generator,
    if numpy.random.RandomState instance, `seed` is the random
    number generator,
    if None, the random number generator is the RandomState instance used
    by numpy.random.

References
.. [1] "Self-Organization Applied to Dynamic Network Layout", M. Geipel,
        International Journal of Modern Physics C, 2007, Vol 18, No 10, pp. 1537-1549.
        https://doi.org/10.1142/S0129183107011558 https://arxiv.org/abs/0704.1748

Returns
-------
pos : dict
    A dictionary of positions keyed by node.

Examples
--------
>>> G = nx.grid_graph((5, 5))
>>> pos = nx.arf_layout(G)

r   Nr1   z'The parameter a should be larger than 1r  c              3   .   >#    U  H
  nTU   v   M     g 7frh   ri   )rj   r   
node_orders     r$   rm   arf_layout.<locals>.<genexpr>  s     6v!
1vs   r3   r   .ignore)warningsr   r   r   r   rM   copyr   r   r   rt   edgesr   rE   ru   rx   r   r   r   catch_warningssimplefilternansumr   r-   r.   )r   r0   scalingaetolr   max_iterr/   r  r!   r#   pos_tmpr   NKr   r   yidxjdxprhoerrorn_iterdiffr   changer  s                              @r$   r   r   g  s=   @ Av7oq,G
{GGID#M..0	 
 	AAAv
 	"&&)#A)216ga$'6J	1661v6HCc3hK  	

4

%&A GGAJ
C 1HEF
$,BJJ!BJJ-/IINN4bN)#rzz/: $$&!!(+sBJJ'$.q4?F ' 6*	Vb[		vB/335H! $,  AGGIq!""? 7* '&s   .I/I
Id   r   r   )r(  jitter_tolerancescaling_ratiogravitydistributed_actionstrong_gravity	node_mass	node_sizerr   dissuade_hubslinlogr/   r    c          	      
   SSK n[        U 5      S:X  a  0 $ Uc>  [        R                  " XUS9nUR	                  [        UR                  5       5      5      nOUR	                  [        UR                  5       5      5      nUR                  SS9nUR                  SS9nUR                  nUUR                  [        U 5      U5      UU-
  -  -   n[        U 5       H$  u  nnUU;   d  M  UU   R                  5       UU'   M&     UR                  [        U 5      5      nUR                  [        U 5      5      nSnU	c  0 n	OSnUc  0 n[        U 5       HB  u  nnUR                  UU R                  U5      S-   5      UU'   U	R                  US5      UU'   MD     [        U 5      nUR                  UU45      nUR                  UU45      nUR                  UU45      n[        R                   " X
S9nS	 nSnSn Sn!Sn"[#        U5       GH  n#USS2S4   US   -
  n$UR$                  R'                  U$S
S9n%U(       aQ  UR)                  SU%-   5      * U%-  nUR+                  US5        UR-                  SUU5      nUR-                  SU$U5      nOUR-                  SU$U5      * nU(       a  UUSS2S4   -  nUSS2S4   US   -  n&U(       a  U%USS2S4   * US   -
  -  n%U%S-  n'UR+                  U&S5        UR+                  U'S5        U&U'-  U-  n(UR-                  SU$U(5      nU* USS2S4   -  U-  UR$                  R'                  US
S9SS2S4   -  nU(       a$  UUR$                  R'                  US
S9SS2S4   -  nUU-   U-   n)U!UUR$                  R'                  UU)-
  S
S9-  R/                  5       -  n!U"SU-  UR$                  R'                  UU)-   S
S9-  R/                  5       -  n"U" UU!U"UU U5      u  nn U(       a  UUR$                  R'                  U)S
S9-  n*SU-  SUR1                  UU*-  5      -   -  n(UR$                  R'                  U)S
S9n+UR3                  U(U+-  SUR5                  U+R6                  5      -  5      U+-  n(O7UUR$                  R'                  U)S
S9-  n*USUR1                  UU*-  5      -   -  n(UU)U(SS2S4   -  -  n[9        U)U(SS2S4   -  R/                  5       5      S:  d  GM    O   [;        [=        U U5      5      $ )aJ	  Position nodes using the ForceAtlas2 force-directed layout algorithm.

This function applies the ForceAtlas2 layout algorithm [1]_ to a NetworkX graph,
positioning the nodes in a way that visually represents the structure of the graph.
The algorithm uses physical simulation to minimize the energy of the system,
resulting in a more readable layout.

Parameters
----------
G : nx.Graph
    A NetworkX graph to be laid out.
pos : dict or None, optional
    Initial positions of the nodes. If None, random initial positions are used.
max_iter : int (default: 100)
    Number of iterations for the layout optimization.
jitter_tolerance : float (default: 1.0)
    Controls the tolerance for adjusting the speed of layout generation.
scaling_ratio : float (default: 2.0)
    Determines the scaling of attraction and repulsion forces.
distributed_attraction : bool (default: False)
    Distributes the attraction force evenly among nodes.
strong_gravity : bool (default: False)
    Applies a strong gravitational pull towards the center.
node_mass : dict or None, optional
    Maps nodes to their masses, influencing the attraction to other nodes.
node_size : dict or None, optional
    Maps nodes to their sizes, preventing crowding by creating a halo effect.
dissuade_hubs : bool (default: False)
    Prevents the clustering of hub nodes.
linlog : bool (default: False)
    Uses logarithmic attraction instead of linear.
seed : int, RandomState instance or None  optional (default=None)
    Used only for the initial positions in the algorithm.
    Set the random state for deterministic node layouts.
    If int, `seed` is the seed used by the random number generator,
    if numpy.random.RandomState instance, `seed` is the random
    number generator,
    if None, the random number generator is the RandomState instance used
    by numpy.random.
dim : int (default: 2)
    Sets the dimensions for the layout. Ignored if `pos` is provided.

Examples
--------
>>> import networkx as nx
>>> G = nx.florentine_families_graph()
>>> pos = nx.forceatlas2_layout(G)
>>> nx.draw(G, pos=pos)

References
----------
.. [1] Jacomy, M., Venturini, T., Heymann, S., & Bastian, M. (2014).
       ForceAtlas2, a continuous graph layout algorithm for handy network
       visualization designed for the Gephi software. PloS one, 9(6), e98679.
       https://doi.org/10.1371/journal.pone.0098679
r   N)r    r/   r   FTr1   rs   c                    SSK nSUR                  U 5      -  nUR                  U5      nSn	Sn
[        XU-  U S-  -  5      nU[        X5      -  nX-  S:  a  XJ:  a  US-  n[        X5      nUS:X  a  UR                  nO
X-  U-  U-  nXU-  :  a  XJ:  a  US-  nOUS	:  a  US
-  nSnU[        X-
  X-  5      -   nX44$ )a!  Computes the scaling factor for the force in the ForceAtlas2 layout algorithm.

This   helper  function   adjusts   the  speed   and
efficiency  of the  layout generation  based on  the
current state of  the system, such as  the number of
nodes, current swing, and traction forces.

Parameters
----------
n : int
    Number of nodes in the graph.
swing : float
    The current swing, representing the oscillation of the nodes.
traction : float
    The current traction force, representing the attraction between nodes.
speed : float
    The current speed of the layout generation.
speed_efficiency : float
    The efficiency of the current speed, influencing how fast the layout converges.
jitter_tolerance : float
    The tolerance for jitter, affecting how much speed adjustment is allowed.

Returns
-------
tuple
    A tuple containing the updated speed and speed efficiency.

Notes
-----
This function is a part of the ForceAtlas2 layout algorithm and is used to dynamically adjust the
layout parameters to achieve an optimal and stable visualization.

r   Ng?re   r(   r   r   gffffff?  g?)r   rx   r   r6   inf)r   swingtractionspeedspeed_efficiencyr6  r!   
opt_jitter
min_jitter
max_jittermin_speed_efficiencyotherjittertarget_speedmax_rises                  r$   estimate_factor+forceatlas2_layout.<locals>.estimate_factorV  s    D 	 BGGAJ&
WWZ(

#JX 51 <=!C
$::c!6 C' 2FA:66L!4x?%GLH$$6 C' T\#L0(2BCC&&r&   r3   zij, ij -> ijzijk, ij -> ikr(   r   r   g      $@g|=)r   r   r   r   r   rE   ru   r6   r   sizer*   rt   r   r   getdegreerz   r   r   r   logfill_diagonalr   r   rx   minimumr   rw   absr-   r.   ),r   r0   r(  r6  r7  r8  r9  r:  r;  r<  rr   r=  r>  r/   r    r!   r   pos_initmax_posmin_posr-  r   massrQ  adjust_sizesr   	gravities
attraction	repulsionr   rO  rE  rF  rC  rD  r   r3  r   tmpd2factorrF   swingingdfs,                                               r$   r   r     s$   V 
1v{	
{q5((4

-. 88D./,,A,&,,A,&llDIIc!fc2g6GHH"1ICs{"4y~~/ & 88CFD88CFD L		q\	TMM$(:;S	MM$*S	 " 	AA!S"I1c(#J!S"I
!+A>'@ EEH8_q$w'$-/99>>$R>0 &&X..9JZ+>:qAJ?D*EJ ))OT1==J$q$w-'J 1d7md4j(agd33Hq[
a 
Q(m+IIotV<	 H1d7m iinnW2n.q$w78 	 b9!T'BBIi')3 	$&(8rBBGGIIS4Z"))..61A."KKPPRR"1#
 biinnV"n==H5[A0@(A$ABFR0BZZTBGGBHH4E-EFKFbiinnV"n==Ha"''%(*:";;<F6F1d7O++4(--/058K N Aw  r&   c                     SSK nX R                  SS9-  n UR                  U 5      R                  5       nUS:  a  XU-  -  n U $ )a7  Returns scaled position array to (-scale, scale) in all axes.

The function acts on NumPy arrays which hold position information.
Each position is one row of the array. The dimension of the space
equals the number of columns. Each coordinate in one column.

To rescale, the mean (center) is subtracted from each axis separately.
Then all values are scaled so that the largest magnitude value
from all axes equals `scale` (thus, the aspect ratio is preserved).
The resulting NumPy Array is returned (order of rows unchanged).

Parameters
----------
pos : numpy array
    positions to be scaled. Each row is a position.

scale : number (default: 1)
    The size of the resulting extent in all directions.

Returns
-------
pos : numpy array
    scaled positions. Each row is a position.

See Also
--------
rescale_layout_dict
r   Nr   )r   meanrW  r6   )r0   r5   r!   lims       r$   r	   r	     sH    :  888C
&&+//
C
Qws{Jr&   c                     SSK nU (       d  0 $ UR                  [        U R                  5       5      5      n[	        X1S9n[        [        X5      5      $ )a  Return a dictionary of scaled positions keyed by node

Parameters
----------
pos : A dictionary of positions keyed by node

scale : number (default: 1)
    The size of the resulting extent in all directions.

Returns
-------
pos : A dictionary of positions keyed by node

Examples
--------
>>> import numpy as np
>>> pos = {0: np.array((0, 0)), 1: np.array((1, 1)), 2: np.array((0.5, 0.5))}
>>> nx.rescale_layout_dict(pos)
{0: array([-1., -1.]), 1: array([1., 1.]), 2: array([0., 0.])}

>>> pos = {0: np.array((0, 0)), 1: np.array((-1, 1)), 2: np.array((-0.5, 0.5))}
>>> nx.rescale_layout_dict(pos, scale=2)
{0: array([ 2., -2.]), 1: array([-2.,  2.]), 2: array([0., 0.])}

See Also
--------
rescale_layout
r   Nr4   )r   r   rE   ru   r	   r-   r.   )r0   r5   r!   pos_vs       r$   r
   r
     sA    : 	HHT#**,'(E5.EC  r&   )rW   r5   r   c                
   [        XS5      u  p[        [        [        R                  " X5      5      5      n[        U 5      [        S UR                  5        5       5      :w  a  [        R                  " S5      e[        XX#US9$ )a!  Position nodes according to breadth-first search algorithm.

Parameters
----------
G : NetworkX graph
    A position will be assigned to every node in G.

start : node in `G`
    Starting node for bfs

center : array-like or None
    Coordinate pair around which to center the layout.

Returns
-------
pos : dict
    A dictionary of positions keyed by node.

Examples
--------
>>> G = nx.path_graph(4)
>>> pos = nx.bfs_layout(G, 0)

Notes
-----
This algorithm currently only works in two dimensions and does not
try to minimize edge crossings.

r(   c              3   8   #    U  H  n[        U5      v   M     g 7frh   r  r	  s     r$   rm   bfs_layout.<locals>.<genexpr>U  s     =_ESZZ_r  zwbfs_layout didn't include all nodes. Perhaps use input graph:
        G.subgraph(nx.node_connected_component(G, start)))r  rW   r5   r   )
r%   r-   rt   r   
bfs_layersr   r   ru   r   r   )r   startrW   r5   r   r  s         r$   r   r   2  sx    <  1-IA )BMM!345F
1v=V]]_===H
 	
 	Ev r&   )Nr(   N)r1   Nr(   )NNr1   Nr(   )rN   r1   NgUUUUUU?)
NNN2   -C6?rr   r1   Nr(   N)NNNro  rp  r(   N)NNrr   r1   Nr(   )rr   r1   Nr(   )r(   )r1   Nr(   gffffff?F)subsetrN   r1   N)Nr1   g?gư>r   rA  rh   )r1   )__doc__networkxr   networkx.utilsr   __all__r%   r   r   r   r   r   r   r{   ry   r   r   r   r   r   r   r   r   r   r   r   r	   r
   r   ri   r&   r$   <module>rv     s  $  *(* - -`AHXx DIK\  

		W Wt ,  PT: :z PTE ER HIJZ*, 2L^+*+66%rL^_D  			v# 
v# v#r  	! 		!! !D%P#!L #-Ad ,r&   