logistic_normalization()

Домен: SIMULATION | Контур: Нормализация шансов (Softmax)

WarningОграничение публичной документации

В открытом доступе представлена демонстрационная версия метода. В настоящей публичной документации отображены не все шаги, технические сценарии и приватные эндпоинты для системы цифровых симуляторов бизнес-процессов.

  • Полная спецификация метода: Будет доступна только во внутреннем контуре разработки (Confluence / Swagger Enterprise).

1. Бизнес-спецификация метода

  • Идентификатор метода: BPDS-SIM-M08
  • Системное имя: logistic_normalization()
  • Микросервис: simulation-core-engine
  • Домен: SIMULATION
  • Класс / Компонент: simulation.engine.generator.StochasticGeneratorImpl

1.1. Описание логики работы

Этот метод берет сырые показатели силы желаний пользователя, полученные на предыдущем шаге, и превращает их в понятные проценты (вероятности). Главное математическое правило этого шага: сумма процентов для всех четырех возможных действий всегда должна быть строго равна 100% (или 1.0000 в долях).

Для перевода чисел в проценты используется стандартная математическая функция Softmax. Однако у нее есть физическая проблема: если на Шаге 7 из-за дикого голода или аномалии выросло гигантское число плотности, компьютер попытается возвести число \(e\) в эту огромную степень и намертво зависнет с ошибкой переполнения процессора (Infinity).

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

1.2. Пошаговое выполнение

  1. Поиск максимума: Метод сканирует полученную карту желаний и находит самое большое число плотности.
  2. Безопасный сдвиг (Safe Shift): Из значения каждого желания вычитается этот найденный максимум. Самое большое число превращается в ноль, а остальные становятся отрицательными (это гарантирует, что процессор будет считать степени только от безопасных чисел меньше или равных нулю).
  3. Расчет локальных экспонент: Программа рассчитывает математическую экспоненту (\(e^x\)) для каждого сдвинутого значения.
  4. Суммирование: Все полученные экспоненты складываются в общую сумму (знаменатель).
  5. Нормирование в проценты: Значение экспоненты каждого действия делится на общую сумму. На выходе получаются чистые проценты, готовые для броска кубика.

2. Диаграмма последовательности метода (Вход и Выход флоу)

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

sequenceDiagram
    autonumber
    participant Gen as Метод 7 (StochasticGeneratorImpl)
    participant Norm as logistic_normalization()
    participant Math as Математический Процессор (JVM Math)
    participant M9 as Метод 9 (project_stochastic_seed)

    %% ВХОД МЕТОДА
    Gen->>Norm: Вызов logistic_normalization(raw_densities)
    activate Norm
    Note over Norm: Вход метода: Карта сырых, ненормированных плотностей желаний (Map)
    
    Norm->>Norm: Проход 1: Сканирование карты и поиск максимального числа
    
    %% БЕЗОПАСНЫЙ ЦИКЛ РАСЧЕТА
    loop Для каждого действия (BUY, COOK, CONSUME, WASTE)
        Norm->>Math: Вычитание максимума: shifted_x = raw_density - max_density
        Norm->>Math: Расчет степени: Math.exp(shifted_x)
        activate Math
        Math-->>Norm: Возврат: Безопасное дробное число (exp_value)
        deactivate Math
        Norm->>Norm: Накопление в общую сумму: sum_exp += exp_value
    end

    %% ФИНАЛЬНОЕ ДЕЛЕНИЕ НА СУММУ
    loop Для каждого действия в карте
        Norm->>Math: Деление: exp_value / sum_exp
        activate Math
        Math-->>Norm: Возврат: Доля вероятности действия (p_probability)
        deactivate Math
        Norm->>Norm: Запись процентов в итоговую карту результатов
    end
    
    Note over Norm: Выход метода: Строгая карта процентов (Сумма всех долей равна 1.0000)

    %% ПЕРЕДАЧА УПРАВЛЕНИЯ СЛЕДУЮЩЕМУ МЕТОДУ
    Norm-->>Gen: Возврат:probabilities Map
    deactivate Norm
    Gen->>M9: Переход к Метод 9 (Выбор итогового действия по рулетке)
    activate M9
    deactivate M9


