Physik der sozio-ökonomischen Systeme mit dem Computer¶

(Physics of Socio-Economic Systems with the Computer)¶

Vorlesung gehalten an der J.W.Goethe-Universität in Frankfurt am Main¶

(Sommersemester 2024)¶

von Dr.phil.nat. Dr.rer.pol. Matthias Hanauske¶

Frankfurt am Main 21.06.2024¶

Aufgabe 15

Aufgabe 15.1.

Erzeugen Sie mittels des Graphengenerators 'barabasi_albert_graph(...)' von NetworkX ein skalenfreies Netzwerk mit $N = 100$ Knoten ('barabasi_albert_graph(100,1)') und $N = 1000$ Knoten ('barabasi_albert_graph(1000,1)').

a)

Stellen Sie das skalenfreie Netzwerk mittels NetworkX für $N = 100$ (mit Kennzeichnung der Knotennummern) und $N = 1000$ (ohne Kennzeichnung der Knotennummern) im 'shell_layout', 'fruchterman_reingold_layout' und 'kamada_kawai_layout' dar.

b)

Erstellen Sie, für die beiden in Aufgabe 15.1. erzeugten Netzwerke, ein Diagramm (Scatter-Plot: plt.scatter(...)), welches den Knotengrad $k$ in Abhängigkeit von der Knotennummer darstellt. Welche Eigenschaft von skalenfreien Netzwerken kann man mittels dieser Abbildung deutlich erkennen?

Aufgabe 15.2.

Erstellen Sie ein skalenfreies Netzwerk mit $N = 300000$ Knoten ('barabasi_albert_graph(300000,1)'). Zeigen Sie, dass die Verteilungsfunktion der Knotengrade für skalenfreie Netzwerke dem folgenden analytischen Zusammenhang folgt: $P(k) \sim k^{- \gamma} \quad, \,\, \gamma \in [2,3]$ Stellen Sie dazu $\hbox{ln} \!\left( P(k) \right)$ in Abhängigkeit von $\hbox{ln} \!\left( k \right)$ in einem Scatter-Plot dar und überprüfen Sie den analytischen Zusammenhang mittels einer linearen Regression (z.B. mittels der Funktion polyfit(...) des 'NumPy' Moduls). Welchen Wert von $\gamma$ erhalten Sie?

Musterlösung Aufgabe 15¶

Musterlösung Aufgabe 15.1.a) (N=100)¶

In [1]:
import networkx as nx
from random import randint
import numpy as np
In [3]:
N = 100
G = nx.barabasi_albert_graph(N,1)
print("Anzahl der Knoten: " + str(len(G.nodes)))
print("Anzahl der Kanten: " + str(len(G.edges)))
Anzahl der Knoten: 100
Anzahl der Kanten: 99
In [4]:
import matplotlib.pyplot as plt 
import matplotlib

params = {
    'figure.figsize'    : [12,8],
    'axes.titlesize' : 14,
    'axes.labelsize' : 16,  
    'xtick.labelsize' : 14 ,
    'ytick.labelsize' : 14 
}
matplotlib.rcParams.update(params) 
In [5]:
pos = nx.shell_layout(G)
In [6]:
#Erzeugung des Netzwerk-Bildes  
node_size = 150
node_alpha = 0.3
node_color = "red"
edge_tickness = 0.4
edge_alpha = 0.7
edge_color = "blue"
node_text_size = 9
text_font = "sans-serif"
nx.draw_networkx_nodes(G,pos,node_size=node_size,alpha=node_alpha, node_color=node_color)
nx.draw_networkx_edges(G,pos,width=edge_tickness, alpha=edge_alpha,edge_color=edge_color)
nx.draw_networkx_labels(G,pos,font_size=node_text_size,font_family=text_font);
No description has been provided for this image
In [7]:
pos = nx.fruchterman_reingold_layout(G)
nx.draw_networkx_nodes(G,pos,node_size=node_size,alpha=node_alpha, node_color=node_color)
nx.draw_networkx_edges(G,pos,width=edge_tickness, alpha=edge_alpha,edge_color=edge_color)
nx.draw_networkx_labels(G,pos,font_size=node_text_size,font_family=text_font);
No description has been provided for this image
In [8]:
pos = nx.kamada_kawai_layout(G)
nx.draw_networkx_nodes(G,pos,node_size=node_size,alpha=node_alpha, node_color=node_color)
nx.draw_networkx_edges(G,pos,width=edge_tickness, alpha=edge_alpha,edge_color=edge_color)
nx.draw_networkx_labels(G,pos,font_size=node_text_size,font_family=text_font);
No description has been provided for this image

