Вы правильно рассчитали, что значение a
после i
-ой итерации внутреннего цикла:
Гдеa_j0
- это значение a
в начале j
-го внешнего цикла.Условие остановки для внутреннего цикла:
, которое можно решить как квадратное неравенство:
Следовательно, внутренний цикл составляет примерно O(sqrt(a_j0 / b))
.Начальное значение next a
удовлетворяет:
Масштабирование примерно как sqrt(2b * a_j0)
.Было бы довольно утомительно точно вычислять сложность времени, поэтому давайте применим приведенные выше приближения с этого момента:
Где a_n
заменяет a_j0
и t_n
- это время выполнения внутреннего цикла - и, конечно, общая сложность времени - это всего лишь сумма t_n
.Обратите внимание, что первый член задан как n = 1
, а входное значение a
определено как a_0
.
Перед непосредственным решением этого повторения, обратите внимание, что, поскольку второй член t_2
уже пропорционально корню квадратному из первого t_1
, последний доминирует над всеми другими слагаемыми в сумме.
Таким образом, общая сложность времени составляет всего O(sqrt(a / b))
.
Обновление: числовые тесты.
Обратите внимание, что, поскольку все изменения значения a
пропорциональны b
, а все условия цикла также пропорциональныдо b
, функция может быть «нормализована» путем установки b = 1
и только с изменением a
.
Тестовая функция Javascript, которая измеряет количество раз, которое внутренний циклвыполняет:
function T(n)
{
let t = 0, k = 0;
while (n >= 1) {
k = 1;
while (n >= k) {
n -= k;
k++; t++;
}
}
return t;
}
Участок sqrt(n)
против T(n)
:
Убедительная прямая линия, которая подтверждает, чтосложность времени действительно наполовину мала.