ГлавнаяБлогДинамическое ценообразование: как работает surge pricing
Алгоритмы

Динамическое ценообразование: как работает surge pricing

Узнайте, как работает динамическое ценообразование в такси: от H3-ячеек до ML-моделей. Разберитесь в алгоритмах и архитектуре surge pricing на примере Python.

Al
Редакция Algolitalgolit.ru
12 мин чтения16 июня 2026 г.

Что такое surge rate и как он рассчитывается?

Surge rate (или динамическое ценообразование) — это множитель цены, который применяется в приложениях такси, когда спрос на поездки превышает предложение свободных водителей в конкретной зоне. Например, при surge rate 2.0× пассажир платит вдвое больше базового тарифа. Этот множитель пересчитывается каждые 30–60 секунд для каждой ячейки H3 (гексагональной сетки) на основе отношения спроса к предложению, которое затем преобразуется в множитель с помощью таблицы или ML-модели.

Почему необходимо динамическое ценообразование?

В новогоднюю ночь, во время сильного дождя или в час пик спрос на поездки резко возрастает, а количество свободных водителей остаётся прежним. Если бы цены были фиксированными:

  • Пассажиры не смогли бы найти машину, так как все водители были бы заняты.
  • У водителей из других районов не было бы стимула приезжать в горячие зоны.
  • Система была бы перегружена, что привело бы к огромному времени ожидания.

Surge pricing — это не просто способ увеличить выручку, а механизм рыночного равновесия:

Рост цены → два одновременных эффекта:

  1. Предложение растёт: Водители видят красные зоны (высокие цены) на своей тепловой карте и перемещаются туда, чтобы заработать больше.
  2. Спрос снижается: Пассажиры видят высокие цены и часть из них решает подождать, поехать на автобусе или пройтись пешком.

В результате спрос и предложение постепенно возвращаются к равновесию, а время ожидания для тех, кому действительно нужна машина, сокращается.

Архитектура движка динамического ценообразования

┌────────────────────────────────────────────────────────────────┐
│                      DATA PIPELINE                              │
│                                                                  │
│  Kafka Topic              Flink Stream Processing                │
│  "driver.location"  ───►  ┌────────────────────┐                │
│  "ride.requests"    ───►  │  Supply-Demand      │                │
│                           │  Aggregator         │                │
│                           │  (per H3 cell,      │                │
│                           │   5-min window)     │                │
│                           └─────────┬──────────┘                │
│                                     │                            │
│                                     ▼                            │
│                           ┌────────────────────┐                │
│                           │  Pricing Engine     │                │
│                           │  (Surge Calculator) │                │
│                           └─────────┬──────────┘                │
│                                     │                            │
│                           ┌─────────▼──────────┐                │
│                           │  Redis Cache        │                │
│                           │  (Surge Multipliers) │                │
│                           └─────────┬──────────┘                │
│                                     │                            │
│                    ┌────────────────┼────────────────┐           │
│                    ▼                ▼                ▼           │
│              Rider App        Driver App       Matching Engine   │
│              (Shows price)    (Heatmap)        (Weighs cost)    │
└────────────────────────────────────────────────────────────────┘

Шаг 1: Геофенсинг с помощью H3

Динамическое ценообразование рассчитывается не для всего города, а для отдельных гексагональных ячеек H3. Uber использует разрешение 7 (каждая ячейка ~5 км²), что достаточно крупно для статистической значимости, но достаточно мелко для отражения локальных условий. Например, Хошимин делится на ~200 ячеек H3:

  • Ячейка A (центр): supply=5, demand=30 → surge 3.2×
  • Ячейка B (пригород): supply=20, demand=15 → surge 1.0×
  • Ячейка C (аэропорт): supply=8, demand=40 → surge 4.0×
  • Ячейка D (окраина): supply=12, demand=3 → surge 1.0×

Шаг 2: Расчёт множителя surge

Базовая модель: отношение спроса и предложения.

surge_multiplier = f(demand / supply)
# supply — количество СВОБОДНЫХ водителей в ячейке за последние 5 минут
# demand — количество запросов на поездку в ячейке за последние 5 минут

# Пример простой формулы (иллюстративно):
ratio = demand / supply
if ratio <= 1.0:
    surge = 1.0  # нормальная цена
elif ratio == 2.0:
    surge = 1.5
elif ratio == 3.0:
    surge = 2.0
elif ratio >= 5.0:
    surge = 3.5  # максимальный потолок

Продвинутая модель: машинное обучение. В реальности Uber использует ML-модели, учитывающие множество факторов:

  • Количество свободных водителей в ячейке
  • Количество запросов в скользящем окне
  • Исторические паттерны спроса/предложения по часу и дню недели
  • Погодные данные (дождь → спрос растёт, предложение падает)
  • События (концерты, футбольные матчи)
  • Коэффициент конверсии (какой процент пассажиров бронирует при текущем surge)
  • Уровни surge в соседних ячейках (эффект перетекания)

Обратная связь для предотвращения завышения цен

