zmc
2023-12-22 9fdbf60165db0400c2e8e6be2dc6e88138ac719a
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
U
K±d4Qã@s0dZddlmZddlmZGdd„deƒZdS)zÜ
altgraph.Graph - Base Graph class
=================================
 
..
  #--Version 2.1
  #--Bob Ippolito October, 2004
 
  #--Version 2.0
  #--Istvan Albert June, 2004
 
  #--Version 1.0
  #--Nathan Denny, May 27, 1999
é)Údeque)Ú
GraphErrorc@sÚeZdZdZdqdd„Zdd„Zdrdd„Zdsd d „Zd d„Zdd„Z    dd„Z
dd„Z dd„Z dd„Z dd„Zdd„Zdd„Zdd „Zd!d"„Zd#d$„Zd%d&„Zd'd(„Zd)d*„Zd+d,„Zd-d.„Zd/d0„Zd1d2„Zd3d4„Zd5d6„Zd7d8„Zd9d:„Zd;d<„Zd=d>„Z d?d@„Z!dAdB„Z"dCdD„Z#dEdF„Z$dGdH„Z%dIdJ„Z&dKdL„Z'dMdN„Z(dOdP„Z)dtdQdR„Z*dSdT„Z+dUdV„Z,dudWdX„Z-dYdZ„Z.d[d\„Z/dvd]d^„Z0dwd_d`„Z1dxdadb„Z2dydcdd„Z3dzdedf„Z4d{dgdh„Z5d|didj„Z6dkdl„Z7dmdn„Z8d}dodp„Z9dS)~ÚGrapha¼
    The Graph class represents a directed graph with *N* nodes and *E* edges.
 
    Naming conventions:
 
    - the prefixes such as *out*, *inc* and *all* will refer to methods
      that operate on the outgoing, incoming or all edges of that node.
 
      For example: :py:meth:`inc_degree` will refer to the degree of the node
      computed over the incoming edges (the number of neighbours linking to
      the node).
 
    - the prefixes such as *forw* and *back* will refer to the
      orientation of the edges used in the method with respect to the node.
 
      For example: :py:meth:`forw_bfs` will start at the node then use the
      outgoing edges to traverse the graph (goes forward).
    NcCsŽd|_ii|_|_ii|_|_|dk    rŠ|D]Z}t|ƒdkrT|\}}| ||¡q.t|ƒdkrz|\}}}| |||¡q.td|fƒ‚q.dS)z 
        Initialization
        rNéézCannot create edge from %s)Ú    next_edgeÚnodesÚedgesÚ hidden_edgesÚ hidden_nodesÚlenÚadd_edger)Úselfr    ÚitemÚheadÚtailÚdata©rúEd:\z\workplace\vscode\pyvenv\venv\Lib\site-packages\altgraph/Graph.pyÚ__init__)s  
zGraph.__init__cCsd| ¡| ¡fS)Nz<Graph: %d nodes, %d edges>)Únumber_of_nodesÚnumber_of_edges©rrrrÚ__repr__=sþzGraph.__repr__cCs,||jkrdS||jkr(gg|f|j|<dS)zê
        Adds a new node to the graph.  Arbitrary data can be attached to the
        node via the node_data parameter.  Adding the same node twice will be
        silently ignored.
 
        The node must be a hashable value.
        N)r r)rÚnodeÚ    node_datarrrÚadd_nodeCs
 
zGraph.add_nodeéTcCs’|j}|r| |¡| |¡z,|j|d |¡|j|d |¡Wn$tk
rntd||fƒ‚YnX|||f|j|<|jd7_dS)aÈ
        Adds a directed edge going from head_id to tail_id.
        Arbitrary data can be attached to the edge via edge_data.
        It may create the nodes if adding edges between nonexisting ones.
 
        :param head_id: head node
        :param tail_id: tail node
        :param edge_data: (optional) data attached to the edge
        :param create_nodes: (optional) creates the head_id or tail_id
            node in case they did not exist
        rrzInvalid nodes %s -> %sN)rrrÚappendÚKeyErrorrr    )rÚhead_idÚtail_idÚ    edge_dataZ create_nodesÚedgerrrr Ys 
 
zGraph.add_edgecCstzN|j|\}}}|j|<|j|d |¡|j|d |¡|j|=Wn tk
rntd|ƒ‚YnXdS)zd
        Hides an edge from the graph. The edge may be unhidden at some later
        time.
        rrúInvalid edge %sN)r    r
rÚremoverr)rr#r r!r"rrrÚ    hide_edge|s zGraph.hide_edgecCsdz>| |¡}|j||f|j|<|D]}| |¡q$|j|=Wn tk
r^td|ƒ‚YnXdS)z¦
        Hides a node from the graph.  The incoming and outgoing edges of the
        node will also be hidden.  The node may be unhidden at some later time.
        úInvalid node %sN)Ú    all_edgesrr r&rr©rrr(r#rrrÚ    hide_node‰s
  zGraph.hide_nodecCsZz4|j|\|j|<}|D]}| |¡q|j|=Wn tk
