Экспоненциальный рост

Возьмём колонию из десяти бактерий, дадим им вдоволь еды и тепла — и через сутки их будут тысячи. Это самый простой и самый «взрывной» закон роста: на каждом шаге популяция умножается на одно и то же число. Сегодня мы запишем его кодом и увидим, как из десятки вырастает почти полторы тысячи.

Экспоненциальный рост — рост, при котором за равный промежуток времени величина увеличивается в одно и то же число раз (а не на одну и ту же добавку). Если за шаг популяция растёт на долю $r$, то новое значение равно старому, умноженному на $(1 + r)$.

Зачем это нужно понимать? Экспонента — это «нулевое приближение» почти любого роста: пока ресурсов много, а тесноты нет, популяции бактерий, дрожжей, насекомых, а заодно и деньги на вкладе под сложный процент, и число заражённых в самом начале эпидемии ведут себя именно так. Поняв экспоненту, вы получаете точку отсчёта: дальше реальность всегда «загибает» кривую вниз, и интересно ровно то, насколько она отклоняется от идеальной экспоненты.

Закон одного множителя

Пусть на шаге есть $N$ особей. За один шаг каждая «в среднем» оставляет потомков так, что популяция меняется на долю $r$ от текущего размера. Тогда $N_{\text{новое}} = N + rN = N(1 + r)$.

Ключевое слово — текущего. Прибавка $rN$ не постоянна: чем больше $N$, тем больше абсолютный прирост. Десять особей при $r = 0.5$ дают $+5$, а тысяча — уже $+500$. Множитель же $(1 + r)$ всегда один и тот же, поэтому за каждый шаг популяция растёт в одинаковое число раз.

Запустим имитацию: начнём с 10 особей, возьмём $r = 0.5$ (то есть $+50\%$ за шаг) и проследим 12 шагов.

def exponential(N0, r, steps):
    N = N0
    out = [N]
    for _ in range(steps):
        N = N * (1 + r)
        out.append(N)
    return out

res = exponential(10, 0.5, 12)
print(f"{'шаг':>4} {'N':>10}")
for i in range(0, 13, 2):
    print(f"{i:>4} {res[i]:>10.1f}")

Вывод:

 шаг          N
   0       10.0
   2       22.5
   4       50.6
   6      113.9
   8      256.3
  10      576.7
  12     1297.5

Проверим арифметику руками. Каждый шаг — умножение на 1.5: 10 → 15 → 22.5 → 33.75 → 50.625 → 75.9375 → 113.906… Видите, на шаге 2 ровно 22.5, на шаге 4 — 50.625 (округляется до 50.6), на шаге 6 — 113.9. К двенадцатому шагу из десяти бактерий получилось около 1297 — рост более чем в 129 раз.

Постоянный темп удвоения и правило 70

Раз за каждый шаг популяция растёт в одинаковое число раз, то и удваивается она тоже за одинаковое число шагов — где бы по высоте мы ни находились. Это самое контринтуитивное свойство экспоненты: время удвоения не зависит от размера.

Сколько шагов нужно на удвоение? Есть удобная прикидка — правило 70: если рост составляет $p$ процентов за шаг, то удвоение происходит примерно за $70 / p$ шагов. При $r = 0.5$ это $p = 50\%$, значит удвоение — за $70 / 50 \approx 1.4$ шага. Откуда берётся 70? Точная формула удвоения — это $\ln(2) / \ln(1 + r)$, а $\ln(2) \approx 0.693 \approx 0.70$, отсюда и «70» в процентах.

import math

for p in (1, 5, 10, 50):
    r = p / 100
    tochno = math.log(2) / math.log(1 + r)
    grubo = 70 / p
    print(f"{p:>3}%  точно={tochno:>6.2f}  правило70={grubo:>6.2f}")

Вывод:

  1%  точно= 69.66  правило70= 70.00
  5%  точно= 14.21  правило70= 14.00
 10%  точно=  7.27  правило70=  7.00
 50%  точно=  1.71  правило70=  1.40

Для маленьких процентов правило 70 почти идеально; для больших (50%) оно завышает, но как быстрая оценка в уме всё равно бесценно. Банковский вклад под 7% годовых удваивается за $70 / 7 = 10$ лет — этим правилом пользуются финансисты каждый день.

Как работает под капотом

