Почему время, затрачиваемое итерационным алгоритмом на поиск суммы списка, не увеличивается равномерно с размером? - PullRequest
0 голосов
/ 25 апреля 2020

Я хотел посмотреть, как drasti c - это разница во временной сложности между итеративным и рекурсивным подходами для суммирования массива. Поэтому я построил график зависимости времени от размера списка для довольно приличного диапазона значений размера (995). То, что я получил, было в значительной степени тем, что я хотел, кроме чего-то неожиданного, привлекшего мое внимание. График можно увидеть здесь 1

Как и ожидалось, рекурсивный граф (синий) остается близким к нулю для всех значений размера, в то время как итерационный граф (зеленый) растет. Что меня смущает, так это те неровности, которые зеленая линия внезапно принимает только для определенных значений, а затем возвращается обратно. Почему это происходит?

Вот код, который я написал:

import matplotlib.pyplot as plt
from time import time

def sum_rec(lst): # Sums recursively
    if len(lst) == 0:
        return 0
    return lst[0]+sum_rec(lst[1:])

def sum_iter(lst): # Sums iteratively
    Sum = 0
    for i in range(len(lst)):
        Sum += i
    return Sum

def check_time(lst): # Returns the time taken for both algorithms
    start = time()
    Sum = sum_iter(lst)
    end = time()
    t_iter = end - start
    start = time()
    Sum = sum_rec(lst)
    end = time()
    t_rec = end - start
    return t_iter, t_rec

N = [n for n in range(995)]
T1 = [] # for iterative function
T2 = [] # for recursive function

for n in N: # values on the x-axis
    lst = [i for i in range(n)]
    t_iter, t_rec = check_time(lst)
    T1.append(t_iter)
    T2.append(t_rec)

plt.plot(N,T1)
plt.plot(N,T2) # Both plotted on graph
plt.show()

1 Ответ

0 голосов
/ 25 апреля 2020

Я бы сказал, что оба алгоритма имеют линейное время выполнения, но рекурсивный имеет более высокий постоянный коэффициент, что приводит к более крутому наклону.

Кроме этого: -

(1) Вы смешиваете два графика.

Итеративный один остается заземленным, в то время как рекурсивный увеличивается.

Одним из возможных объяснений может быть то, что рекурсивные вызовы делают записи в стеке и требуют больше вычислительного времени, чем итеративный звонки.

(2) Вам необходимо увеличить размер массива, так как небольшие размеры с большей вероятностью могут вызвать всплески из-за местоположения ссылки.

(3) Вам необходимо повторить эксперимент в течение нескольких эпох, чтобы убедиться, что случайные пики из-за какого-то другого процесса, блокирующего ресурс, распределяются равномерно.

Effect Of Averaging with constant array size

...