Search code examples
pythonnetworkxgraph-theory

Creating a directed scale-free graph with row-stochastic adjacency matrix using Networkx


As part of my dissertation in the field of behavioural economics, I started to work with social networks and opinion dynamics.

For a simulation-based study, I currently require a directed scale-free network featuring a row-stochastic adjacency matrix in order to perform calculations with the Degroot opinion dynamics model. The aim is to generate a directed scale-free network in which the nodes with the highest out-degree affect many other agents within their network hub, but are influenced themselves only a bit (ingoing weights are still > 0 since I need a positive sum of the respective row in the adjacency matrix).

You can think about the network as a stylized Twitter network where you have a few strongly connected nodes affecting many other nodes, but are not themselves influenced by others.

The problem was that after normalization the network was no longer perceived as directed.In the following my code.

In a first step, I used the Networkx package to generate a scale-free graph and converted the graph object into an adjacency matrix:

G = nx.scale_free_graph(100)

nx.is_directed(G)

Output: True

Subsequently, I normalised the underlying adjacency (e.g., row-stochastic) and converted it back into a graph.

A = nx.to_numpy_array(G)

A_normalized = normalize(A, axis=1, norm='l1')

G_new = nx.from_numpy_matrix(A_normalized)

nx.is_directed(G_new)

Output: False

Can someone explain to me why this is the case or what I can change to make my normalised network count as directed again?


Solution

  • The directed scale-free network is a MultiDiGraph. All you need to do is using the create_using parameter when creating the new graph from the numpy array:

    import networkx as nx
    
    G = nx.scale_free_graph(100)
    A = nx.to_numpy_array(G)
    A_normalized = normalize(A, axis=1, norm='l1')
    G_new = nx.from_numpy_array(A_normalized, create_using=nx.MultiDiGraph)