6. Erdos-Renyi random networks#

import random

import networkx as nx
import numpy as np
import seaborn as sb
import matplotlib.pyplot as plt

sb.set_theme(style="ticks", context="notebook")
random.random()
0.6529223135709693

6.1. Write a random graph generator#

def random_graph(N, p):
    
    G = nx.Graph()
    nodes = range(N)
    G.add_nodes(N)
    
    for i in nodes:
        for j in nodes[:i]:
            if random.random <= p:
                G.add_edge((i, j))
                
    return G
def random_graph(N, p):

    G = nx.Graph()

    nodes = range(N)
    G.add_nodes_from(nodes)

    edges = []

    for i in nodes:
        for j in nodes[:i]:
            if random.random() < p:
                edges.append([i, j])

    G.add_edges_from(edges)

    return G
G = random_graph(N=10, p=0.1)
print(G)

fig, ax = plt.subplots(figsize=(3, 3))
nx.draw(G, node_size=15)
Graph with 10 nodes and 3 edges
../_images/760c57f43d5a5fd690a4b5d59154ec40943993274a20b84516ccf77bbff73ef6.png
N = 100
p = 0.8 / N
G = random_graph(N, p)
np.log(N)
4.605170185988092
params = {
    "node_size": 10,
    "with_labels": False,
    "edge_color": "silver",
    "node_color": "b",
}

nx.draw_networkx(G, **params)

sb.despine(bottom=True, left=True)

plt.show()
../_images/4bfa83e500337be91072abef61d9c263327c72d4fffc1bafe516f0fda5b4e183.png

6.2. Analyse characteristics#

N = 1000
p = 5 / N

G = nx.erdos_renyi_graph(N, p, seed=1)
params = {
    "node_size": 10,
    "with_labels": False,
    "edge_color": "silver",
    "node_color": "b",
}

pos = nx.spring_layout(G)

nx.draw_networkx(G, pos=pos, **params)

# identify largest connected component
Gcc = sorted(nx.connected_components(G), key=len, reverse=True)
G0 = G.subgraph(Gcc[0])
# highlight largest connected component
nx.draw_networkx_edges(G0, pos=pos, width=3.0, edge_color="r")

# draw other connected components
for Gi in Gcc[1:]:
    if len(Gi) > 1:
        nx.draw_networkx_edges(
            G.subgraph(Gi), pos, alpha=0.4, width=3.0, edge_color="r"
        )


