1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7

# теория · шаг 2 из 7

Метод предоплаты и метод потенциалов

Коротко

Кроме агрегатного, есть два тонких метода. Предоплата (учётный): назначаешь операции цену-предоплату, отличную от настоящей; переплата копится как КРЕДИТ на структуре и потом платит за дорогие операции. Кредит не должен уходить в минус. Потенциал: заводишь функцию Φ от состояния структуры («запас энергии»), и амортизированная цена ĉ = c + Φ_после − Φ_до. Дешёвая операция копит Φ, дорогая тратит. Оба дают ту же оценку, что агрегатный, но гибче.

Если умеешь доказывать амортизированную оценку и методом предоплаты (кредит ≥ 0), и методом потенциалов (ĉ = c + ΔΦ), листай до «Теперь сам».

Как думаешь, зачем ещё два метода

Агрегатный метод даёт одну среднюю цену на все операции сразу. Но операций бывает несколько видов (в стек кладут и достают), и хочется у каждого своя амортизированная цена. Для этого и нужны два других метода: они назначают цену покаждой операции, а не делят общую сумму поровну. Заодно они не требуют считать всю серию наперёд - доказательство идёт локально, шаг за шагом.

На что это похоже

Предоплата - как абонемент: платишь чуть больше за дешёвые походы в зал, копишь на счёте, и дорогой поход (с тренером) уже оплачен заранее. Главное - счёт не уходит в минус, иначе «оплачено заранее» неправда. Потенциал - как заряд батареи: дешёвые операции её заряжают, дорогая разряжает, и пока заряд не падает ниже стартового, все дорогие всплески уже покрыты накопленным.

Механизм: предоплата и потенциал

Предоплата. Каждой операции назначаешь амортизированную цену ĉ - можно не равную настоящей c. Если ĉ > c, разница кладётся КРЕДИТОМ на структуру; если ĉ < c, недостаток берётся из накопленного кредита. Требование одно: суммарный кредит НИКОГДА не уходит в минус. Тогда Σĉ ≥ Σc, и Σĉ - честная верхняя оценка всей серии.

Потенциал. Заводишь функцию Φ(D) ≥ 0 от состояния структуры D (обычно Φ пустой структуры = 0). Амортизированная цена операции:

ĉ = c + Φ(D_после) − Φ(D_до)

Просуммируем по всей серии - соседние Φ сокращаются (телескоп):

Σĉ = Σc + Φ(D_n) − Φ(D_0)

Раз Φ(D_0) = 0 и Φ(D_n) ≥ 0, получаем Σĉ ≥ Σc - снова верхняя оценка. Дешёвая операция поднимает Φ (копит про запас), дорогая роняет Φ (тратит запас), и её большая c гасится отрицательным ΔΦ.

Правило

Предоплата: назначь ĉ, следи, чтобы кредит Σĉ − Σc ≥ 0 всегда. Потенциал: задай Φ ≥ 0 с Φ(D_0) = 0, тогда ĉ = c + ΔΦ. Кредит и потенциал - одно и то же число с двух сторон: накопленный кредит и есть значение Φ.

Разбор: стек методом предоплаты

Стек с операциями push, pop и multipop(k) (снять k элементов). Настоящие цены: push и pop по 1, multipop(k) - k. Назначим предоплату: push = 2, pop = 0, multipop = 0. При push платим 1 за само добавление, а 1 кладём кредитом НА этот элемент. Когда элемент снимают (pop или multipop), его снятие уже оплачено лежащим на нём кредитом - поэтому назначенная цена снятия 0. Кредит не уходит в минус: на каждом лежащем в стеке элементе ровно 1. Значит любая серия из n операций стоит не больше 2n - амортизированно O(1) на операцию, хотя один multipop бывает Θ(n).

Разбор: тот же стек методом потенциалов

