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

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

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

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

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

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

Ключевое слово — текущего. Прибавка r * N не постоянна: чем больше 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 ≈ 1.4 шага. Откуда берётся 70? Точная формула удвоения — это ln(2) / ln(1 + r), а ln(2) ≈ 0.693 ≈ 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 = N0 * (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) раз». Прибавка r * N растёт вместе с N, а множитель (1 + r) постоянен. Линейный рост — это +c каждый шаг (постоянная добавка), экспоненциальный — это умножение на (1 + r) каждый шаг.
  • Думать, что время удвоения зависит от размера. Нет: и от 10 до 20, и от 1000 до 2000 нужно одинаковое число шагов. Кривая «ускоряется» только визуально, потому что абсолютные числа растут.
  • Брать r как процент, а не как долю. «50%» в коде — это 0.5, а не 50. Перепутав, получите умножение на 51 за шаг.
  • Ожидать, что экспонента описывает весь рост. Она верна только пока ресурсов в избытке; в тесноте модель надо менять.
  • Забывать про накопление: маленький r за много шагов даёт огромный итог. Даже +1% за шаг через 70 шагов — это удвоение.

Итоги

  • Экспоненциальный рост — это умножение на постоянный множитель (1 + r) на каждом шаге.
  • После k шагов размер равен N0 * (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Потому что популяция всегда растёт линейно