sb.despine(bottom=True, left=True)
/var/folders/wm/5gv37br900l73y63tjf8sr1r0000gn/T/ipykernel_7931/3661388696.py:21: DeprecationWarning: `alltrue` is deprecated as of NumPy 1.25.0, and will be removed in NumPy 2.0. Please use `all` instead.
  nx.draw_networkx_edges(
../_images/73c2ba8274e6875f6e16e751b2a1b259c3e5cf04b7b6b1c338977278f1da2a3a.png
print(f"Connected: {nx.is_connected(G)}")
print(f"# connected components: {len(list(nx.connected_components(G)))}")

print()
print(f"Size of largest connected component: {len(G0)}")
print(f"Prop. of nodes in it: {len(G0) / N:.2f}")

print()
degree_sequence = sorted((d for n, d in G.degree()), reverse=True)
print(f"Average degree: {np.average(degree_sequence)}")
print(f"Clustering coefficient: {nx.average_clustering(G)}")
Connected: False
# connected components: 11

Size of largest connected component: 989
Prop. of nodes in it: 0.99

Average degree: 5.0
Clustering coefficient: 0.005966788766788765
deg, counts = np.unique(degree_sequence, return_counts=True)

fig, ax = plt.subplots()

ax.plot(deg, counts)

ax.axvline(np.average(degree_sequence), ls="--", c="grey", zorder=-1)

ax.set_xlabel("$k$")
ax.set_ylabel("$P(k)$")
#plt.yscale("log")
#plt.xscale("log")

sb.despine()
../_images/4da10ed9f2228c1c0fb13312718c5aad99b8ce5091a79da75792a8a2a17898f7.png

6.3. Vary the degree k#

N = 1000

ks = np.
N = 1000

ks = np.arange(0, 5.1, 0.1)

ps = ks / (N - 1)

n_reps = 10

props_arr = np.zeros((len(ps), n_reps))

for i, p in enumerate(ps):
    for rep in range(n_reps):
        G = nx.erdos_renyi_graph(N, p)

        Gcc = sorted(nx.connected_components(G), key=len, reverse=True)
        G0 = G.subgraph(Gcc[0])

        prop = len(G0) / N
        props_arr[i, rep] = prop
fig, ax = plt.subplots()

ax.plot(ks, props_arr[:, :], "-o", alpha=0.3)

ax.plot(ks, np.average(props_arr, axis=1), "k-", lw=3)

ax.set_ylabel("Proportion of nodes in G0")
ax.set_xlabel(r"$< k >$")

sb.despine()
../_images/d1433996051044fc264e0114855975eab50953af029a6322e16f7877fa813459.png

6.4. Configuration model#

N = 20
p = 6 / N
G = random_graph(N, p)
degree_sequence = [d for n, d in G.degree()]
degree_sequence
[7, 4, 4, 7, 1, 4, 5, 2, 6, 5, 9, 7, 9, 3, 5, 5, 6, 5, 5, 3]
deg, counts = np.unique(degree_sequence, return_counts=True)

fig, ax = plt.subplots()
ax.plot(deg, counts / N)
ax.axvline(np.average(degree_sequence), ls="--", c="grey", zorder=-1)

ax.set_xlabel("$k$")
ax.set_ylabel("$P(k)$")
plt.yscale("log")
plt.xscale("log")

sb.despine()
../_images/499a2c97eaec65995aa5bbb71936b0dd9189eecfadd5cc032427ee33bec811a5.png
G_conf = nx.configuration_model(degree_sequence)
print(G_conf)
MultiGraph with 20 nodes and 51 edges
G_conf = nx.Graph(G_conf)
print(G_conf)
Graph with 20 nodes and 48 edges
degree_sequence_conf = [d for n, d in G_conf.degree()]
print(G)
Graph with 20 nodes and 51 edges
print(G_conf)
Graph with 20 nodes and 48 edges
deg_conf, counts_conf = np.unique(degree_sequence_conf, return_counts=True)

fig, ax = plt.subplots()
ax.plot(degree_sequence, "o-", ms=10, label="original")
ax.plot(degree_sequence_conf, "o-", label="config")

ax.set_xlabel("Node index")
ax.set_ylabel("Degree")
# plt.yscale("log")
# plt.xscale("log")

ax.set_xticks(range(len(G)))

ax.legend()

sb.despine()
../_images/456be17cf9fa9581a4f3bc29a1cf10048294c0cd473cc81405d24ca7c5932c72.png
print(G)
print(G_conf)
Graph with 20 nodes and 51 edges
Graph with 20 nodes and 48 edges
pos = nx.spring_layout(G)
pos = nx.spring_layout(G, seed=1)
nx.draw_networkx(G, pos=pos, node_color="lightgrey")
../_images/5848b1985bf068f17742c3555b99645136cce42c6e22d79a1224f9c8e475daab.png
nx.draw_networkx(G_conf, node_color="lightgrey")
../_images/eda23b51393057d5c00a633e73e73e4d7078b23613dfde26f67f124e5378a9ea.png
list(nx.selfloop_edges(G_conf))
[(8, 8), (15, 15)]
print(G_conf)
Graph with 20 nodes and 48 edges
edges_to_remove = list(nx.selfloop_edges(G_conf))
edges_to_remove
[(8, 8), (15, 15)]
G_conf.remove_edges_from(edges_to_remove)
print(G_conf)
Graph with 20 nodes and 46 edges
edges_to_remove
[(12, 12)]
nx.draw_networkx(G_conf, node_color="lightgrey")
../_images/6c41dca4164923b17b2d03f580213c92a41067d11109e6cf0d9b88f6ed04f595.png