K iZdZddlmZddlZddlmZddgZejdZ dZ d'd Z d Z d Z d Z d(d Zejddd)dZejdZejdd)dZejdZdZdZdZdZdZdZdZdZd*dZdZdZd Zed!d)d"Z d#Z!d$Z"ed%d+d&Z#y),z? Threshold Graphs - Creation, manipulation and identification. )sqrtN)py_random_stateis_threshold_graphfind_threshold_graphcft|jDcgc]\}}| c}}Scc}}w)ax Returns `True` if `G` is a threshold graph. Parameters ---------- G : NetworkX graph instance An instance of `Graph`, `DiGraph`, `MultiGraph` or `MultiDiGraph` Returns ------- bool `True` if `G` is a threshold graph, `False` otherwise. Examples -------- >>> from networkx.algorithms.threshold import is_threshold_graph >>> G = nx.path_graph(3) >>> is_threshold_graph(G) True >>> G = nx.barbell_graph(3, 3) >>> is_threshold_graph(G) False References ---------- .. [1] Threshold graphs: https://en.wikipedia.org/wiki/Threshold_graph )is_threshold_sequencedegree)Gnds c/mnt/ssd/data/python-lab/Trading/venv/lib/python3.12/site-packages/networkx/algorithms/threshold.pyrr s': ! !;1!!; <??/4(5D5J5J5L M/5&vuo M M!*?!; <Aq!f < <GGI B a58q=VVAYFQ2w{ !aX& !aX&  b6!9B! #A !aX(* +1qtax1 + +  B QAaD /N <, sEEE E cr|d}t|tr|dd}n@t|tr|Dcgc]}|d }}nt|tr|St dg}d}t dt |D])}||||dz k(r|dz }|j|d}+|j||Scc}w)aK Returns the creation sequence in a compact form that is the number of 'i's and 'd's alternating. Examples -------- >>> from networkx.algorithms.threshold import make_compact >>> make_compact(["d", "i", "i", "d", "d", "i", "i", "i"]) [1, 2, 2, 3] >>> make_compact(["d", "d", "d", "i", "d", "d"]) [3, 1, 2] Notice that the first number is the first vertex to be used for construction and so is always 'd'. Labeled creation sequences lose their labels in the compact representation. >>> make_compact([3, 1, 2]) [3, 1, 2] rNr"Not a valid creation sequence type)rstrtupleint TypeErrorrangerappend)r%firstr#sccscountrs r rrs, a E% q ! E5 !- .qad . . E3   <== C E 1c"g  a5Bq1uI  QJE JJu E  JJu J/s B4c<|d}t|tr|St|tr|St|tr|dd}n t dg}|rM|j |j ddgz|r$|j |j ddgz|rM|S)z Converts a compact creation sequence for a threshold graph to a standard creation sequence (unlabeled). If the creation_sequence is already standard, return it. See creation_sequence. rNr'r r)rr(r)r*r+extendr)r%r.ccscopyr#s r uncompactr5s a E%  E5 !  E3 #A&<== B  '++a.C5()  IIgkk!nu, -  IcX|d}t|tr"t|tr|dd}nVt|}nJt|tr|Dcgc]}|d }}n't|tr t |}n t d|jd}d}t|D]\}}|dk(r|||<|}|dk(s|}|dz }!|jt|D]\}}|dk(r|||<|}|dk(s|}|dz }!|dk(r|dz }d|z }|D cgc]} | |z c} Scc}wcc} w)z Returns a list of node weights which create the threshold graph designated by the creation sequence. The weights are scaled so that the threshold is 1.0. The order of the nodes is the same as that in the creation sequence. rNrr'rr ) rr(listr)r*r5r+reverser) r%r.wseqr$wprevjr/wscalewws r creation_sequence_to_weightsr@sT a E% ' .$Q'D)*D E5 !/0!00 E3 *+<==LLN A D$1 8DGD S[D FA  LLN$1 8DGD S[D FA  s{ Q UF"& 'BBK ''918 (s D" D'c|r |r tdt|tr%|jDcgc] \}}||g }}}nt |Dcgc] \}}||g }}}|j g}||ddz } |r|dd| kr(|j d\}}|j|dfn1|j \}}|j|df||ddz } t|dk(r&|j \}}|j|df|r|j|r|S|r t|S|D cgc]} | d c} Scc}}wcc}}wcc} w)a Returns a creation sequence for a threshold graph determined by the weights and threshold given as input. If the sum of two node weights is greater than the threshold value, an edge is created between these nodes. The creation sequence is a list of single characters 'd' or 'i': 'd' for dominating or 'i' for isolated vertices. Dominating vertices are connected to all vertices present when it is added. The first node added is by convention 'd'. If with_labels==True: Returns a list of 2-tuples containing the vertex number and a character 'd' or 'i' which describes the type of vertex. If compact==True: Returns the creation sequence in a compact form that is the number of 'i's and 'd's alternating. Examples: [1,2,2,3] represents d,i,i,d,d,i,i,i [3,1,2] represents d,d,d,i,d,d Notice that the first number is the first vertex to be used for construction and so is always 'd'. with_labels and compact cannot both be True. rrrrr r) rrrrrrrr-rr9r) weights thresholdr r!r"r;r:rr#cutoffr$s r weights_to_creation_sequencerEsY<w>??'4 -4]]_=zqE ==#,W#5641aA66IIK B b! $F  71: !JQ IIucl #JQ IIucl #b!,F t9>JQ IIucl # JJL B QAaD 1>6, sEE ET)graphs returns_graphc$|d}t|trtt|}nRt|tr|dd}n> AF I   !W ! 1a  ! 1   Hr6c|jD]m\}}|jD]U}|j||r||k7s|j|D]&}|j||r||k7s||||gcccSWoy)z Returns False if there aren't any alternating 4 cycles. Otherwise returns the cycle as [a,b,c,d] where (a,b) and (c,d) are edges and (a,c) and (b,d) are not. F)edgesnodeshas_edge neighbors)r rTr$r;xs r find_alternating_4_cycler\es ,1 ,A::a#QQ,A::a+Q !1a|+, ,, r6)rGc,tt||S)as Returns a threshold subgraph that is close to largest in `G`. The threshold graph will contain the largest degree node in G. Parameters ---------- G : NetworkX graph instance An instance of `Graph`, or `MultiDiGraph` create_using : NetworkX graph class or `None` (default), optional Type of graph to use when constructing the threshold graph. If `None`, infer the appropriate graph type from the input. Returns ------- graph : A graph instance representing the threshold graph Examples -------- >>> from networkx.algorithms.threshold import find_threshold_graph >>> G = nx.barbell_graph(3, 3) >>> T = find_threshold_graph(G) >>> T.nodes # may vary NodeView((7, 8, 5, 6)) References ---------- .. [1] Threshold graphs: https://en.wikipedia.org/wiki/Threshold_graph )rUfind_creation_sequence)r rQs r rrus@ 1!4l CCr6c g}|}|jdkDr!t|j}|jDcgc] \}}||f }}}|j |dddk(r0|j t |dgt|dz zdgzn|dddk(r3|jd\}}|j|df|dddk(r3|j\}}|j|df|j|j|}|jdkDr!|j|Scc}}w)z Find a threshold subgraph that is close to largest in G. Returns the labeled creation sequence of that threshold graph. rrrrr ) orderrr rrr3ziprrr-subgraphrZr9) r r#Hdsdictr$r risobigvs r r^r^s- B A '')a-ahhj!!' 0Aq!f 0 0  b6!9> IIc&3%3r7Q;"73%"?@ A eAh!mvvayHQ IIsCj !eAh!mFFH D 4+ JJq{{4( )% '')a-&JJL I#1sE c|}|jd}||dz z|dz zdz }t|D]\}}|dk(r|||dz zdz z }|dz} |S)zb Compute number of triangles in the threshold graph with the given creation sequence. r rr)r1r)r%r#drntrirtyps r trianglesrmsx B #B a=BF #a 'DB-3 #: B"q&MA% %D !GB  Kr6c|}g}|jd}|dz |dz zdz}d}d}t|D]W\}}|dk(r|dz }||dz |zz} n) dk(r||dz |zz }d}||z}d}|dz }||dz zdz} |j| |} Y|S)zT Return triangle sequence for the given threshold graph creation sequence. r rrhrr1rr-) r%r#seqrjdcurirundrunrsymtriprevsyms r triangle_sequencerws B C #B FrAv ! #D D DB- 3 #: AID"q&D(C#~a4'd  AIDQ-1$C 3  Jr6ct|}t|}g}t|D]@\}}||}|dkr|jd"||dz zdz}|j||z B|S)zR Return cluster sequence for the given threshold graph creation sequence. rrrh)rwrrr-)r%triseqdegseqcseqrdegrumax_sizes r cluster_sequencer~s~0 1F . /F DF#$3Qi !8 KKN 37O) C(N# $ Kr6c|}g}|jd}t|D]5\}}|dk(r|dz}|j||z%|j|7|S)z] Return degree sequence for the threshold graph with the given creation sequence r rro)r%r#rprdrrts r rrsd B C #BB-3 #: !GB JJrAv  JJrN  Jr6c^t|}tt|}||dz z}||z }|S)z Return the density of the graph with this creation_sequence. The density is the fraction of possible edges present. r)rsumr)r%Ntwo_size two_possibledens r densityr s; A?#456HA;L \ !C Jr6c|}d}d}d}d}|jd}t|Dcgc] \}}|dk(s |} }}t|} t|D]j\}}|dk(r,|| dk7rtd|| t| j d| |} | D]*} | | } || | zz }|| dz| dzzz }|| | zz }|dz },ld|z|z||zz }d|z|z||zz }|dk(r|dk(ryt d|||z Scc}}w)z> Return the degree-degree correlation over all edges. rr z!Logic error in degree_correlationrhrz"Zero Denominator but Numerator is )r1rrrIrr)r%r#s1s2s3mrrrtrdirdegidjdegjdenomnumers r degree_correlationrsZ B B B B A #B$R= 7CC3J1 7C 7  BB- 3 #:CF{91cB  GGAJ!u Bb6D $+ B $'D!G# #B $+ B FA    EBJb E EBJb E z A:=eWEFF 5=+ 8s C<C<c|d}t|tr'tt|Dcgc] }|||f }}nct|tr|dd}nMt|t r2t |}tt|Dcgc] }|||f }}n td|Dcgc]}|d }}||vrtd|d||vrtd|d||k(r|gS|j|} |j|} t| | } || ddk(r||gS|| d}|r#|j} | ddk(r|| d|gS|r#ycc}wcc}wcc}w) a= Find the shortest path between u and v in a threshold graph G with the given creation_sequence. For an unlabeled creation_sequence, the vertices u and v must be integers in (0,len(sequence)) referring to the position of the desired vertices in the sequence. For a labeled creation_sequence, u and v are labels of vertices. Use cs=creation_sequence(degree_sequence,with_labels=True) to convert a degree sequence to a creation sequence. Returns a list of vertices from u to v. Example: if they are neighbors, it returns [u,v] rNr'zVertex z$ not in graph from creation_sequencerr r) rr(r,rr)r*r5r+rindexmaxr) r%rTr$r.rr#rRr/vertsuindexvindexbigindverts r shortest_pathr9s$ a E%16s;L7M1N OAq#A&' O O E5 ! q ! E3  ( )"'B. 1Qq"Q%j 1 1<== aQqT E ~71#%IJKK~71#%IJKKAvs [[^F [[^F  F &z!}1v FGB vvx 7c>tAw? " =P 2 sEE $ EcT|d}t|tr"t|tr|dd}nxt|}nlt|tr5|Dcgc]}|d }}|Dcgc]}|d c}j |}n't|t r t |}n tdt|}dg|z}d||<t|dz|D]}||dk(s d||<||dk(rt|D]}d||< t|dz ddD]}||dk(r|Sd||<|Scc}wcc}w)a Return the shortest path length from indicated node to every other node for the threshold graph with the given creation sequence. Node is indicated by index i in creation_sequence unless creation_sequence is labeled in which case, i is taken to be the label of the node. Paths lengths in threshold graphs are at most 2. Length to unreachable nodes is set to -1. rNrr'rhr r) rr(r8r)rr*r5r+rr,)r%rr.r#r$rsplr=s r shortest_path_lengthrnsY a E% ' ."1%B'(B E5 !- .qad . ., -aQqT - 3 3A 6 E3  ( )<== BA #'C CF 1q5!_ a5C<CF !u|q ACF 1q5!R  a5C<  JA J// -s D  D%c|}g}d}t|jd}d}d}d}t|D]c\} } | dk(r&||dz |z|z zd|z| |z |z z|z z} |dz }n|dk(r  }||z}d}d}d} |dz }|jt| | }e|r+t |} d| dz | dz zz } |Dcgc]}|| z }}|Scc}w)z Return betweenness for the threshold graph with the given creation sequence. The result is unscaled. To scale the values to the interval [0,1] divide by (n-1)*(n-2). r rgrrh?)floatr1rr-r)r% normalizedr#rplastcharrjrrrsdlastrcbr`scaler/s r betweenness_sequencers B CH rxx} B D D E" 1 8T)B..TQX_1MPR1RRA AID3d A AID 58!&B eai01"%&Qq5y&& J's7 Cct|}t|}dg|z}|dd}t|ddd}|d}dt|z g|z|d<d|d<|}||z}d}d} d} | |krGdt| | z| zz } | | gz| | zgzdg|| z dz zz|| <||| <| dz } | dz } | |krGt|dk(r||fS|ddD]}dt|| z| |zzz } | | | zgz|| | zgzzdg|| z |z zz|| <| }|r | |z}||z}n|}||| <| } | dz } d} | |ksddt| | z | | zzz } dg| z| | z | gzz| | zgzdg|| z dz zz|| <||| <| dz } | dz } | |krT||fS)a Return a 2-tuple of Laplacian eigenvalues and eigenvectors for the threshold network with creation_sequence. The first value is a list of eigenvalues. The second value is a list of eigenvectors. The lists are in the same order so corresponding eigenvectors and eigenvalues are in the same position in the two lists. Notice that the order of the eigenvalues returned by eigenvalues(cs) may not correspond to the order of these eigenvectors. rNrhrTr)rrrr) r%r0rvecvalrjnnetype_drddrsts r eigenvectorsrsJ ( )C CA #'C a&C S1XB QBDGm_q CF CF A"HB F A B r'd27Q;''ufXe ,sa!eai/@@AA Q a r'  3x1}Sz!"gd26QV,--rcEk]"R1u9+%55q1urz8JJA BA "HBAA  Q 2g$q2vR/00ES2XRUF8 33rEzlBaSAPQETUIEVVCFCF FA !GB 2g( :r6c|g}|d}|D]/}tdt||D}|j|1|S)a Returns the coefficients of each eigenvector in a projection of the vector u onto the normalized eigenvectors which are contained in eigenpairs. eigenpairs should be a list of two objects. The first is a list of eigenvalues and the second a list of eigenvectors. The eigenvectors should be lists. There's not a lot of error checking on lengths of arrays, etc. so be careful. rc3,K|] \}}||zywN).0evvuvs r z&spectral_projection..s5Yc2b5s)rrar-)rT eigenpairscoeffevectevrs r spectral_projectionrsI E qME 5#b!*5 5 Q Lr6ct|}|jg}d}t|}|j}|r9||kr|j ||dz}n|dz }|r|j}nd}|r9|S)a Return sequence of eigenvalues of the Laplacian of the threshold graph for the given creation_sequence. Based on the Ferrer's diagram method. The spectrum is integral and is the conjugate of the degree sequence. See:: @Article{degree-merris-1994, author = {Russel Merris}, title = {Degree maximal graphs are Laplacian integral}, journal = {Linear Algebra Appl.}, year = {1994}, volume = {199}, pages = {381--389}, } rr)rrrrr-)r%rzeiglisteigrowbigdegs r eigenvaluesrs}(. /F KKMG C f+C ZZ\F C< NN3  1HC 1HC  Nr6rhcd|cxkrdkstdtddg}td|D]8}|j|kr|jd(|jd:|S)a Create a random threshold sequence of size n. A creation sequence is built by randomly choosing d's with probability p and i's with probability 1-p. s=nx.random_threshold_sequence(10,0.5) returns a threshold sequence of length 10 with equal probably of an i or a d at each position. A "random" threshold graph can be built with G=nx.threshold_graph(s) seed : integer, random_state, or None (default) Indicator of random number generation state. See :ref:`Randomness`. rrzp must be in [0,1]r r)rr,randomr-)r pseedr#rs r random_threshold_sequencer=ss( KaK-.. -.. B 1a[ ;;=1  IIcN IIcN  Ir6cdgdg|dz zz}||krd||<|S|||dz zdz kDr td|dz }|dz }||krd||<|dz}||z }||kr|||z z }d||<|S)aA Returns a "right-dominated" threshold sequence with `n` vertices and `m` edges. Each vertex in the sequence is either dominant or isolated. In the "right-dominated" version, once the basic sequence is formed, isolated vertices may be flipped to dominant from the right in order to reach the target number of edges. Parameters ---------- n : int Number of vertices. m : int Number of edges. Returns ------- A list of 'd' (dominant) and 'i' (isolated) forming a right-dominated threshold sequence. Raises ------ ValueError If `m` exceeds the maximum number of edges. Examples -------- >>> from networkx.algorithms.threshold import right_d_threshold_sequence >>> right_d_threshold_sequence(5, 3) ['d', 'i', 'i', 'd', 'i'] r rrrh#Too many edges for this many nodes.r)r rr#indrs r right_d_threshold_sequencer`s@ #!a% B 1u1  1A;?>?? a%C a%C '3 q s  ' sSy/CBsG Ir6cdgdg|dz zz}||krd||<|S|||dz zdz kDr tdd||dz <|dz }d}||krd||<||z }|dz }||kr||kDrd|||z <|S)a7 Returns a "left-dominated" threshold sequence with `n` vertices and `m` edges. Each vertex in the sequence is either dominant or isolated. In the "left-dominated" version, once the basic sequence is formed, isolated vertices may be flipped to dominant from the left in order to reach the target number of edges. Parameters ---------- n : int Number of vertices. m : int Number of edges. Returns ------- A list of 'd' (dominant) and 'i' (isolated) forming a left-dominated threshold sequence. Raises ------ ValueError If `m` exceeds the maximum number of edges. Examples -------- For certain small cases, both left and right dominated versions produce the same sequence. However, for larger values of `m`, the difference in flipping order becomes evident. For instance, compare the sequences for ``n=6, m=8``: >>> from networkx.algorithms.threshold import left_d_threshold_sequence >>> seq = left_d_threshold_sequence(6, 8) >>> seq ['d', 'd', 'd', 'i', 'i', 'd'] In contrast, the right-dominated version yields: >>> from networkx.algorithms.threshold import right_d_threshold_sequence >>> right_seq = right_d_threshold_sequence(6, 8) >>> right_seq ['d', 'i', 'i', 'd', 'i', 'd'] r rrrhrr)r rr#rrs r left_d_threshold_sequencersZ #!a% B 1u1  1A;?>??Bq1uI a%C C '3 s  q ' Qw37 Ir6ct|ddDcgc] \}}|dk(s |}}}|j|kre|j|}|jt|}||z } || k7r0||dk(r(|| dk(r d||<d||<d|| <|j ||j|krU|rS|j|} |j|} | | z} | t |k\s || dk(s| | k(r|Sd|| <d|| <d|| <|Scc}}w)a Perform a "swap" operation on a threshold sequence. The swap preserves the number of nodes and edges in the graph for the given sequence. The resulting sequence is still a threshold sequence. Perform one split and one combine operation on the 'd's of a creation sequence for a threshold graph. This operation maintains the number of nodes and edges in the graph, but shifts the edges from node to node maintaining the threshold quality of the graph. seed : integer, random_state, or None (default) Indicator of random number generation state. See :ref:`Randomness`. rrr r)rrchoicer,remover) r#p_split p_combinerrrSdlistrsplit_to flip_side first_choice second_choicetargets r swap_drs/(&/r!Bx%8 M>AyIrs`* !7 8==>.8v)X0+(`6;;~T20 30 f  %D&DD@(8"" D2j+\%P7t*$TD4nBJ..r6