Лабораторна робота 19. Квадратичний план заряджання акумуляторного парку
Коротко про роботу
Ви побудуєте квадратичну модель заряджання чотирьох акумуляторних модулів у CVXPY. Після solver-а потрібно перевірити межі, баланс потужності, dual values та сформувати незалежний KKT-аудит розв’язку.
Ця робота виконується після лекцій 26. Вона спирається лише на матеріал, який уже пройдено до цього заняття.
▶ Відкрити робочий зошит у браузері
1. Ситуація
Чотири акумуляторні модулі мають бажані потужності та різну ціну відхилення від них. Разом вони повинні видати задану потужність, залишитися у власних межах і виконати обмеження на дисбаланс.
Головне питання роботи: Як побудувати QP у CVXPY і незалежно перевірити, що отриманий план справді допустимий та оптимальний з числової точки зору?
2. Що вже потрібно знати
Перед початком достатньо розуміти такі речі з попередніх лекцій:
- квадратична ціль;
- PSD/PD матриця;
- QP;
- декларативний запис моделі в CVXPY;
- значення двоїстих змінних;
Якщо якийсь пункт забувся, поверніться до відповідної лекції. У цій роботі нова теорія не вводиться без пояснення.
3. Як перейти від ситуації до математики
CVXPY дозволяє коротко описати QP, але математичний зміст не зникає. Ви все одно повинні знати, що означає змінна, кожне обмеження і кожне число у цілі.
Спочатку сформулюйте зміст задачі словами. Лише після цього записуйте формули й код. Це зменшує ризик правильно порахувати не ту задачу.
4. Ваш варіант
У notebook змініть тільки один рядок:
STUDENT_X = 1 # поставте свій номер 1..30
Номер варіанта змінює числа, але не дає готового способу розв’язання. Основна частина роботи однакова для всіх: побудувати правильну модель, зробити потрібний вибір і перевірити результат.
Після запуску комірки «Дані вашого варіанта» notebook покаже всі числа, потрібні для роботи. Вручну підставляти STUDENT_X у формули не потрібно. Спочатку подивіться на отримані дані та підпишіть, що означає кожен масив або параметр.
5. Де тут треба подумати
CVXPY дуже зручний, але його короткий код може приховати математику. Перед solve() поясніть кожну змінну й обмеження. Після solve() перераховуйте рівності, межі та KKT-показники з NumPy.
Перед тим як писати код, дайте собі відповідь на два питання:
- Чому статус
optimalвід CVXPY ще не замінює незалежну перевірку? - Які нев’язки KKT повинні бути малими, щоб числовому розв’язку можна було довіряти?
Відповідь не треба робити довгою. Достатньо 1–2 речень на кожне питання. Це допомагає перевірити, що ви розумієте задачу до запуску обчислень.
6. Послідовність роботи
Крок 1. Перевірити матрицю \(Q\)
Знайдіть її власні значення і поясніть, чому це важливо для опуклості QP.
Крок 2. Оголосити змінну CVXPY
Створіть вектор із чотирьох потужностей.
Крок 3. Записати ціль і обмеження
Окремо підпишіть загальну потужність, нижні та верхні межі та дисбаланс. У цій роботі дисбаланс записуємо як \(x_1+x_2-x_3-x_4\le L\), де \(L\) показано у даних варіанта.
Крок 4. Розв’язати задачу
Збережіть status, значення цілі, x.value та значення двоїстих змінних.
Крок 5. Перевірити допустимість NumPy-кодом
Перерахуйте рівність, межі та додаткову нерівність незалежно від CVXPY.
Крок 6. Перевірити KKT на доступному рівні
Сформуйте стаціонарність з отриманих значення двоїстих змінних та оцініть максимальну нев’язку.
7. Python
Використовуйте: NumPy, CVXPY/cvxpy-base, Clarabel.
Не намагайтеся вмістити всю роботу в одну велику комірку. Зручніше мати окремі невеликі блоки: дані → модель → обчислення → перевірка → висновок. Назви змінних повинні показувати їхній зміст.
8. Локальна самоперевірка
У робочому notebook наперед створені назви змінних, які читає автоматична перевірка. Не перейменовуйте їх. Ви самі пишете спосіб розв’язання, але фінальний результат записуєте у визначені змінні.
| Змінна | Що записати |
|---|---|
status |
рядок зі статусом CVXPY, очікується optimal/optimal_inaccurate |
x_solution |
чотири оптимальні потужності |
objective_value |
0.5*(x-target).T@Q@(x-target) |
dual_values |
словник {"equality": ..., "lower": ..., "upper": ..., "imbalance": ...} |
complementarity_residual |
найбільший добуток «множник × запас обмеження» за модулем |
equality_residual |
sum(x_solution)-R |
bound_violation |
максимальне порушення lower/upper |
imbalance_violation |
max((x1+x2-x3-x4)-imbalance_limit,0) |
stationarity_residual |
найбільша за модулем компонента рівняння стаціонарності |
Після виконання всіх кроків запустіть комірку «Локальна самоперевірка». Для вашого STUDENT_X вона читає наперед обчислені контрольні значення та порівнює з ними всі результатні змінні з таблиці вище. Числові значення порівнюються з указаним допуском; логічні, текстові та дискретні результати — точно. Для множин індексів порядок елементів не має значення, а для напрямів власних векторів враховується еквівалентність v та -v.
✅ OKозначає, що всі результатні змінні збігаються з контрольними значеннями в межах заданих допусків.❌означає, що біля конкретної змінної буде вказано, яке порівняння не пройдено.
Самоперевірка не замінює короткий предметний висновок: після OK поясніть своїми словами, що означає отриманий результат у ситуації цієї лабораторної.
9. Що має бути у звіті
Звіт не повинен бути переписаним notebook. Покажіть вихідні дані, ключові проміжні результати, перевірки та короткий висновок своїми словами. У звіті обов’язково мають бути:
- номер вашого варіанта;
- вихідні дані, які реально використовувалися;
- ключовий проміжний результат, на якому ґрунтується рішення;
- фінальний результат;
- незалежна числова перевірка;
- коротке пояснення, що цей результат означає в початковій прикладній ситуації.
Наприкінці дайте відповідь на головне питання лабораторної одним коротким абзацом.
10. Контрольні питання
- Чому перевірка власних значень \(Q\) потрібна до
solve()?
Показати відповідь
Вона підтверджує опуклість квадратичної частини й допомагає зрозуміти, чому знайдений локальний оптимум є глобальним у цій задачі.- Чому
status="optimal"недостатньо?