3. Схемы данных и SQL-взаимодействие

Этот метод работает исключительно с примитивами с плавающей точкой внутри оперативной памяти и к базе данных PostgreSQL не обращается.


4. Спецификация обмена данными (Вход / Выход)

Данные передаются между внутренними калькуляторами математического ядра симулятора.

4.1. Пример входного вектора сырых плотностей желаний (Входные параметры от Метода 7)

Ситуация, когда у голодного пользователя сработал запрет пустого холодильника (все действия кроме покупки обнулены):

{
  "raw_densities_input": {
    "SCENARIO_B2B_BUY_RECEIPT": 1.0150,
    "SCENARIO_COOKING_MEAL": 0.0000,
    "SCENARIO_CONSUMING_FOOD": 0.0000,
    "SCENARIO_WASTE_DISPOSAL": 0.0000
  }
}

4.2. Пример выходного вектора выровненных процентов (Выходные параметры для Метода 9)

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

{
  "softmax_probabilities_output": {
    "SCENARIO_B2B_BUY_RECEIPT": 0.5422,
    "SCENARIO_COOKING_MEAL": 0.1526,
    "SCENARIO_CONSUMING_FOOD": 0.1526,
    "SCENARIO_WASTE_DISPOSAL": 0.1526
  }
}

Пояснение: Поскольку аргументы обнуленных интентов сдвинулись относительно максимума (\(0 - 1.015 = -1.015\)), их экспоненты дали значения \(e^{-1.015} \approx 0.3624\). Экспонента покупки дала \(e^0 = 1.0\). Общая сумма равен \(1.0 + 0.3624 + 0.3624 + 0.3624 = 2.0872\). Доля покупки: \(1.0 / 2.0872 = 0.4791\) (остальные три варианта делят остаток поровну), математика сбалансирована.


5. ЗАДАЧА ДЛЯ РАЗРАБОТЧИКА: BACKEND

Заголовок: Реализация вычислительно стабильного алгоритма Safe-Shift Softmax logistic_normalization

5.1. Что нужно сделать

  1. Написать приватный метод logisticNormalization внутри существующего сервиса StochasticGeneratorImpl.
  2. Реализовать первый проход по значениям карты для поиска максимального числа через rawDensities.values().stream().mapToDouble(Double::doubleValue).max().
  3. Запустить цикл расчета экспонент. Внутри цикла выполнять вычитание: double shiftedX = entry.getValue() - maxDensity, после чего брать экспоненту Math.exp(shiftedX). Накапливать сумму полученных экспонент в переменную sumExp.
  4. Добавить защитную проверку: если на вход пришла пустая карта или итоговая сумма экспонент равна нулю / содержит нечисловое значение Double.isNaN(), выбросить системное исключение ArithmeticException.
  5. Запустить финальный цикл нормализации, где разделить каждую локальную экспоненту на sumExp и записать полученные проценты в результирующую карту EnumMap.

6. ЗАДАЧА ДЛЯ РАЗРАБОТЧИКА: МИГРАЦИЯ

Заголовок: Поставка автоматического unit-теста стабильности математических вычислений ядра Softmax

6.1. Что нужно сделать

Этот шаг не затрагивает таблицы PostgreSQL, поэтому задача относится к категории миграции кодовых активов (Code Asset Migration). Разработчик обязан написать и включить в конвейер сборки Docker автоматический unit-тест SoftmaxStabilityTest на базе JUnit 5. Тест должен передавать в метод аномально огромные числа плотности желаний (например, 10000.0) и проверять, что метод успешно выдерживает нагрузку, не падает с ошибкой Infinity и выдает корректную сумму процентов, равную ровно 1.0000.