ryansmcgee / seirsplus

Models of SEIRS epidemic dynamics with extensions, including network-structured populations, testing, contact tracing, and social distancing.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

'KeysView' object is returned instead of a list

tomermilo opened this issue · comments

When running this:
G_normal = custom_exponential_graph(baseGraph, scale=100)

I get the following error:

==================================================

TypeError Traceback (most recent call last)
mtrand.pyx in mtrand.RandomState.choice()

TypeError: 'KeysView' object cannot be interpreted as an integer

During handling of the above exception, another exception occurred:

ValueError Traceback (most recent call last)
in
3
4 # Baseline normal interactions:
----> 5 G_normal = custom_exponential_graph(baseGraph, scale=100)
6 plot_degree_distn(G_normal, max_degree=40)

~\Anaconda3\envs\corona\lib\site-packages\seirsplus\models.py in custom_exponential_graph(base_graph, scale, min_num_edges, m, n)
1175 neighbors = graph[node].keys()
1176 quarantineEdgeNum = int( max(min(numpy.random.exponential(scale=scale, size=1), len(neighbors)), min_num_edges) )
-> 1177 quarantineKeepNeighbors = numpy.random.choice(neighbors, size=quarantineEdgeNum, replace=False)
1178 for neighbor in neighbors:
1179 if(neighbor not in quarantineKeepNeighbors):

mtrand.pyx in mtrand.RandomState.choice()

ValueError: 'a' must be 1-dimensional or an integer

solved it by wrapping graph[node].keys() with list():
neighbors = graph[node].keys() -> neighbors = list(graph[node].keys())

Is it right?

I did the same and it solved this problem, but then I had a runtime error

RuntimeError: dictionary changed size during iteration

at the line 1177:

for neighbor in neighbors:

Any thoughts?

@kpelechrinis can you send your new custom_exponential_graph function?

@tomermilo actually the following version does not give any problem (essentially it is what you also mentioned I think) and I was able to run the example provided:

==============================================
def custom_exponential_graph(base_graph=None, scale=100, min_num_edges=0, m=9, n=None):
# Generate a random preferential attachment power law graph as a starting point.
# By the way this graph is constructed, it is expected to have 1 connected component.
# Every node is added along with m=8 edges, so the min degree is m=8.
if(base_graph):
graph = base_graph.copy()
else:
assert(n is not None), "Argument n (number of nodes) must be provided when no base graph is given."
graph = networkx.barabasi_albert_graph(n=n, m=m)

# To get a graph with power-law-esque properties but without the fixed minimum degree,
# We modify the graph by probabilistically dropping some edges from each node. 
for node in graph:
    neighbors = list(graph[node].keys())
    quarantineEdgeNum = int( max(min(numpy.random.exponential(scale=scale, size=1), len(neighbors)), min_num_edges) )
    quarantineKeepNeighbors = numpy.random.choice(neighbors, size=quarantineEdgeNum, replace=False)
    for neighbor in neighbors:
        if(neighbor not in quarantineKeepNeighbors):
            graph.remove_edge(node, neighbor)

return graph

This is how I fixed it as well. Good luck

The change to list(dict.keys()) has been made throughout the package to make this keys lookup work in both Python 2 and 3. Thank you for flagging this issue.