Yc@sUdZddlZddlmZddlZddgZdZdZeedZ d Z d Z d Z d eed Z ddZdZddZdZdZdZdZdZdZdZdZdZedZdZdZdZddZ dZ!d Z"d!d!dd"Z#dS(#s? Threshold Graphs - Creation, manipulation and identification. iN(tsqrttis_threshold_graphtfind_threshold_graphcCs ttd|jDS(s1 Returns True if G is a threshold graph. css|]\}}|VqdS(N((t.0tntd((ss/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/threshold.pys s(tis_threshold_sequencetlisttdegree(tG((ss/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/threshold.pyRscCs|}|jxr|r|ddkr=|jdqn|dt|dkr[tS|jg|D]}|d^ql}qWtS(s Returns True if the sequence is a threshold degree seqeunce. Uses the property that a threshold graph must be constructed by adding either dominating or isolated nodes. Thus, it can be deconstructed iteratively by removing a node of degree zero or a node that connects to the remaining nodes. If this deconstruction failes then the sequence is not a threshold sequence. iii(tsorttpoptlentFalsetTrue(tdegree_sequencetdsR((ss/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/threshold.pyRs     !c Cs|r|rtdnt|trXg|jD]\}}||g^q7}n+gt|D]\}}||g^qe}|jg}x|r|dddkr |jd\}} t|dkr|jd| dfq|jd| dfqn|ddt|dkr.dS|j\}} |jd| dfg|D]}|dd|dg^q]}qW|r|S|rt |Sg|D]} | d^qS(s Determines the creation sequence for the given threshold degree sequence. 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'. This list can be converted to a string if desired using "".join(cs) 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. Returns None if the sequence is not a threshold sequence s#compact sequences cannot be labeleditiRiiN( t ValueErrort isinstancetdicttitemst enumerateR R R tinserttNonet make_compact( Rt with_labelstcompacttlabelRRRRtcstv((ss/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/threshold.pytcreation_sequence4s0 .+  / cCs|d}t|tr#|}nNt|trRg|D]}|d^q9}nt|tre|Stdg}d}xUtdt|D]>}||||dkr|d7}q|j|d}qW|j||S(sK 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] iis"Not a valid creation sequence type(Rtstrttupletintt TypeErrortrangeR tappend(RtfirstRtstccstcountR((ss/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/threshold.pyRos"        cCs|d}t|tr|St|tr0|St|trI|}n tdg}xM|r|j|jddg|r^|j|jddgq^q^W|S(s 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. is"Not a valid creation sequence typeRR(RR R!R"R#textendR (RR&tccscopyR((ss/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/threshold.pyt uncompacts    $c Cs|d}t|trAt|tr2|}qt|}nYt|trpg|D]}|d^qW}n*t|trt|}n td|jd}d}xXt|D]J\}}|dkr|||<|}q|dkr|}|d7}qqW|jxXt|D]J\}}|dkrM|||<|}q"|dkr"|}|d7}q"q"W|dkr|d7}ndt |}g|D]} | |^qS(s 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. iis"Not a valid creation sequence typeRRg?( RR RR!R"R,R#treverseRtfloat( RR&twseqRtwtprevtjR'twscaletww((ss/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/threshold.pytcreation_sequence_to_weightss@                ic Cs|r|rtdnt|trXg|jD]\}}||g^q7}n+gt|D]\}}||g^qe}|jg}||dd} x|ra|dd| kr|jd\}}|j|dfn7|j\}}|j|df||dd} t|dkr|j\}}|j|dfqqW|j |rv|S|rt |Sg|D]} | d^qS(s 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. s#compact sequences cannot be labelediiRRi( RRRRRR R R%R R-R( tweightst thresholdRRRR0R/RRtcutoffR((ss/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/threshold.pytweights_to_creation_sequences0 .+    c Cs;|d}t|tr.tt|}nRt|trG|}n9t|trwt|}tt|}n dGHdS|dkrtj }n.|j rtj dn|}|j d|_ xb|r6|jd\}}|dkr&x't|D]}|j||q Wn|j|qW|S(s Create a threshold graph from the creation sequence or compact creation_sequence. The input sequence can be a creation sequence (e.g. ['d','i','d','d','d','i']) labeled creation sequence (e.g. [(0,'d'),(2,'d'),(1,'i')]) compact creation sequence (e.g. [2,1,1,2,0]) Use cs=creation_sequence(degree_sequence,labeled=True) to convert a degree sequence to a creation sequence. Returns None if the sequence is not valid is"not a valid creation sequence typesDirected Graph not supportedsThreshold GraphRN(RR RRR!R"R,RtnetworkxtGrapht is_directedt NetworkXErrortcleartnameR tadd_edgetadd_node( Rt create_usingR&tciRR Rt node_typetu((ss/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/threshold.pytthreshold_graphs0         cCsx|jD]\}}x|jD]q}|j|| r&||kr&xI|j|D]5}|j|| r[||kr[||||gSq[Wq&q&Wq WtS(s 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. (tedgestnodesthas_edget neighborsR (R RERR0tx((ss/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/threshold.pytfind_alternating_4_cycleVscCstt||S(s Return a threshold subgraph that is close to largest in G. The threshold graph will contain the largest degree node in G. (RFtfind_creation_sequence(R RB((ss/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/threshold.pyResc Cs@g}|}x#|jdkr1t|j}g|jD]\}}||f^q@}|j|dddkr|jt|dgt|ddgPnx@|dddkr|jd\}}|j |dfqW|j\}}|j |df|j |j |}qW|j |S(s Find a threshold subgraph that is close to largest in G. Returns the labeled creation sequence of that threshold graph. iiRiR( torderRRRR R*tzipR R R%tsubgraphRJR-( R RtHtdsdictRRRtisotbigv((ss/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/threshold.pyRMns"+ . cCs|}|jd}||d|dd}xIt|D];\}}|dkrm|||dd7}q<|d8}q<W|S(sb Compute number of triangles in the threshold graph with the given creation sequence. RiiiR(R)R(RRtdrtntriRttyp((ss/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/threshold.pyt triangless c Cs|}g}|jd}|d|dd}d}d}xt|D]\}}|dkr|d7}||d|} nS| dkr||d|7}d}||8}d}n|d7}||dd} |j| |} qJW|S(sT Return triangle sequence for the given threshold graph creation sequence. Riii(R)RR%( RRtseqRUtdcurtiruntdrunRtsymttritprevsym((ss/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/threshold.pyttriangle_sequences(        cCst|}t|}g}xrt|D]d\}}||}|dkr`|jdq+n||dd}|jt|t|q+W|S(sR Return cluster sequence for the given threshold graph creation sequence. iii(R`RRR%R.(RttriseqtdegseqtcseqRtdegR^tmax_size((ss/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/threshold.pytcluster_sequences     !cCss|}g}|jd}xQt|D]C\}}|dkr^|d8}|j||q(|j|q(W|S(s] Return degree sequence for the threshold graph with the given creation sequence Ri(R)RR%(RRRYtrdRR]((ss/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/threshold.pyRs  cCs@t|}tt|}||d}|t|}|S(s Return the density of the graph with this creation_sequence. The density is the fraction of possible edges present. i(R tsumRR.(RtNttwo_sizet two_possibletden((ss/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/threshold.pytdensitys  cCs|}d}d}d}d}|jd}gt|D]\}}|dkr:|^q:} t|} xt|D]\}}|dkr|| dkrd|| fGHtn| jdn| |} xT| D]L} | | } || | 7}|| d| d7}|| | 7}|d7}qWqwWd||||}d||||}|dkr|dkrsdStd|n|t|S(s> Return the degree-degree correlation over all edges. iRs!Logic error in degree_correlationiiis$Zero Denominator but Numerator is %s(R)RRRR R.(RRts1ts2ts3tmRgRR]trdiRtdegitdjtdegjtdenomtnumer((ss/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/threshold.pytdegree_correlations81        c Cs|d}t|trKgtt|D]}|||f^q,}nrt|trd|}nYt|trt|}gtt|D]}|||f^q}n tdg|D]}|d^q}||krtd|n||krtd|n||kr+|gS|j |} |j |} t | | } || ddkrv||gS|| }x7|r|j } | ddkr|| d|gSqWdS(s= 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)) refering to the position of the desired vertices in the sequence. For a labeled creation_sequence, u and v are labels of veritices. 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] is"Not a valid creation sequence types-Vertex %s not in graph from creation_sequenceiRi( RR R$R R!R"R,R#RtindextmaxR ( RRERR&RRRCR'tvertstuindextvindextbigindtvert((ss/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/threshold.pyt shortest_paths6 2  2        cCs|d}t|trAt|tr2|}qt|}nt|trg|D]}|d^qW}g|D]}|d^qtj|}n*t|trt|}n tdt|}dg|}d|| s>     ; ,  /= 7      " 5 . ( :  ) " " #