rTtd|ƒ‚YnXdS)z„
        Restores a previously hidden node back into the graph and restores
        all of its incoming and outgoing edges.
        r'N)r rÚ restore_edgerrr)rrrÚ restore_node—s  zGraph.restore_nodecCszzT|j|\}}}|j|d |¡|j|d |¡|||f|j|<|j|=Wn tk
rttd|ƒ‚YnXdS)zH
        Restores a previously hidden edge back into the graph.
        rrr$N)r
rrr    rr)rr#r r!rrrrr+¤s zGraph.restore_edgec    Cs<t|j ¡ƒD](}z| |¡Wqtk
r4YqXqdS)z,
        Restores all hidden edges.
        N)Úlistr
Úkeysr+r©rr#rrrÚrestore_all_edges±s
zGraph.restore_all_edgescCs"t|j ¡ƒD]}| |¡qdS)z,
        Restores all hidden nodes.
        N)r-r r.r,©rrrrrÚrestore_all_nodes»szGraph.restore_all_nodescCs
||jkS)z5
        Test whether a node is in the graph
        ©rr1rrrÚ __contains__ÂszGraph.__contains__cCsFz|j|\}}}Wn(tk
r<d\}}td|ƒ‚YnX||fS)úN
        Returns the edge that connects the head_id and tail_id nodes
        )NNr$)r    rr©rr#rrrrrrÚ
edge_by_idÈs zGraph.edge_by_idcCs*| |¡D]}| |¡|kr
|Sq
dS)r5N)Ú    out_edgesr)rrrr#rrrÚ edge_by_nodeÔs
zGraph.edge_by_nodecCs
t|jƒS)z-
        Returns the number of nodes
        )r rrrrrrÝszGraph.number_of_nodescCs
t|jƒS)z-
        Returns the number of edges
        )r r    rrrrrãszGraph.number_of_edgescCs
t|jƒS)z6
        Iterates over all nodes in the graph
        )ÚiterrrrrrÚ__iter__észGraph.__iter__cCst|j ¡ƒS)zS
        Return a list of the node ids for all visible nodes in the graph.
        )r-rr.rrrrÚ    node_listïszGraph.node_listcCst|j ¡ƒS)zI
        Returns an iterator for all visible nodes in the graph.
        )r-r    r.rrrrÚ    edge_listõszGraph.edge_listcCs
t|jƒS)z4
        Returns the number of hidden edges
        )r r
rrrrÚnumber_of_hidden_edgesûszGraph.number_of_hidden_edgescCs
t|jƒS)z4
        Returns the number of hidden nodes
        )r r rrrrÚnumber_of_hidden_nodesszGraph.number_of_hidden_nodescCst|j ¡ƒS)z8
        Returns the list with the hidden nodes
        )r-r r.rrrrÚhidden_node_listszGraph.hidden_node_listcCst|j ¡ƒS)z6
        Returns a list with the hidden edges
        )r-r
r.rrrrÚhidden_edge_list szGraph.hidden_edge_listcCs|j|\}}}||||fS)zQ
        return node, node data, outgoing edges, incoming edges for node
        r3)rrÚincomingÚoutgoingrrrrÚ describe_nodeszGraph.describe_nodecCs|j|\}}}||||fS)z=
        return edge, edge data, head, tail for edge
        ©r    r6rrrÚ describe_edgeszGraph.describe_edgecCs|j|dS)z9
        Returns the data associated with a node
        rr3r1rrrr!szGraph.node_datacCs|j|dS)z:
        Returns the data associated with an edge
        rrEr/rrrr"'szGraph.edge_datacCs"|j|dd…|f|j|<dS)z;
        Replace the edge data for a specific edge
        rrNrE)rr#r"rrrÚupdate_edge_data-szGraph.update_edge_datacCs|j|dS)z;
        Returns the node of the head of the edge.
        rrEr/rrrr3sz
Graph.headcCs|j|dS)z7
        Returns node of the tail of the edge.
        rrEr/rrrr9sz
Graph.tailcs‡fdd„ˆ |¡DƒS)z;
        List of nodes connected by outgoing edges
        csg|]}ˆ |¡‘qSr)r©Ú.0ÚnrrrÚ
