Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Що означає глобально оптимальне рішення в жадібному алгоритмі?». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)**Глобально оптимальне рішення** - це таке рішення, яке мінімізує або максимізує цільову функцію серед усіх допустимих рішень задачі. У контексті жадібних алгоритмів це означає, що послідовність локально кращих виборів за заданим критерієм приводить до найкращого можливого підсумкового рішення. Це вірно лише для задач, які мають оптимальну підструктуру і жадібну властивість вибору (зазвичай доводиться «обмінним аргументом»). **Ключове:** коректність зазвичай доводять «обмінним аргументом» - показують, що будь-яку оптимальну відповідь можна перетворити на жадібну без втрати якості.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення## Коротка відповідь Глобально оптимальне рішення - це таке рішення, яке мінімізує або максимізує цільову функцію серед усіх допустимих рішень задачі. У контексті жадібних алгоритмів це означає, що послідовність локально кращих виборів за заданим критерієм приводить до найкращого можливого підсумкового рішення. Це вірно лише для задач, які мають оптимальну підструктуру і жадібну властивість вибору (зазвичай доводиться «обмінним аргументом»). ## Детальне пояснення ### Визначення - Локально оптимальний вибір: дія, яка здається найкращою «тут і зараз» за деяким жадібним критерієм, не заглядаючи далеко наперед. - Глобально оптимальне рішення: рішення, кращого за яке не існує серед усіх допустимих рішень (за цільовою функцією). Для задач на мінімум - має найменшу вартість, для задач на максимум - найбільшу вигоду. - Жадібний алгоритм: будує рішення покроково, щоразу роблячи локально оптимальний вибір у надії отримати глобальний оптимум. ### Коли жадібний алгоритм гарантує глобальний оптимум - Оптимальна підструктура: оптимальне рішення задачі містить оптимальні рішення її підзадач. - Жадібна властивість вибору: існує оптимальне рішення, що починається з локально кращого кроку за обраним критерієм. Найчастіше коректність доводять «обмінним аргументом»: показують, що будь-яку оптимальну відповідь можна «обмінами» перетворити на таку, де перший крок збігається з жадібним, не погіршивши якість. Повторюючи кроки, отримуємо всю жадібну відповідь, рівну глобальному оптимуму. ### Типові задачі, де жадібний дає глобальний оптимум - Вибір максимальної кількості інтервалів (активностей), що не перетинаються - сортування за часом закінчення. - Мінімальне остовне дерево (Kruskal/Prim) - «властивість розрізу» гарантує глобальну мінімальність. - Оптимальне префіксне кодування (Хаффман) - найменші частоти об'єднуються першими. - Розмін монет у «канонічних» системах номіналів (наприклад, 1, 5, 10, 25). ### Приклад (жадібний глобально оптимальний): вибір інтервалів, що не перетинаються Жадібний вибір: завжди брати інтервал із найменшим часом закінчення, який не перетинається з уже вибраними. ```js function selectActivities(intervals) { // intervals: [{ start: number, end: number }] intervals.sort((a, b) => a.end - b.end); const result = []; let lastEnd = -Infinity; for (const it of intervals) { if (it.start >= lastEnd) { result.push(it); lastEnd = it.end; } } return result; } // Приклад const intervals = [ { start: 1, end: 3 }, { start: 2, end: 5 }, { start: 4, end: 7 }, { start: 1, end: 2 } ]; console.log(selectActivities(intervals)); // Жадібний дає глобальний максимум за кількістю вибраних інтервалів ``` ### Контрприклад (жадібний не дає глобальний оптимум): розмін монет Номінали 1, 3, 4; сума 6. Жадібний за великими монетами обере 4 + 1 + 1 (3 монети), але глобально оптимально 3 + 3 (2 монети). ```js function greedyCoins(coins, amount) { coins = [...coins].sort((a, b) => b - a); const taken = []; for (const c of coins) { while (amount >= c) { amount -= c; taken.push(c); } } return { coins: taken, count: taken.length, remainder: amount }; } console.log(greedyCoins([1, 3, 4], 6)); // { coins: [4, 1, 1], count: 3, remainder: 0 } <-- не глобальний оптимум ``` ### Як усе ж отримати глобальний оптимум, коли жадібний ламається (DP) Динамічне програмування гарантує глобальний оптимум, перебираючи підзадачі і запам'ятовуючи найкращі результати. ```js function minCoinsDP(coins, amount) { const INF = amount + 1; const dp = new Array(amount + 1).fill(INF); const prev = new Array(amount + 1).fill(-1); dp[0] = 0; for (let a = 1; a <= amount; a++) { for (const c of coins) { if (a >= c && dp[a - c] + 1 < dp[a]) { dp[a] = dp[a - c] + 1; prev[a] = c; } } } if (dp[amount] === INF) return { count: -1, coins: [] }; const out = []; let a = amount; while (a > 0) { out.push(prev[a]); a -= prev[a]; } return { count: out.length, coins: out }; } console.log(minCoinsDP([1, 3, 4], 6)); // { count: 2, coins: [3, 3] } <-- глобально оптимально ``` ### Практичні поради для співбесіди - Спершу сформулюйте критерій оптимальності і допустиму множину рішень. - Перевірте оптимальну підструктуру і спробуйте сформулювати жадібний критерій вибору. - Спробуйте «обмінний аргумент»: чи можна будь-яку оптимальну структуру перетворити так, щоб перший крок збігався з вашим жадібним? - Якщо швидко знаходите контрприклад - жадібний, ймовірно, не гарантує глобальний оптимум; розгляньте DP/пошук. ### Підсумок Глобально оптимальне рішення - найкраще з усіх допустимих. Жадібні алгоритми досягають його лише на задачах з оптимальною підструктурою і жадібною властивістю вибору, що зазвичай доводиться обмінним аргументом. В іншому випадку застосовують динамічне програмування або інші методи.Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.