Вычисление рекуррентного отношения T (n) = T (n/log n) + Θ (1)

Вопрос исходит из Введение в алгоритмы 3rd Edition, P63, Problem 3-6, где он вводится как Итерированные функции. Я переписываю его следующим образом:

int T(int n){
   for(int count = 0; n > 2 ; ++count)
   {
      n = n/log₂(n); 
   }
   return count;
}

Тогда дайте как можно более плотную оценку на T(n).

Я могу сделать это O(log n) и Ω(log n / log log n), но может ли он быть более плотным?


PS: Используя Mathematica, я узнал, что когда n=1*10^3281039, T(n)=500000

и в то же время T(n)=1.072435*log n/ log log n

и коэффициент уменьшается с n от 1.22943 (n = 2.07126*10^235) до 1.072435 (n = 1*10^3281039).

Пусть эта информация будет полезной.

Ответы

Ответ 1

Похоже, что нижняя граница довольно хороша, поэтому я попытался доказать, что верхняя граница O(log n / log log n). Но позвольте мне сначала объяснить другие границы (только для лучшего понимания).

TL; DR

T(n) находится в Θ(log n / log log n).

T (n) находится в O(log n)

Это можно увидеть, изменив n := n/log₂n на n := n/2.
Для этого требуется O(log₂ n) шагов до n ≤ 2.

T (n) находится в Ω(log n / log log n)

Это можно увидеть, изменив n := n/log₂(n) на n := n/m, где m - начальное значение log n.
Решая уравнение n / (log n)x < 2 для x приводит нас к

               log n - x log log n < log 2
    ⇔                log n - log 2 < x log log n
    ⇔  (log n - log 2) / log log n < x

    ⇒ x ∈ Ω(log n / log log n)

Улучшение верхней границы: O(log n) → O(log n / log log n)

Теперь попробуем улучшить верхнюю границу. Вместо деления n на фиксированную константу (а именно, 2 в вышеприведенном доказательстве) мы разделим n как можно раньше на начальное значение log(n)/2, поскольку текущее значение log(n) больше. Чтобы быть более ясными, посмотрите на модифицированный код:

int T₂(int n){
     n_old = n;
     for(int count=0; n>2 ;++count)
     {
         n = n / (log₂(n_old)/2);

         if(log₂(n)) <= log₂(n_old)/2)
         {
            n_old = n;
         }
     }
     return count;
}

Сложность функции T₂ явно является верхней оценкой для функции T, так как log₂(n_old)/2 < log₂(n) выполняется за все время.

Теперь нам нужно знать, сколько раз мы делим на каждый 1/2⋅log(n_old):

    n / (log(sqrt(n)))x ≤ sqrt(n)
⇔           n / sqrt(n) ≤ log(sqrt(n))x
⇔          log(sqrt(n)) ≤ x log(log(sqrt(n)))

⇔    log(sqrt(n)) / log(log(sqrt(n)))  ≤ x 

Итак, мы получаем рекуррентную формулу T₂(n) = T(sqrt(n)) + O(log(sqrt(n)) / log(log(sqrt(n)))).

Теперь нам нужно знать, как часто эту формулу нужно развернуть до n < 2.

        n2-x < 2
⇔       2-x⋅log n < log 2
⇔       -x log 2 + log log n < log 2
⇔       log log n < log 2 + x log 2
⇔       log log n < (x + 1) log 2

Итак, нам нужно разложить формулу о log log n раз.

Теперь это становится немного сложнее. (Посмотрите также на ответ Mike_Dog)

T₂(n) = T(sqrt(n)) + log(sqrt(n)) / log(log(sqrt(n)))
      = Σk=1,...,log log n - 1 2-k⋅log(n) / log(2-k⋅log n))
      = log(n) ⋅ Σk=1,...,log log n - 1 2-k / (-k + log log n))
