Skip to content

directed_edge_swap: ZeroDivisionError when passing a digraph without edges #6144

@paulitapb

Description

@paulitapb

I was working on improving test coverage for swap.py and tested directed_edge_swap with a digraph without edges. That resulted in a ZeroDivisionError from nx.utils.cumulative_distribution.

Steps to Reproduce

from networkx as nx

G = nx.DiGraph()
G.add_nodes_from([0, 2, 4, 3])

G = nx.directed_edge_swap(G, nswap=1, max_tries=500, seed=1)

Current Behavior

ZeroDivisionError is raised because in nx.utils.cumulative_distribution there's a division by the sum of the input distribution that is zero. The distribution that nx.utils.cumulative_distribution is called with in this example is the degrees of a digraph without edges (all degrees are zero). This is the error log.

Traceback (most recent call last):
  File "test.py", line 12, in <module>
    G = nx.directed_edge_swap(G, nswap=1, max_tries=500, seed=1)
  File "/home/paula/Outreachy/networkX/networkx/networkx/utils/decorators.py", line 766, in func
    return argmap._lazy_compile(__wrapper)(*args, **kwargs)
  File "<class 'networkx.utils.decorators.argmap'> compilation 21", line 5, in argmap_directed_edge_swap_17
  File "/home/paula/Outreachy/networkX/networkx/networkx/algorithms/swap.py", line 81, in directed_edge_swap
    cdf = nx.utils.cumulative_distribution(degrees)  # cdf of degree
  File "/home/paula/Outreachy/networkX/networkx/networkx/utils/random_sequence.py", line 103, in cumulative_distribution
    cdf.append(cdf[i] + distribution[i] / psum)
ZeroDivisionError: division by zero

Expected Behavior

I think the best is to raise an exception in directed_edge_swap with a message that exposes this situation. Also, this should be added to the doc entry.

Environment

Python version: 3.8
NetworkX version: 2.8.7

Further Discoveries

Something else that should be added is that if the digraph has less than 3 edges then is impossible to swap edges. In that case, the current behavior is that the max number of tries is reached. In my opinion, this case should raise an exception with an appropriate message. Also, this could be mentioned in the doc entry.

I will work on these changes and will look closely at the other functions in swap.py.
Also, I think it will be good to review the functions that use nx.utils.cumulative_distribution to check for this error. I can do that too.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions