Search code examples
pythonnetworkxgraph-theory

Calculating non-randomness with networkx


I am attempting to calculate a graph's non-randomness using networkx.

This error appears for some graphs but not for other graphs.

~\anaconda3\lib\site-packages\networkx\algorithms\non_randomness.py
eq. 4.5

nr_rd = (nr - ((n - 2 * k) * p + k)) / math.sqrt(2 * k * p * (1 - p))

What graph characteristics result in this error?

The documentation describes two possible exceptions. Neither is this one.

Here is an example of a graph resulting in the error. The node labels (a, m, d), colors, and size are node attributes used for grouping similar nodes. Each node has a unique ID that is not shown in the graph. Example of a graph generating the error

Here is code for creating that graph and generating the error.

nodes = ['a1','a2','a3','a4','m1','m2','m3','m4','d']
edges = [('a1','m1'),('a2','m2'),('a3','m3'),('a4','m4'),('m1','d'),('m2','d'),('m3','d'),('m4','d')]

my_g = nx.Graph()

for n in nodes:
    my_g.add_node(n)

for e in edges:
    my_g.add_edge(e[0],e[1])

nx.non_randomness(my_g)

Solution

  • Interesting, I tried with the reproducible example below and it seems to work fine:

    import networkx as nx
    
    G = nx.karate_club_graph()
    nr, nr_rd = nx.non_randomness(G)
    

    This is using version 2.7.1 of networkx. Also, this function is not implemented for directed graphs or multigraphs, which might help explain why it works for some graphs and not others in your testing (but could be due to other reasons also). So one way to isolate this reason is to ensure that G satisfies this condition:

        G : NetworkX graph
            Graph must be symmetric, connected, and without self-loops.
    

    Update: given the sample graph in the question, there is indeed a problem with using the function with the default settings. However, explicitly specifying all arguments appears to resolve the issue (at least for this example):

    import networkx as nx
    
    nodes = ["a1", "a2", "a3", "a4", "m1", "m2", "m3", "m4", "d"]
    edges = [
        ("a1", "m1"),
        ("a2", "m2"),
        ("a3", "m3"),
        ("a4", "m4"),
        ("m1", "d"),
        ("m2", "d"),
        ("m3", "d"),
        ("m4", "d"),
    ]
    
    
    G = nx.Graph()
    
    for n in nodes:
        G.add_node(n)
    
    for e in edges:
        G.add_edge(e[0], e[1])
    
    print(nx.non_randomness(G, k=1, weight=None))
    # (2.2360679774997902, -0.5433972933277872)