<listcomp>Csz"Graph.out_nbrs.<locals>.<listcomp>)r8r1rrrÚout_nbrs?szGraph.out_nbrscs‡fdd„ˆ |¡DƒS)z;
        List of nodes connected by incoming edges
        csg|]}ˆ |¡‘qSr)rrHrrrrKIsz"Graph.inc_nbrs.<locals>.<listcomp>)Ú    inc_edgesr1rrrÚinc_nbrsEszGraph.inc_nbrscCstt | |¡| |¡¡ƒS)zH
        List of nodes connected by incoming and outgoing edges
        )r-ÚdictÚfromkeysrNrLr1rrrÚall_nbrsKszGraph.all_nbrscCs:zt|j|dƒWStk
r4td|ƒ‚YnXdS)z6
        Returns a list of the outgoing edges
        rr'N©r-rrrr1rrrr8QszGraph.out_edgescCs:zt|j|dƒWStk
r4td|ƒ‚YnXdS)z6
        Returns a list of the incoming edges
        rr'NrRr1rrrrMZszGraph.inc_edgescCst| |¡| |¡ƒS)z?
        Returns a list of incoming and outging edges.
        )ÚsetrMr8r1rrrr(cszGraph.all_edgescCst| |¡ƒS)z6
        Returns the number of outgoing edges
        )r r8r1rrrÚ
out_degreeiszGraph.out_degreecCst| |¡ƒS)z6
        Returns the number of incoming edges
        )r rMr1rrrÚ
inc_degreeoszGraph.inc_degreecCs| |¡| |¡S)z,
        The total degree of a node
        )rUrTr1rrrÚ
all_degreeuszGraph.all_degreecCsèg}tƒ}i}|r&|j}|j}|j}n|j}|j}|j}| ¡D]$}||ƒ}    |    rZ|    ||<q@| |¡q@|rÂ|     ¡}
| |
¡||
ƒD]:} || ƒ} | |kr„|| d8<|| dkr„| | ¡q„qft
|ƒt
| ¡ƒkrÜd} nd} | |fS)zì
        Topological sort.
 
        Returns a list of nodes where the successors (based on outgoing and
        incoming edges selected by the forward parameter) of any given node
        appear in the sequence after that node.
        rrTF) rr8rUrrMrTrr<rÚpopleftr )rÚforwardZ    topo_listÚqueueZindegÚ    get_edgesZ
get_degreeÚget_nextrZdegreeÚ    curr_noder#r!ZvalidrrrÚ
_topo_sort{s8 
 
  zGraph._topo_sortcCs |jddS)zµ
        Topological sort.
 
        Returns a list of nodes where the successors (based on outgoing edges)
        of any given node appear in the sequence after that node.
        T©rX©r]rrrrÚforw_topo_sortªszGraph.forw_topo_sortcCs |jddS)z½
        Reverse topological sort.
 
        Returns a list of nodes where the successors (based on incoming edges)
        of any given node appear in the sequence after that node.
        Fr^r_rrrrÚback_topo_sort³szGraph.back_topo_sortc    Csz|r|j}|j}n |j}|j}tƒ}||ƒ}|D]}| |¡q0|D]0}||ƒD]"}|rf| ||¡qP| ||¡qPqD|S)z£
        Private method creates a subgraph in a bfs order.
 
        The forward parameter specifies whether it is a forward or backward
        traversal.
        )Úforw_bfsrLÚback_bfsrNrrr )    rÚstart_idrXZget_bfsZget_nbrsÚgÚbfs_listrZnbr_idrrrÚ _bfs_subgraph¼s  zGraph._bfs_subgraphcCs|j|ddS)z‡
        Creates and returns a subgraph consisting of the breadth first
        reachable nodes based on their outgoing edges.
        Tr^©rg©rrdrrrÚforw_bfs_subgraphØszGraph.forw_bfs_subgraphcCs|j|ddS)z…
        Creates and returns a subgraph consisting of the breadth first
        reachable nodes based on the incoming edges.
        Fr^rhrirrrÚback_bfs_subgraphßszGraph.back_bfs_subgraphc csˆ|ht|gƒ}}|r$|j}|j}n |j}|j}|r„| ¡}|V||krLq„t||ƒƒD](}    ||    ƒ}