Непрерывный цикл обратной связи:

  1. Surge = 3.0× → многие пассажиры отменяют (конверсия падает с 70% до 30%)
  2. Движок понимает: цена слишком высока, пассажиры уходят
  3. Снижает surge до 2.0× → конверсия восстанавливается до 60%
  4. Одновременно приезжают водители (предложение растёт) → отношение падает
  5. Surge продолжает снижаться до 1.5× → 1.0×

Этот процесс происходит автоматически за несколько минут.

Шаг 3: Тепловая карта для водителей

Surge pricing не только влияет на цену для пассажира, но и генерирует тепловую карту, отображаемую в приложении водителя, направляя их в зоны с высоким спросом.

Визуализация тепловой карты:
  🟢 = 1.0× (норма, избыток водителей)
  🟡 = 1.5-2.0× (умеренный спрос)
  🔴 = 2.5×+ (очень высокий спрос, отличный заработок)

Тепловая карта обновляется в реальном времени через WebSocket (или gRPC-стримы):

# Сервер → WebSocket Push → Приложение водителя
# Полезная нагрузка каждые 30 секунд:
{
  "heatmap": [
    {"h3": "872a100d6ffffff", "surge": 3.2, "color": "#FF0000"},
    {"h3": "872a100d7ffffff", "surge": 1.0, "color": "#00FF00"},
    {"h3": "872a100d8ffffff", "surge": 1.8, "color": "#FFAA00"}
  ],
  "updated_at": "2026-05-06T20:30:00Z"
}

Прогнозирование surge — предвосхищение спроса

Uber и Grab не просто реагируют на текущие всплески — они предсказывают surge до того, как он произойдёт:

# Прогностическая модель:
# Входные данные:
#   - Текущее время: 17:00 (приближается час пик)
#   - День: пятница (выходные → спрос растёт)
#   - Погода: прогноз дождя в 17:30
#   - События: концерт на стадионе в 20:00
#   - История: последние 4 пятницы также давали surge 2.5× в 17:30
#
# Выход:
#   - Прогноз: surge достигнет 2.8× в районе стадиона в 17:30
#   - Действие: отправить уведомления ближайшим водителям за 15 минут
#     "Скоро ожидается высокий спрос у стадиона, поезжайте туда, чтобы заработать больше!"

Upfront Pricing vs. Surge Multiplier

Старая модель: множитель surge (Uber до 2017). Пассажиру показывали: "Surge 2.5×". Итоговая цена = базовая стоимость × 2.5. Проблема: пассажиры не знали точную стоимость до посадки → сюрпризы, жалобы.

Новая модель: Upfront Pricing (текущие Uber, Grab). Пассажиру показывают: "Цена: 125 000 VND" (фиксирована до бронирования). Цена рассчитывается как: базовая стоимость + (расстояние × тариф за км) + (время × тариф за минуту) + surge_premium + корректировки на маршрут (например, пробки). Пассажир знает точную цену заранее — гораздо прозрачнее.

Хранение состояния surge

# Redis: хранит множитель surge для каждой ячейки H3
# Ключ: surge:{resolution}:{h3_cell_id}
# TTL: 60 секунд (автоматически удаляется, если не обновлён → возврат к 1.0×)

SET surge:7:872a100d6ffffff "3.2" EX 60
SET surge:7:872a100d7ffffff "1.0" EX 60
SET surge:7:872a100d8ffffff "1.8" EX 60

# Когда приложение пассажира запрашивает цену:
GET surge:7:872a100d6ffffff → "3.2"
# API Gateway использует это значение для расчёта Upfront Price

Механизмы защиты от злоупотреблений

РискРешение
Водители намеренно отключают приложение, чтобы создать искусственный дефицитОбнаружение паттернов: множество водителей одновременно уходят в офлайн → флаг
Водители принимают только заказы с высоким surge, отклоняя обычныеНизкий уровень принятия → более низкий приоритет в алгоритме подбора
Экстремально высокий surge вызывает массовую негативную реакциюМаксимальный потолок (например, 5.0×), мягкие потолки на основе конверсии
Мерцающий surge (быстро меняющиеся цены)Сглаживание: surge может увеличиваться/уменьшаться не более чем на 0.5× каждые 30 секунд

Практический вывод: что делать прямо сейчас

Чтобы закрепить понимание, попробуйте реализовать простой симулятор динамического ценообразования на Python. Возьмите данные о спросе и предложении для нескольких H3-ячеек, рассчитайте ratio и примените таблицу множителей. Затем добавьте обратную связь по конверсии и посмотрите, как меняется равновесие. Это отличное упражнение для понимания механики.

#динамическое ценообразование#surge pricing#H3#алгоритмы#архитектура
Al
Редакция Algolit

Пишем про алгоритмы, подготовку к собеседованиям и карьеру в IT — так, чтобы было понятно и полезно.

Хочешь закрепить знания на практике?

Решай задачи на Algolit — интерактивная платформа для обучения

Начать бесплатно →