-
Notifications
You must be signed in to change notification settings - Fork 266
Expand file tree
/
Copy pathbasic.py
More file actions
186 lines (153 loc) · 6.89 KB
/
basic.py
File metadata and controls
186 lines (153 loc) · 6.89 KB
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
from igraph._igraph import GraphBase
from igraph.seq import EdgeSeq
from igraph.utils import deprecated
def _add_edge(graph, source, target, **kwds):
"""Adds a single edge to the graph.
Keyword arguments (except the source and target arguments) will be
assigned to the edge as attributes.
The performance cost of adding a single edge or several edges
to a graph is similar. Thus, when adding several edges, a single
C{add_edges()} call is more efficient than multiple C{add_edge()} calls.
@param source: the source vertex of the edge or its name.
@param target: the target vertex of the edge or its name.
@return: the newly added edge as an L{Edge} object. Use
C{add_edges([(source, target)])} if you don't need the L{Edge}
object and want to avoid the overhead of creating it.
"""
eid = graph.ecount()
graph.add_edges([(source, target)])
edge = graph.es[eid]
for key, value in kwds.items():
edge[key] = value
return edge
def _add_edges(graph, es, attributes=None):
"""Adds some edges to the graph.
@param es: the list of edges to be added. Every edge is represented
with a tuple containing the vertex IDs or names of the two
endpoints. Vertices are enumerated from zero.
@param attributes: dict of sequences, each of length equal to the
number of edges to be added, containing the attributes of the new
edges.
"""
eid = graph.ecount()
res = GraphBase.add_edges(graph, es)
n = graph.ecount() - eid
if (attributes is not None) and (n > 0):
for key, val in attributes.items():
graph.es[eid:][key] = val
return res
def _add_vertex(graph, name=None, **kwds):
"""Adds a single vertex to the graph. Keyword arguments will be assigned
as vertex attributes. Note that C{name} as a keyword argument is treated
specially; if a graph has C{name} as a vertex attribute, it allows one
to refer to vertices by their names in most places where igraph expects
a vertex ID.
@return: the newly added vertex as a L{Vertex} object. Use
C{add_vertices(1)} if you don't need the L{Vertex} object and want
to avoid the overhead of creating t.
"""
if isinstance(name, int):
# raise TypeError("cannot use integers as vertex names; use strings instead")
deprecated(
"You are using integers as vertex names. This is discouraged because "
"most igraph functions interpret integers as vertex _IDs_ and strings "
"as vertex names. For sake of consistency, convert your vertex "
"names to strings before assigning them. Future versions from igraph "
"0.11.0 will disallow integers as vertex names."
)
vid = graph.vcount()
graph.add_vertices(1)
vertex = graph.vs[vid]
for key, value in kwds.items():
vertex[key] = value
if name is not None:
vertex["name"] = name
return vertex
def _add_vertices(graph, n, attributes=None):
"""Adds some vertices to the graph.
Note that if C{n} is a sequence of strings, indicating the names of the
new vertices, and attributes has a key C{name}, the two conflict. In
that case the attribute will be applied.
@param n: the number of vertices to be added, or the name of a single
vertex to be added, or a sequence of strings, each corresponding to the
name of a vertex to be added. Names will be assigned to the C{name}
vertex attribute.
@param attributes: dict of sequences, each of length equal to the
number of vertices to be added, containing the attributes of the new
vertices. If n is a string (so a single vertex is added), then the
values of this dict are the attributes themselves, but if n=1 then
they have to be lists of length 1.
"""
if isinstance(n, str):
# Adding a single vertex with a name
m = graph.vcount()
result = GraphBase.add_vertices(graph, 1)
graph.vs[m]["name"] = n
if attributes is not None:
for key, val in attributes.items():
graph.vs[m][key] = val
elif hasattr(n, "__iter__"):
m = graph.vcount()
if not hasattr(n, "__len__"):
names = list(n)
else:
names = n
result = GraphBase.add_vertices(graph, len(names))
if len(names) > 0:
graph.vs[m:]["name"] = names
if attributes is not None:
for key, val in attributes.items():
graph.vs[m:][key] = val
else:
result = GraphBase.add_vertices(graph, n)
if (attributes is not None) and (n > 0):
m = graph.vcount() - n
for key, val in attributes.items():
graph.vs[m:][key] = val
return result
def _delete_edges(graph, *args, **kwds):
"""Deletes some edges from the graph.
The set of edges to be deleted is determined by the positional and
keyword arguments. If the function is called without any arguments,
all edges are deleted. If any keyword argument is present, or the
first positional argument is callable, an edge sequence is derived by
calling L{EdgeSeq.select} with the same positional and keyword
arguments. Edges in the derived edge sequence will be removed.
Otherwise, the first positional argument is considered as follows:
Deprecation notice: C{delete_edges(None)} has been replaced by
C{delete_edges()} - with no arguments - since igraph 0.8.3.
- C{None} - deletes all edges (deprecated since 0.8.3)
- a single integer - deletes the edge with the given ID
- a list of integers - deletes the edges denoted by the given IDs
- a list of 2-tuples - deletes the edges denoted by the given
source-target vertex pairs. When multiple edges are present
between a given source-target vertex pair, only one is removed.
"""
if len(args) == 0 and len(kwds) == 0:
return GraphBase.delete_edges(graph)
if len(kwds) > 0 or (callable(args[0]) and not isinstance(args[0], EdgeSeq)):
edge_seq = graph.es(*args, **kwds)
else:
edge_seq = args[0]
return GraphBase.delete_edges(graph, edge_seq)
def _clear(graph):
"""Clears the graph, deleting all vertices, edges, and attributes.
@see: L{GraphBase.delete_vertices} and L{Graph.delete_edges}.
"""
graph.delete_vertices()
for attr in graph.attributes():
del graph[attr]
def _as_directed(graph, *args, **kwds):
"""Returns a directed copy of this graph. Arguments are passed on
to L{GraphBase.to_directed()} that is invoked on the copy.
"""
copy = graph.copy()
copy.to_directed(*args, **kwds)
return copy
def _as_undirected(graph, *args, **kwds):
"""Returns an undirected copy of this graph. Arguments are passed on
to L{GraphBase.to_undirected()} that is invoked on the copy.
"""
copy = graph.copy()
copy.to_undirected(*args, **kwds)
return copy