R и f - совершенно разные функции, которые не имеют ничего общего, кроме как они растут относительно n, поэтому нет причины, по которой f (n) должно равняться R (n). R - это «количество ресурсов, которое требуется процессу для решения проблемы размера n». f - несвязанная математическая функция.
Что делает определение Θ особенно запутанным, так это то, что оно не относится к ресурсу, который измеряет R, ни к процессу, использующему ресурс.
Примеры R (n) могут быть:
- Количество регистров, используемых для суммирования n чисел.
- Диск, используемый для перекодирования n ГБ видео
- Время, необходимое для запуска n дронов.
Но в определении Θ не упоминаются ресурсы (регистры, диск, время) и процессы (суммирование, транскодирование или запуск).
Если наш «процесс» представляет собой программную процедуру с именем p, то у нас есть три совершенно разные «функции»:
p(n) - a procedural function that programmers work with.
R(n) - a measuring function like ones used by engineers.
f(n) – a 'pure' mathematical function.
Если мы используем в качестве примера факториальную процедуру, которая имеет Θ (n) рост по времени, мы получили бы:
p(n) = (define (factorial n) (if (= n 1) 1 (* n (factorial (- n 1)))))
R(n) = The time in seconds for (factorial n) to complete.
f(n) = n
R (n) = f (n) подразумевает (факториал 17) для запуска ровно 17 секунд, что маловероятно.
Определение Θ (n) гласит, что k₂ и k₂ существуют так, что когда n достаточно велико:
k₁ * n <= "Time taken for (factorial n) to run in seconds" <= k₂ * n
На современном компьютере k₁ должно быть очень маленьким, чтобы k₁ * n было меньше, чем фактическое время работы.
Для дерево-рекурсивной процедуры Фибоначчи рост равен Θ (1.618ⁿ), поэтому имеем:
p(n) = (define (fib n) (cond ((= n 0) 0) ((= n 1) 1) (else ... )))
R(n) = The time in seconds for (fib n) to complete.
f(n) = 1.618ⁿ
и определение гласит, что k₁ и k₂ существуют так, что:
k₁ * 1.618ⁿ <= "Time taken for (fib n) to run" <= k₂ * 1.618ⁿ)
(я использовал «1.618» для золотого рациона вместо «φ»)