Musterlösung Aufgabe 14.1.b) (N=100)¶

In [9]:
degree_sequence = np.array(G.degree)[:,1]
plt.ylabel('Knotengrad k')
plt.xlabel('Knotennummer')
plt.scatter(range(len(G.nodes)),degree_sequence,color="blue");
No description has been provided for this image

Die obere Abbildung zeigt, dass in skalenfreien Netzwerken die am Anfang erzeugten Knoten (kleine Knotennummer) im Mittel einen höheren Knotengrad besitzen.

Musterlösung Aufgabe 15.1.a) (N=1000)¶

In [10]:
N = 1000
G = nx.barabasi_albert_graph(N,1)
print("Anzahl der Knoten: " + str(len(G.nodes)))
print("Anzahl der Kanten: " + str(len(G.edges)))
Anzahl der Knoten: 1000
Anzahl der Kanten: 999
In [11]:
node_size = 12
pos = nx.shell_layout(G)
nx.draw_networkx_nodes(G,pos,node_size=node_size,alpha=node_alpha, node_color=node_color)
nx.draw_networkx_edges(G,pos,width=edge_tickness, alpha=edge_alpha,edge_color=edge_color);
No description has been provided for this image
In [12]:
pos = nx.fruchterman_reingold_layout(G)
nx.draw_networkx_nodes(G,pos,node_size=node_size,alpha=node_alpha, node_color=node_color)
nx.draw_networkx_edges(G,pos,width=edge_tickness, alpha=edge_alpha,edge_color=edge_color);
No description has been provided for this image
In [13]:
pos = nx.kamada_kawai_layout(G)
nx.draw_networkx_nodes(G,pos,node_size=node_size,alpha=node_alpha, node_color=node_color)
nx.draw_networkx_edges(G,pos,width=edge_tickness, alpha=edge_alpha,edge_color=edge_color);
No description has been provided for this image

Musterlösung Aufgabe 15.1.b) (N=1000)¶

In [14]:
degree_sequence = np.array(G.degree)[:,1]
plt.ylabel('Knotengrad k')
plt.xlabel('Knotennummer')
plt.scatter(range(len(G.nodes)),degree_sequence,color="blue",s=1);
No description has been provided for this image

Die obere Abbildung zeigt, dass in skalenfreien Netzwerken die am Anfang erzeugten Knoten (kleine Knotennummer) im Mittel einen höheren Knotengrad besitzen.

Musterlösung Aufgabe 15.2.¶

In [31]:
N = 300000
G = nx.barabasi_albert_graph(N,1)
print("Anzahl der Knoten: " + str(len(G.nodes)))
print("Anzahl der Kanten: " + str(len(G.edges)))
Anzahl der Knoten: 300000
Anzahl der Kanten: 299999
In [32]:
degree_sequence = np.array(G.degree)[:,1]
max_k = np.max(degree_sequence)
In [33]:
plt.xlabel('Knotengrad k')
plt.ylabel(r'$\rm P(k)$')
plt.hist(degree_sequence,bins=range(1,int(max_k+2),1),density="True");
plt.xscale('log')
plt.yscale('log')
No description has been provided for this image
In [41]:
x_hist_log = []
y_hist_log = []
y_0 = []
for i in range(1,max_k+1):
    y = np.count_nonzero(degree_sequence == i)
    if y != 0:
        x_hist_log.append(np.log(i))
        y_hist_log.append(np.log(y/len(G.nodes)))
    else:
        y_0.append(i)
Lin_fit = np.polyfit(x_hist_log[0:y_0[0]],y_hist_log[0:y_0[0]],1)
In [42]:
plt.ylabel(r'$\rm ln(P(k))$')
plt.xlabel(r"$\rm ln(k)$")
plt.ylim((np.min(y_hist_log)-1, 0.1))
plt.plot(x_hist_log,Lin_fit[0]*np.array(x_hist_log) + Lin_fit[1],color="red")
plt.scatter(x_hist_log,y_hist_log,color="blue");
No description has been provided for this image
In [40]:
print("Steigung (gamma-Wert): " + str(Lin_fit[0]))
Steigung (gamma-Wert): -2.885007521514056

Die Ergebnisse der linearen Regression stimmen gut mit der analytischen Verteilungsfunktion $P(k) \sim k^{- \gamma} \quad, \,\, \gamma \in [2,3]$ überein.

$\hbox{ln} \!\left( P(k) \right) \sim - \gamma \, \cdot \, \hbox{ln} \!\left( k \right)\quad \rightarrow $ Steigung = $-\gamma$ .