Dear All,
I just bumped into a MemoryError when I was debugging the following lines:
working_array_digraph=nx.DiGraph(working_array)
cycles_list = nx.simple_cycles(working_array_digraph)
where working_array is a table representing 55 nodes, i.e. an array of shape (55,55) which thus contains 3025 values.
so I think the cycles_list should be about 5*10^95 long but I might be wrong
After running for 25minutes, the last line of the code above spit out:
MemoryError: MemoryError()
I am on Linux, spider 2.1.13, python 2.7.3 32 bits and I have 6Gb of Ram in my laptop with an i5 CPU. (Actually 8Gb but the 32bits version of the OS cannot use them all).
How can I debug this more finely and are there any workarounds to be able to find all simple cycles of the array I am working with?
Thanks a lot to all!
Aleix
>>> matrix=np.ones((10,10))
>>> working_array_digraph=nx.DiGraph(matrix)
>>> cycles_list = nx.simple_cycles(working_array_digraph)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<string>", line 2, in simple_cycles
File "C:\Python27\lib\site-packages\networkx\utils\decorators.py", line 63, in _not_implemented_for
return f(*args,**kwargs)
File "C:\Python27\lib\site-packages\networkx\algorithms\cycles.py", line 205, in simple_cycles
dummy=circuit(startnode, startnode, component)
File "C:\Python27\lib\site-packages\networkx\algorithms\cycles.py", line 168, in circuit
if circuit(nextnode, startnode, component):
File "C:\Python27\lib\site-packages\networkx\algorithms\cycles.py", line 168, in circuit
if circuit(nextnode, startnode, component):
File "C:\Python27\lib\site-packages\networkx\algorithms\cycles.py", line 168, in circuit
if circuit(nextnode, startnode, component):
File "C:\Python27\lib\site-packages\networkx\algorithms\cycles.py", line 168, in circuit
if circuit(nextnode, startnode, component):
File "C:\Python27\lib\site-packages\networkx\algorithms\cycles.py", line 168, in circuit
if circuit(nextnode, startnode, component):
File "C:\Python27\lib\site-packages\networkx\algorithms\cycles.py", line 168, in circuit
if circuit(nextnode, startnode, component):
File "C:\Python27\lib\site-packages\networkx\algorithms\cycles.py", line 168, in circuit
if circuit(nextnode, startnode, component):
File "C:\Python27\lib\site-packages\networkx\algorithms\cycles.py", line 168, in circuit
if circuit(nextnode, startnode, component):
File "C:\Python27\lib\site-packages\networkx\algorithms\cycles.py", line 168, in circuit
if circuit(nextnode, startnode, component):
File "C:\Python27\lib\site-packages\networkx\algorithms\cycles.py", line 165, in circuit
result.append(path + [startnode])
MemoryError
Dear all,
I made some tests. Just a reminder that finding all simple cycles of a complete digraph is the very worst case of finding simple cycles since all simple cycles are present. The trend of number of simple cycles I found is about (nbr_nodes-1)!*3 (I know that the number of Hamiltonian cycles of a complete digraph is (nbr_nodes-1)!. The (nbr_nodes-1)!*3 number is an approximation I found after calculating the simple cycles for complete digraphs from 2 to 11 nodes.
Both simple_cycle.py and the new code suggested above (simple_cycle2.py) have similar cpu times (but I guess this is because it is the worst case for finding the simple cycles). Both manage to find the simple cycles of a complete digraph up to 11 nodes. From 12 nodes onwards, it raises a memory error.
Thus, the biggest simple cycle list that simple_cycles.py is able to calculate is for an 11 node complete digraph which contains 10 976 184 cycles.
According to the approximation of cycles described above, the list containing all simple cycles of a 12 node complete digraph contains about 120E6 cycles (of which one third are hamiltonian cycles, i.e. 12 nodes long, and the rest simple cycles of smaller length); but it seems that this is already too much for python or the module.
This is however against python's max capacity (unless my back-of-the-envelope calculation is wrong). According to http://stackoverflow.com/questions/855191/how-big-can-a-python-array-get
'''According to the source code, the maximum size of a list is PY_SSIZE_T_MAX/sizeof(PyObject*).
PY_SSIZE_T_MAX is defined in pyport.h to be ((size_t) -1)>>1
On a regular 32bit system, this is (4294967295 / 2) / 4 or 536870912.
Therefore the maximum size of a python list on a 32 bit system is 536,870,912 elements.
As long as the number of elements you have is equal or below this, all list functions should operate correctly.'''
The question is then: if the size all cycles of a 12 nodes complete digraph should be below 536E6 elements so why does simple_cycle.py run out of memory? (see below for a quick code to replicate the error)
The memory error is raised when appending to the final results list The error is:
File "/usr/lib/pymodules/python2.7/networkx/algorithms/cycles.py", line 161, in circuit
result.append(path + [startnode])
MemoryError
So how can this limitation be overcome? Would it be possible to split the results list every, say, 10 million elements (i.e. cycles)?
I will also explore the possibility of using cycle_basis, but I believe it is not the way to follow in my case. I ran the test above on a complete digraph to show the worst case. What I do in my case is to find all simple cycles between the economic sectors which are usually represented by a complete digraph. However, I subtract those cycles according to some weighting algorithm and need to iterate it over the remainder of the original array to subtract the remaining cycles, that is why I need to recalculate the remaining cycles within that graph (which then is not a complete digraph any more because some arcs are zeroed after some iterations). I believe I really need to use the simple_cycles.py module. The issue is that although I can aggregate the sectors economy not to exceed the calculation capacity of simple_cycles.py (i.e. reduce the economy to 11 sectors), this is really hindering the possible analyses since this level of aggregation is too coarse compared to the original data set which contains about 55 sectors.
Thanks a lot,
Aleix
========= code replicating error =============
import networkx as nx
nbr_nodes=12
working_array_digraph=nx.DiGraph(np.ones((nbr_nodes,nbr_nodes)))
all_cycles = nx.simple_cycles(working_array_digraph)
print('''... There are {0} simple cycles in a {1} node complete digraph '''.format(len(all_cycles),nbr_nodes))
--
You received this message because you are subscribed to the Google Groups "networkx-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to networkx-discu...@googlegroups.com.
To post to this group, send email to networkx...@googlegroups.com.
Visit this group at http://groups.google.com/group/networkx-discuss?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.
--
You received this message because you are subscribed to a topic in the Google Groups "networkx-discuss" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/networkx-discuss/6FiQy-cxsBM/unsubscribe?hl=en.
To unsubscribe from this group and all its topics, send an email to networkx-discu...@googlegroups.com.