КурсыИИМатематикаКодФизикаО проекте и вопросы

TwiddleLab / Код / Рекурсия: функции, которые вызывают себя

Запоминай ответы: мемоизация

Урок 5 из 11 · 7 мин · Бесплатно, без аккаунта

Что ты узнаешь

  • Мемоизация: веди блокнот ответов. Прежде чем что-то считать, загляни в него; после запиши ответ.
  • В Python блокнот это словарь: ключ n, значение fib(n).
  • С ним fib(n) делает 2n - 1 вызовов вместо миллионов: каждое значение считается один раз.
  • Та же идея считает пути по сетке: каждая клетка считается один раз из соседей.

Начать урок

Как идёт урок

  1. Приложение задаёт один и тот же трудный вопрос 1000 раз. Решать его 1000 раз?

    fib(15) сделала 1973 вызова. Теперь у неё есть блокнот: когда fib(k) известна, она записана. Угадай, сколько вызовов теперь.

  2. Побудь блокнотом для fib(6).

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

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

  3. fib(15) с блокнотом и без.

    Та же функция, тот же ответ. Посчитай вызовы.

  4. Мемоизация.

    Мемоизация значит запоминать ответы. Веди блокнот; это словарь, memo = {}.

    Прежде чем считать fib(n), проверь: if n in memo, return memo[n]. Посчитав, запиши: memo[n] = ответ.

    Каждый ответ вычисляется один раз. Дерево вызовов сжимается из пышного дерева в одну цепочку.

  5. Дай fib блокнот.

    Сначала проверь блокнот, потом базовый случай, потом посчитай и запиши. Сделай так, чтобы fib(30) печатала 832040.

    Поиск в блокноте должен идти до всякой работы, иначе он ничего не экономит. Запись memo[n] перед возвратом заполняет блокнот для следующих вызовов.

  6. Что в блокноте после fib(6)?

    Заполни каждую страницу. Каждое значение это сумма двух предыдущих страниц.

    fib(2) = 1 + 0 = 1, fib(3) = 1 + 1 = 2, fib(4) = 2 + 1 = 3, fib(5) = 3 + 2 = 5, fib(6) = 5 + 3 = 8. До строки memo[n] = ... доходят только n от 2 и больше.

  7. Сколько путей от старта до дальнего угла, если двигаться только вправо или вниз?

    paths(клетка) = paths(клетка сверху) + paths(клетка слева). Заполни сетку, каждую клетку один раз.

  8. Направь свою fib с блокнотом на месяц 30 и месяц 70.

    Без блокнота fib(70) считалась бы годами. Нажми «Запуск».

  9. Сколько вызовов делает fib(20) с блокнотом?

    fib(6) сделала 11 вызовов, fib(15) 29, fib(30) 59.

    С блокнотом fib(n) вызывает fib(n - 1), fib(n - 2) ... до fib(1): n вызовов. По пути второй вызов каждого уровня это поиск или базовый случай: ещё n - 1. Итого 2n - 1.

  10. Оба дерева считают fib(6). Какое пользовалось блокнотом?

    Нажми на дерево, потом «Проверить».

    Пышное дерево пересчитывает fib(4), fib(3) и fib(2). Тонкое считает каждую один раз; повторные запросы это пунктирные поиски, под которыми ничего нет.

Предыдущий урок: Деревья вызовов · Следующий урок: Ханойские башни · Часть курса: Рекурсия: функции, которые вызывают себя

Уроки интерактивные и работают на JavaScript. Включи его, чтобы играть.

Loading TwiddleLab