В коде нет никакой «магии экспоненты» — есть цикл, в котором одна и та же строка N = N * (1 + r) повторяется снова и снова. Каждый проход берёт предыдущее значение и умножает на множитель. Математически после $k$ шагов получается $N_k = N_0 (1 + r)^k$ — то есть наш цикл это просто пошаговое возведение (1 + r) в степень числа шагов. Проверим, что цикл и формула дают одно и то же:

def exponential(N0, r, steps):
    N = N0
    for _ in range(steps):
        N = N * (1 + r)
    return N

N0, r = 10, 0.5
cikl = exponential(N0, r, 12)
formula = N0 * (1 + r) ** 12
print(f"цикл    = {cikl:.4f}")
print(f"формула = {formula:.4f}")
print(f"совпали: {abs(cikl - formula) < 1e-9}")

Вывод:

цикл    = 1297.4634
формула = 1297.4634
совпали: True

Почему мы вообще крутим цикл, если есть готовая формула со степенью? Потому что цикл — это имитация: в реальных моделях множитель на каждом шаге может меняться (еды стало меньше, похолодало), и тогда красивой формулы со степенью уже не будет, а цикл по-прежнему честно посчитает шаг за шагом. Степенная формула — частный случай, когда множитель постоянен.

Почему в природе чистая экспонента долго невозможна? Потому что любой реальный мир конечен. Возьмём кишечную палочку: она делится примерно раз в 20 минут. Если бы рост был экспоненциальным без ограничений, то за двое суток потомство одной бактерии по массе превысило бы массу Земли — этого, очевидно, не происходит. Еда кончается, продукты обмена отравляют среду, появляются хищники. Экспонента описывает только самое начало, пока теснота ещё не чувствуется. Как именно она «загибается», мы разберём в следующем уроке про логистический рост.

Частые ошибки

  • Путать «на $r$» и «в $(1 + r)$ раз». Прибавка $rN$ растёт вместе с $N$, а множитель $(1 + r)$ постоянен. Линейный рост — это $+c$ каждый шаг (постоянная добавка), экспоненциальный — это умножение на $(1 + r)$ каждый шаг.
  • Думать, что время удвоения зависит от размера. Нет: и от 10 до 20, и от 1000 до 2000 нужно одинаковое число шагов. Кривая «ускоряется» только визуально, потому что абсолютные числа растут.
  • Брать $r$ как процент, а не как долю. «$50\%$» в коде — это $0.5$, а не $50$. Перепутав, получите умножение на $51$ за шаг.
  • Ожидать, что экспонента описывает весь рост. Она верна только пока ресурсов в избытке; в тесноте модель надо менять.
  • Забывать про накопление: маленький $r$ за много шагов даёт огромный итог. Даже $+1\%$ за шаг через 70 шагов — это удвоение.

Итоги

  • Экспоненциальный рост — это умножение на постоянный множитель $(1 + r)$ на каждом шаге.
  • После $k$ шагов размер равен $N_0 (1 + r)^k$; наш цикл — пошаговая версия этой формулы.
  • Время удвоения постоянно и не зависит от текущего размера; быстро оценивается правилом 70 ($70 / p$ шагов при $p$ процентах роста).
  • Экспонента описывает бактерии, сложный процент и начало эпидемии — но только пока ресурсов в избытке.
  • В конечном мире чистая экспонента долго невозможна: дальше нужна модель с ёмкостью среды.
Проверьте себя
1. Популяция растёт по закону N = N * (1 + r) с r = 0.5. Что верно?
AКаждый шаг прибавляется одна и та же постоянная добавка
BКаждый шаг популяция увеличивается в 1.5 раза
CКаждый шаг популяция увеличивается на 1.5 особи
DРост со временем замедляется сам по себе
2. По правилу 70, за сколько примерно шагов удвоится популяция, растущая на 10% за шаг?
AЗа 10 шагов
BЗа 7 шагов
CЗа 70 шагов
DЗа 2 шага
3. Почему чистый экспоненциальный рост в природе долго невозможен?
AПотому что бактерии не умеют делиться быстро
BПотому что ресурсы и пространство конечны, и теснота тормозит рост
CПотому что множитель (1 + r) со временем сам становится меньше единицы
DПотому что популяция всегда растёт линейно
py
Курс по теме
Пройдите курс «Python с нуля» — по шагам, с проверкой
8 уроков · ~14 ч · теория, упражнения и экзамен с бейджем
Открыть курс →