---
name: variational-designer
description: Демонстрация метафоры вариационного проектирования (каскадный коллапс) через численную модель. Сравнение детерминированного градиентного спуска vs вариационного поиска с шумом. Генерирует PNG-визуализацию с тремя панелями (функционал → критические точки → устойчивость).
---

# Вариационный проектировщик

Модель: поиск пути в потенциальном поле с препятствиями.
Метафора трёхстадийного каскадного коллапса:
1. **Функционал** — потенциальное поле + препятствия
2. **Критические точки** — градиентный спуск (детерминированный) vs градиент + шум (вариационный)
3. **Устойчивость** — вторая вариация (собственные значения гессиана)

## Запуск

```bash
cd ~/Desktop && python3 variational_designer.py
```

Выход: `~/Desktop/output/variational_designer.png` + `report.json`

## Зависимости

- Python 3.10+
- `pip3 install --user numpy matplotlib` (если нет)

## Параметры для экспериментов

В `main()` можно менять:
- `obstacles` — список препятствий (x, y, радиус)
- `noise_scale` — амплитуда вариационного шума (0.0 = детерминированный спуск)
- `n_trials` — количество вариационных траекторий
- `start` — стартовая точка

## Смысл

Детерминированный спуск → одно решение, застревание в первом локальном минимуме.
Вариационный поиск → множество уникальных решений, выход из локальных ям.
Свобода вариации — не баг, а конституирующий элемент системы.

## Питфоллы

- **Emoji в matplotlib на macOS:** Дефолтный шрифт DejaVu Sans не содержит emoji. В warnings будут `Glyph missing` — косметика, на результат не влияет. Для подавления: убрать emoji из cat_labels.
- **Граничные эффекты устойчивости:** Вариационные траектории, упирающиеся в границу поля, возвращают `None` из `check_stability()` из-за нехватки соседей для конечных разностей. Это артефакт, не характеристика решения.
- **Воспроизводимость:** Детерминированный спуск детерминирован. Вариационный использует `np.random.RandomState(trial * 42)` — seed фиксирован, но при изменении `n_trials` результаты меняются. Для полной воспроизводимости фиксировать `np.random.seed()`.
- **Размер поля:** При `size < 50` градиент становится слишком грубым. При `size > 200` — медленно.