(1)   = log(n) ⋅ Σk=1,...,log log n - 1 2k - log log n / k
      = log(n) ⋅ Σk=1,...,log log n - 1 2k ⋅ 2- log log n / k
      = log(n) ⋅ Σk=1,...,log log n - 1 2k / (k ⋅ log n)
      = Σk=1,...,log log n - 1 2k / k

В строке, отмеченной (1), я переупорядочил сумму.

Итак, в конце мы "только" должны вычислить Σk=1,...,t 2k / k для t = log log n - 1. В этот момент Maple решает эту проблему с помощью

Σk=1,...,t 2k / k = -I⋅π - 2t⋅LerchPhi(2, 1, t)  +2t/t

где I - мнимая единица, а LerchPhi - Lerch transcendent. Поскольку результат для указанной выше суммы является вещественным числом для всех соответствующих случаев, мы можем просто игнорировать все мнимые части. Трансцендентный Lerch LerchPhi(2,1,t), кажется, находится в O(-1/t), но я не уверен в этом на 100%. Может быть, кто-то это докажет.

Наконец, это приводит к

T₂(n) = -2t⋅O(-1/t) + 2t/t = O(2t/t) = O(log n / log log n)

Все вместе мы имеем T(n) ∈ Ω(log n / log log n) и T(n) ∈ O(log n/ log log n),
поэтому T(n) ∈ Θ(log n/ log log n) выполняется. Этот результат также поддерживается вашими данными примера.

Надеюсь, это понятно, и это немного помогает.

Ответ 2

Чувства проблемы проверки гипотетической оценки состоят в том, чтобы получить хорошую оценку включения значения

n / log(n)

в функцию

n --> log(n) / log(log(n))

Теорема

log( n/log(n) ) / log(log( n/log(n) )) = log(n)/log(log(n)) - 1 + o(1)

(в случае проблем с читабельностью шрифта, это мало-о, а не большое-о)

Доказательство:

Чтобы сохранить запись, напишите

A = n
B = log(n)
C = log(log(n))

Работа основана на первом порядке приближения к (естественному) логарифму: когда 0 < y < x,

log(x) - y/x < log(x - y) < log(x)

Значение, которое мы пытаемся оценить,

log(A/B) / log(log(A/B)) = (B - C) / log(B - C)

Применяя оценки для логарифма разности, получаем

(B-C) / log(B) < (B-C) / log(B-C) < (B-C) / (log(B) - C/B)

т.е.

(B-C) / C < (B-C) / log(B-C) < (B-C)B / (C (B-1))

Как рекурсия, которую мы пытаемся удовлетворить, так и нижняя граница, предположим, что мы должны оценить это с помощью B/C - 1. Вытягивание этого с обеих сторон дает

B/C - 1 < (B-C) / log(B-C) < B/C - 1 + (B-C)/(C(B-1))

и, следовательно, заключаем

(B-C) / log(B-C) = B/C - 1 + o(1)

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

log(x-y) = log(x) + Θ(y/x) when y = o(x)

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

Ответ 3

Спасибо за ответ @AbcAeffchen

Я являюсь владельцем вопроса, используя знания "мастер-метода", который я узнал вчера, "немного более сложная" часть доказательства может быть выполнена просто так. The master method

Я начну здесь:

T(n) = T(sqrt(n)) + O(log(sqrt(n)) / log(log(sqrt(n))))
⇔ T(n)=T(sqrt(n)) + O(log n  / log log n)

Пусть

n = 2 k S (k) = T (2 k)

то имеем

T (2 k) = T (2 k/2) + O (log 2 k/log log 2 k) ⇔ S (k) = S (k/2) + O (k/log k)

с помощью мастер-метода

S (k) = a * S (k/b) + f (k), где a=1, b=2, f (k) = k/log k = Ω (k log 2 1 + ε) = Ω (k ε),

пока ε∈(0,1)

поэтому мы можем применить случай 3. Тогда

S (k) = O (k/log k)

T (n) = S (k) = O (k/log k) = O (log n/log log n)