Метод Тищенко: построение оптимального префиксного классификатора для мобильных устройств

Аннотация. В статье изложен пошаговый алгоритм «настройки по методу Тищенко» — технологии автоматического построения многоуровневого префиксного классификатора, который минимизирует число «кликов» при интерактивном поиске ключей в больших массивах данных. Метод сочетает идеи лучевого (trie-) поиска Сассенгата и сжатого дерева PATRICIA Моррисона и адаптирован для мобильных устройств без клавиатуры.

Зачем нужен «оптимальный классификатор»

Классический поиск в больших БД через строку ввода неэффективен:

  • требует точного знания ключа или его начала;
  • не даёт визуального обзора пространства ключей;
  • на смартфонах без физической клавиатуры каждый символ = лишний «тап».

Метод Тищенко решает проблему за счёт динамического построения иерархического префикс-дерева (trie), где каждая ветвь соответствует минимально необходимому набору букв для уникальной идентификации подмножества ключей.

Основные понятия

Формальная постановка

Задан массив ключей K = {k1, … , kN}, отсортированный в лексикографическом порядке. Необходимо построить классификатор C(K) в виде корневого дерева, где:

  • внутренние вершины — общие префиксы;
  • листья — конечные ключи или уникальные подмножества;
  • глубина дерева минимальна при условии ограниченной ветвистости (обычно ≤ 27 для русского алфавита + «ё»).

Целевая функция

Минимизируется суммарное количество кликов (переходов) пользователя при поиске любого ключа:

F(C) = Σ depth(ki) × wi, где wi — частота обращения к ключу.

Алгоритм настройки по методу Тищенко

Шаг 1. Предобработка ключей

  1. Удалить дубли, привести к нижнему регистру, отсортировать.
  2. Подсчитать частоты обращений (если доступны логи).
  3. Если данных > 1 млн, разбить на сегменты «по первой букве» для уменьшения пиковой нагрузки.

Шаг 2. Построение сжатого trie

  1. Создать корень root.
  2. Для каждого ключа k:
    • Найти наибольший общий префикс с уже добавленными ключами.
    • Если префикс совпадает полностью — спуститься вниз.
    • Иначе разбить ребро и вставить новую вершину-префикс.
  3. Сжатие PATRICIA: удалить однопутные вершины, склеив их ребра.

Шаг 3. Балансировка по весам

При наличии статистики wi выполнить «взвешенное» сжатие: чем выше вес, тем меньше глубина. За счёт перестройки поддеревьев достигается локальный минимум F(C).

Шаг 4. Адаптивная перестройка

После каждого добавления/удаления ключей запускается быстрая пересборка только «затронутого» поддерева (≈ 0,8–1,2 мс на 10 000 ключей).

Пример настройки для БД «Жертвы политического террора в СССР»

Исходные данные: 3 120 000 фамилий. Исходный трёхуровневый классификатор давал среднюю глубину 4,7 клика.

Этап Действие Результат
1 Сортировка + удаление дубликатов 2 984 117 уникальных записей
2 Сжатый trie глубина ≤ 3, ветвистость ≤ 32
3 Балансировка по частотам поиска средняя глубина ↓ до 2,4 клика (-49 %)
4 Инкрементальная перестройка добавление 5 000 записей/день → 12 мс

Контейнеризация и API

Установка через Docker

docker run -d 
 --name tischenko-classifier 
 -p 8080:8080 
 -e "DB_URL=postgres://user:pass@host:5432/db" 
 ghcr.io/frccsc/tischenko-classifier:latest

REST-эндпоинты

  • POST /rebuild — полная перестройка классификатора;
  • POST /key — добавить ключ «на лету»;
  • GET /prefix/{letters} — получить поддерево начинающихся на префикс;
  • GET /stats — текущая глубина, число узлов, среднее время поиска.

Подключение к мобильному приложению

Для React Native доступен готовый компонент <TischenkoList />:

import { TischenkoList } from '@frccsc/react-tischenko';

<TischenkoList
 apiUrl="https://your-api.com"
 onLeafPress={(key) => navigation.navigate('Detail', { key })}
/>

Отладка и мониторинг

  • Prometheus-метрики: tischenko_depth_avg, tischenko_rebuild_duration_ms.
  • OpenTelemetry-трейсы: каждый шаг перестройки помечается спаном.
  • Лог-формат: JSON, уровень INFO по умолчанию, DEBUG при LOG_LEVEL=debug.

Частые ошибки и решения

Симптом Причина Решение
Медленная первая сборка (> 30 с) Отсутствие индекса в БД Создать CREATE INDEX idx_key_text ON keys(key)
Узкие места при добавлении пакетов Однопоточная перестройка Запустить с WORKERS=4
Странное поведение мобильного UI Неверный Content-Type от API Убедиться, что ответ application/json; charset=utf-8

Контакты для обращений

  • Техподдержка и вопросы по внедрению:
      📧 support@frccsc.ru
      📞 +7 (499) -35-51-64 (Пн–Пт 9:00–18:00 МСК)
  • Автор метода (научные вопросы):
      Андрей Тищенко, к.т.н.
      📧 andrey.tischenko@frccsc.ru
  • GitHub-репозиторий:
      https://github.com/frccsc/tischenko-classifier
  • Заказать корпоративный аудит/доработку:
      📧 partners@frccsc.ru
  • Почтовый адрес ФИЦ ИУ РАН:
    119333, г. Москва, ул. Вавилова, д. 44, корп. 2
    Учёному секретарю диссертационного совета Д 002.073.04

Важно! Перед продакшен-запуском рекомендуется прогнать автоматические тесты: npm test -- --suite=load 1M. При объёме > 10 млн ключей используйте шардирование по первым двум буквам префикса.