Python recursive algorithm doesn't work for large values - C program works -


i wanted write backtracking solution this question, asks find distinct odd numbers sum given n.

i hacked python code:

import sys sys.setrecursionlimit(10000)    stop = false def solve(n, used, current_sum):     global stop     if stop:         return      if current_sum == n:         print(used)         stop = true         return      start = 1 if len(used) == 0 else (used[-1] + 2)     in range(start, n + 1, 2):         if current_sum + <= n , not stop:             used.append(i)             solve(n, used, current_sum + i)             used.pop()         else:             return  solve(100000000, [], 0) 

which, unfortunately, not print me. far can tell, never gets if condition. if print current_sum @ each step, seems stop @ around 16000000 when entire program quits no error.

i tried increasing recursion limit, no luck.

i tested on idle , eclipse, in python 3.4, 64 bit, under windows 8.1. have 16 gb of ram.

if reduce n, solution (remove 0 example).

this did not make sense me, wanted see if maybe have better luck in c. hacked in c:

int sol[100000]; bool done = false; void solve(int n, int k, int sum) {     if (done)         return;      if (sum == n)     {         done = true;         (int = 0; < k; ++i)         {             printf("%d ", sol[i]);         }         printf("\n");         return;     }      int start = 1;     if (k > 0)         start = sol[k - 1] + 2;     (int = start; <= n; += 2)         if (sum + <= n && !done)         {             sol[k] = i;             solve(n, k + 1, sum + i);         }         else             return; }  int main() {     solve(100000000, 0, 0);      return 0; } 

which works great if add zero!

what deal python , how can working large values well?

the execution time lower values comparable c code, quits on me higher values.

what deal python , how can working large values well?

i rewrote code make work. need adapt recursion depth when increase n parameter. used python 2.7.6. idea same way c code wrote, second parameter passed integer , not list.

import sys sys.setrecursionlimit(100000)   sol = [] stop = false  def solve(n, k, current_sum):     global stop      if stop:         return      if current_sum == n:     stop = true     in xrange(0, k, 1):             print(sol[i]),     print         return      start = 1 if len(sol) == 0 else (sol[k-1] + 2)     in xrange(start, n + 1, 2):         if current_sum + <= n , not stop:         sol.append(0)         sol[k] =             solve(n, k + 1, current_sum + i)         else:             return  solve(100000000, 0, 0) 

discussion of issue

i tried read memory usage of python code wrote. had set n = 100.000 in order result of 370 mb. adding 0 made operating system kill program. (on mac os x received memory error).

here code used on linux:

import os import sys  sys.setrecursionlimit(100000)   _proc_status = '/proc/%d/status' % os.getpid()  _scale = {'kb': 1024.0, 'mb': 1024.0*1024.0,           'kb': 1024.0, 'mb': 1024.0*1024.0}  def _vmb(vmkey):     '''private.     '''     global _proc_status, _scale      # pseudo file  /proc/<pid>/status     try:         t = open(_proc_status)         v = t.read()         t.close()     except:         return 0.0  # non-linux?      # vmkey line e.g. 'vmrss:  9999  kb\n ...'     = v.index(vmkey)     v = v[i:].split(none, 3)  # whitespace     if len(v) < 3:         return 0.0  # invalid format?      # convert vm value bytes     return float(v[1]) * _scale[v[2]]  def memory(since=0.0):     '''return memory usage in bytes.     '''     return _vmb('vmsize:') - since   stop = false def solve(n, used, current_sum):     global stop      if stop:         return      if current_sum == n:         print(used)         stop = true         return      start = 1 if len(used) == 0 else (used[-1] + 2)     in range(start, n + 1, 2):         if current_sum + <= n , not stop:             used.append(i)             solve(n, used, current_sum + i)             used.pop()         else:             return  m0 = memory() solve(100000, [], 0) m1 = memory(m0) print(m1/(1024*1024)) 

in comparison result improved (corrected) code wrote uses 4 mb parameter n set 100.000.000. that's huge difference indeed.

i not sure why is. in particular have loop contains recursive call (so call recursively several times same branch).

if insist on using recursive calls, maybe you'd want redesign program. recursive calls memorization can faster loops in cases. see this link example.


Comments

Popular posts from this blog

toolbar - How to add link to user registration inside toobar in admin joomla 3 custom component -

linux - disk space limitation when creating war file -

How to provide Authorization & Authentication using Asp.net, C#? -