Возьмём Φ(D) = число элементов в стеке. Она ≥ 0, а на пустом стеке = 0 - условия выполнены. Считаем ĉ = c + ΔΦ:

  • push: c = 1, элементов стало на один больше, ΔΦ = +1. ĉ = 1 + 1 = 2.
  • pop: c = 1, ΔΦ = −1. ĉ = 1 − 1 = 0.
  • multipop(k): c = k (сняли k), ΔΦ = −k. ĉ = k − k = 0.

Каждая операция амортизированно O(1), включая multipop. Заметь: Φ = число элементов - это ровно суммарный кредит из метода предоплаты (1 на элемент). Два метода - один и тот же запас, записанный по-разному.

Разбор: считаем серию по шагам

Проследим серию push, push, push, multipop(3) с потенциалом Φ = высота стека, считая ĉ = c + ΔΦ:

push:         c=1, Φ 0→1, ĉ = 1+1 = 2
push:         c=1, Φ 1→2, ĉ = 1+1 = 2
push:         c=1, Φ 2→3, ĉ = 1+1 = 2
multipop(3):  c=3, Φ 3→0, ĉ = 3−3 = 0
настоящих действий: 1+1+1+3 = 6
амортизированных:   2+2+2+0 = 6

Суммы сошлись: Σĉ = Σc = 6, потому что Φ вернулась к нулю (Φ(конец) = Φ(старт) = 0). Три дешёвых push подняли потенциал до 3, и дорогой multipop(3) полностью его израсходовал - оттого и вышел бесплатным. Если бы серия кончилась при непустом стеке, Σĉ было бы даже больше Σc на остаток Φ - оценка с запасом, но всё ещё верная.

Что ломается без этого

Две ловушки. В предоплате - забыть проверить, что кредит не уходит в минус: если дорогая операция случится раньше, чем накоплен кредит, «предоплата» ничего не доказывает. В потенциале - взять Φ, которая бывает отрицательной или не ноль на старте: тогда Φ(D_n) − Φ(D_0) может оказаться отрицательным, Σĉ < Σc, и оценка перестаёт быть верхней. Φ ≥ 0 и Φ(D_0) = 0 - не формальность, а то, что делает Σĉ гарантией.

Зачем это в работе

Метод потенциалов - главный инструмент для структур со сложным поведением: динамические массивы, splay-деревья, фибоначчиевы кучи доказывают свои оценки именно им, потому что агрегатно их серию не сложить. Умение подобрать Φ - это и есть «увидеть, где структура копит запас на будущее»: у стека запас - его высота, у динамического массива (следующий урок) - насколько он заполнен сверх половины.

Теперь сам

Стек считают методом потенциалов с Φ = число элементов. Чему равна амортизиро‐ ванная цена push, за которым сразу идёт multipop, снимающий всё (пусть в стеке стало m элементов перед ним)?

Ответ. push: ĉ = 1 + 1 = 2. Следующий multipop(m): снимает все m, c = m, ΔΦ = −m (стек опустел), ĉ = m − m = 0. Вместе две операции стоят амортизированно 2 + 0 = 2 = O(1), хотя настоящая цена второй Θ(m). Накопленный за push-и потенциал (высота стека) ровно оплатил дорогой multipop - Φ упала с m до 0, погасив его цену.

Главное

Два тонких метода. Предоплата: назначь операции цену ĉ, переплата копится кредитом, недостаток берётся из него, кредит всегда ≥ 0 - тогда Σĉ ≥ Σc. Потенциал: задай Φ ≥ 0 c Φ(D_0)=0, и ĉ = c + Φ_после − Φ_до; при суммировании средние Φ телескопируются, остаётся Σĉ = Σc + Φ(D_n) ≥ Σc. Дешёвая операция копит запас, дорогая его тратит. У стека Φ = высота, и это тот же кредит 1 на элемент - multipop амортизированно O(1).

Комментарии

Пока нет комментариев. Будь первым!

Оставить комментарий

Комментарий появится после проверки. Email не публикуется. Войти, чтобы не вводить имя каждый раз.