|
|krX| |
¡| |
¡qXq0dS)z¡
        Collecting nodes in some depth first traversal.
 
        The forward parameter specifies whether it is a forward or backward
        traversal.
        N)    rr8rrMrÚpopÚsortedÚaddr) rÚstartÚendrXÚvisitedÚstackrZr[r\r#rrrrÚiterdfsæs 
z Graph.iterdfsccs¬|ht|gƒ}}|r$|j}|j}n |j}|j}|j}    |r¨| ¡}
|    |
ƒ} | dk    rj|dk    rd|| ƒsdq6| V|
|krtq¨||
ƒD](} || ƒ} | |kr|| | ¡| | ¡q|q6dS)zÛ
        Perform a depth-first walk of the graph (as ``iterdfs``)
        and yield the item data of every node where condition matches. The
        condition callback is only called when node_data is not None.
        N)    rr8rrMrrrlrnr)rrorprXÚ    conditionrqrrrZr[Úget_datar\Z    curr_datar#rrrrÚiterdatas* 
zGraph.iterdatac cs˜t|dfgƒ|h}}|r(|j}|j}n |j}|j}|r”| ¡\}}    ||    fV||krXq”||ƒD]0}
||
ƒ} | |kr`| | ¡| | |    df¡q`q4dS)zÒ
        The forward parameter specifies whether it is a forward or backward
        traversal.  Returns a list of tuples where the first value is the hop
        value the second value is the node id.
        rrN)rr8rrMrrWrnr) rrorprXrYrqrZr[r\Z    curr_stepr#rrrrÚ_iterbfs"s  
 
zGraph._iterbfscCsdd„|j||ddDƒS)zª
        Returns a list of nodes in some forward BFS order.
 
        Starting from the start node the breadth first search proceeds along
        outgoing edges.
        cSsg|] \}}|‘qSrr)rIrÚsteprrrrKDsz"Graph.forw_bfs.<locals>.<listcomp>Tr^©rw©rrorprrrrb=szGraph.forw_bfscCsdd„|j||ddDƒS)z«
        Returns a list of nodes in some backward BFS order.
 
        Starting from the start node the breadth first search proceeds along
        incoming edges.
        cSsg|] \}}|‘qSrr)rIrÚ_rrrrKMsz"Graph.back_bfs.<locals>.<listcomp>Fr^ryrzrrrrcFszGraph.back_bfscCst|j||ddƒS)z¨
        Returns a list of nodes in some forward DFS order.
 
        Starting with the start node the depth first search proceeds along
        outgoing edges.
        Tr^©r-rsrzrrrÚforw_dfsOszGraph.forw_dfscCst|j||ddƒS)z©
        Returns a list of nodes in some backward DFS order.
 
        Starting from the start node the depth first search proceeds along
        incoming edges.
        Fr^r|rzrrrÚback_dfsXszGraph.back_dfscCs6| ¡}|D]$}| |¡}t|ƒt|ƒkr dSq dS)zq
        Returns :py:data:`True` if the graph's every node can be reached from
        every other node.
        FT)r<rbr )rr<rrfrrrÚ    connectedas 
zGraph.connectedcCsˆd}t| |¡ƒ}||kr$| |¡|D]4}t| |¡ƒ}||krL| |¡|t||@ƒ7}q(t|ƒ}|r€t|ƒ||d}nd}|S)a–
        Computes and returns the local clustering coefficient of node.
 
        The local cluster coefficient is proportion of the actual number of
        edges between neighbours of node and the maximum number of edges
        between those neighbours.
 
        See "Local Clustering Coefficient" on
        <http://en.wikipedia.org/wiki/Clustering_coefficient>
        for a formal definition.
        rrg)rSrLr%r Úfloat)rrÚnumZnbr_setZnbrZsec_setZnbr_numÚ
clust_coefrrrr‚ms 
 
zGraph.clust_coefcCs0|rt|j||ddƒSt|j||ddƒSdS)a$
        Computes the hop distance to all nodes centered around a node.
 
        First order neighbours are at hop 1, their neigbours are at hop 2 etc.
        Uses :py:meth:`forw_bfs` or :py:meth:`back_bfs` depending on the value
        of the forward parameter.  If the distance between all neighbouring
        nodes is 1 the hop number corresponds to the shortest distance between
        the nodes.
 
        :param start: the starting node
        :param end: ending node (optional). When not specified will search the
            whole graph.
        :param forward: directionality parameter (optional).
            If C{True} (default) it uses L{forw_bfs} otherwise L{back_bfs}.
        :return: returns a list of tuples where each tuple contains the
            node and the hop.
 
        Typical usage::
 
            >>> print (graph.get_hops(1, 8))
            >>> [(1, 0), (2, 1), (3, 1), (4, 2), (5, 3), (7, 4), (8, 5)]
            # node 1 is at 0 hops
            # node 2 is at 1 hop
            # ...
            # node 8 is at 5 hops
        T)rorprXFN)r-rw)rrorprXrrrÚget_hopsŒszGraph.get_hops)N)N)rT)T)T)NT)NTN)NT)N)N)N)N)NT):Ú__name__Ú
__module__Ú __qualname__Ú__doc__rrrr r&r*r,r+r0r2r4r7r9rrr;r<r=r>r?r@rArDrFrr"rGrrrLrNrQr8rMr(rTrUrVr]r`rargrjrkrsrvrwrbrcr}r~rr‚rƒrrrrrsn
 
 
#   
             
/        
 
 
!
 
    
    
    
     rN)r‡Ú collectionsrZaltgraphrÚobjectrrrrrÚ<module>s