Modifying networks the immutable way¶
All Reticula networks are immutable. Instead of changing a graph in place,
operations like adding or removing edges return a new object. This tutorial
demonstrates the basic with_*
and without_*
functions.
Adding edges¶
Start with a simple cycle and add a few new links:
>>> import reticula as ret
>>> g = ret.cycle_graph[ret.int64](size=8)
>>> extra = [(0, 5), (1, 6)]
>>> g2 = ret.with_edges(g, extra)
>>> len(g.edges()), len(g2.edges())
(8, 10)
Because g
is unchanged we can safely reuse it elsewhere.
Removing vertices¶
Vertices can be removed in a similar fashion:
>>> g3 = ret.without_vertices(g2, [0, 1])
>>> len(g3.vertices())
6
Any edges incident to the removed vertices disappear automatically.
Adding and removing multiple items at once is more efficient than repeatedly calling these functions in a loop, so try to batch your operations when possible.
Induced subgraphs¶
A subset of a network can be created by selecting a set of vertices or edges,
using vertex_induced_subgraph()
or edge_induced_subgraph()
.
For example, to create a subgraph of the first five vertices:
>>> g4 = ret.vertex_induced_subgraph(g, [0, 1, 2, 3, 4])
>>> len(g4.vertices()), len(g4.edges())
(5, 4)
Vertex and edge occupation¶
Another way to create a subset of the network is to prbabilistically keep a fraction of the vertices or edges. This is useful for sampling large networks. Inspired by the percolation literature, Reticula calls this process occupation.
Vertex or edge occupation is done with a uniform probability, using uniformly_occupy_edges()
and uniformly_occupy_edges()
:
>>> gen = ret.mersenne_twister(42)
>>> g5 = ret.uniformly_occupy_vertices(
... g, occupation_prob=0.5, random_state=gen)
>>> g5
<undirected_network[int64] with 5 verts and 2 edges>
Similarly, the probability of keeping edges can be determined using a lambda function. Here for example we set the odd vertices to be kept (occupied) at a higher probability:
>>> gen = ret.mersenne_twister(42)
>>> g6 = ret.occupy_vertices(g,
... lambda x: 0.3 if x%2 == 0 else 0.7,
... random_state=gen)
>>> g6
<undirected_network[int64] with 5 verts and 3 edges>