2015-01-25 3 views
0

Пытается использовать рекурсию для решения суммы римана.Возвращаемое значение if/else рекурсивной функции неверно, но значение для печати

def f(x): 
    import math 
    return 10*math.e**(math.log(0.5)/5.27 * x) 

liTotal = 0 
def radExpo(start, stop, step): 
    global liTotal 
    x = start 
    area = f(x)*step 
    liTotal += area 
    numOfRects = (stop - start)/step 
    if start > (stop - (2 *step)): 
     return liTotal 
    else: 
     return radExpo((start+step), stop, step) 

radExpo(12, 16, 1) 

Если я изменяю, если оператор возврата к

print liTotal 

или если я вызываю функцию с

print radExpo 

Он работает правильно, но если я позвоню/вернуть его регулярно возвращает неправильно поэтому я не могу использовать то, что возвращается.

+2

Вы на самом деле не нужен еще –

+0

не иначе рекурсивный вызов обратно в функционировать? – user2659099

+0

вы можете возвращать только один или оба не на каждом звонке –

ответ

0

Если это вопрос о том, что не так с кодом, я бы реорганизовал код, чтобы удалить глобальную ссылку, и это повысит его надежность. Я не был в состоянии воссоздать ваш вопрос, где print liTotal отличается, что print radExpo(12,16,1)

Модифицированная версия кода, который удаляет глобальной переменной ссылка выглядит следующим образом:

def f(x): 
    import math 
    return 10*math.e**(math.log(0.5)/5.27 * x) 

def radExpoNew(start, stop, step): 
    x = start 
    area = f(x)*step 
    if start <= (stop - (2 *step)): 
     area += radExpoNew((start+step), stop, step) 
    return area 

print radExpoNew(12,16,1) # prints 6.84864583554 
+0

Ничего себе! Я даже не думал о добавлении рекурсии в область на основе условия запуска. – user2659099

0

Некоторые упрощений:

from math import e, log 

# rule #1: 
# e ** (a*b) == (e ** a) ** b 

# applying rule #1 twice: 
# e ** (log(0.5)/5.27 * x) == ((e ** log(0.5)) ** (1/5.27)) ** x 

# rule #2: 
# e ** log(k) == k 

# applying rule #2: 
# e ** log(0.5) == 0.5 
# 0.5 ** (1/5.27) == 0.8767556206241964 

# so we get: 
def fn(x): 
    return 10 * 0.8767556206241964 ** x 

Затем radExpo по существу выполняет хвостовую рекурсию (называя себя один раз в конце функции), поэтому мы можем переписать ее нерекурсивно:

def integrate(fn, start, stop, step): 
    steps = int((stop - start)/step) 
    return sum(
     fn(start + k*step)  # calculate x directly for each step 
     for k in range(steps) # to prevent error accumulation 
    ) * step 

Это избавляет от глобальной переменной, которая вызывает проблемы (потому что вы не сбросили ее перед вызовом функции снова).

Тогда

>>> integrate(fn, 12, 16, 1) 
6.848645835538626 

и в качестве бонуса вы можете интегрировать любые функции вам нравится:

>>> from math import pi, sin 
>>> integrate(sin, 0, pi, 0.001) 
1.999999361387437 # pretty darn close to 2.0