2.2 «Жадібні» алгоритми
«Жадібний» алгоритм на кожному кроці забезпечує локально найкращий вибір – з надією, що кінцеве рішення буде оптимальним.
Суть «жадібного» алгоритму пояснимо на простій задачі. Допустимо, що у продавця є монети вартістю в 20, 10, 5 копійок та 1 копійка. Йому необхідно вернути решту 56 копійок. Алгоритм, який розв’язує цю нескладну задачу полягає у тому, що вибирається монета найбільшої вартості (20 копійок), але не більше 56 копійок. Потім знаходимо різницю 56-20=36. Оскільки 20<36, то наступною монетою буде монета найбільшої вартості (20 копійок). Цю монету продавець добавляє до у список решти (20+20=40). Так як наступна різниця 56-40=16<20, то наступною монетою найбільшої вартості буде 10 копійок. Цю монету добавляємо у список решти: 20+20+10=50. Очевидно, що наступними монетами у списку решти будуть монети вартістю 5 копійок та 1 копійка, що у підсумку дає розв’язок поставленої задачі (20+20+20+10+5++1=56), яка є оптимальною у сенсі мінімальної кількості монет із даного набору.
У даному випадку «жадібність» алгоритму полягає у тому, що на кожному кроці вибирається монета найбільшої вартості, виходячи із умови , де -1, 2, …, - номера наборів монет вартостей ; - список решти. У загальному випадку на кожному кроці «жадібний» алгоритм вибирає той варіант, який є оптимально локальним в тому чи іншому сенсі.
Тепер розглянемо не тривіальний приклад – задачу, яка називається задачею комівояжера. Суть її у наступному. Задане певне число населених пунктів, які сполучені між собою дорогами. Відомі віддалі між такими населеними пунктами. Необхідно обійти всі населені пункти таким чином, щоб сумарний пройдений шлях був найкоротшим і при цьому комівояжер повернувся у початковий пункт.
Допустимо, що є шість населених пунктів, віддалі між якими задані у вигляді табл. 2.1
Знайдемо довжину кожного із чотирьох маршрутів. Для маршруту, який показаний на рис. 2.2,а, маємо
.
Із табл. 2.1 знаходимо, що ; ; ; ; ; і відповідно .
Таблиця 2.1 – Віддалі між населеними пунктами
-
Віддаль між населеними пунктами, км
Населені пункти
0
4,7
1,7
15,7
15,4
18,0
4,7
0
3,4
11,8
10,7
14,5
1,7
3,4
0
15,0
14,1
17,6
15,7
11,8
15,0
0
2,4
5,1
15,4
10,7
14,1
2,4
0
4,1
18,0
14,5
17,6
5,1
4,1
0
Аналогічно знаходимо, що
,
,
.
На рис. 2.2 показані можливі варіанти маршруту комівояжера по шести населених пунктах.
а б
в г
Рисунок 2.2 – Можливі маршрути комівояжера по шести населених пунктах
Аналіз отриманих результатів показує, що маршрут , який показаний на рис 2.2,б є найкоротшим із чотирьох можливих.
Відмітимо, маршрути, які показані на рис. 2.2 можуть розглядатися як графи, у яких вершини – населені пункти, а ребра – шляхи, які з’єднують відповідні населені пункти. Кожне ребро графа має вагу, яка дорівнює віддалі між двома населеними пунктами, що з’єднані відповідним ребром.
Робота «жадібного» алгоритму для задачі комівояжера полягає у тому, що спочатку розглядаються найкоротші ребра. Нове ребро добавляється до уже наявних ребер у тому випадку, коли це не приводить до появи вершини зі степеню три і більше та не утворює цикл (замкнутий маршрут) за винятком випадку, коли кількість включених ребер дорівнює кількості вершин графа.
Множина ребер, що вибрані у відповідності зі зазначеними умовами, утворюють сукупність не з’єднаних шляхів; така ситуація зберігається до виконання останнього кроку, тоді єдиний шлях, що залишився, замикається, утворюючи замкнутий маршрут.
Застосуємо даний алгоритм до сформульованої задачі комівояжера (табл. 2.1). Спочатку вибираємо ребро , так як воно є найкоротшим і має довжину 1,7. Наступним найкоротшим ребром є ребро довжиною 2,4. Після перших двох кроків маємо множину ребер - . До множини включаємо наступне найкоротше ребро довжиною 3,4. Тепер і до отриманої множини слід було б включити ребро , довжина якого 4,1, але воно може з ребром утворити цикл. Тому ребро не включаємо до множини . Після четвертого кроку множина залишається незмінною. Із ребер, що залишились, найкоротшим є ребро , довжина якого – 5,1; ребро долучаємо до множини , тобто . . Наступним найкоротшим ребром є ребро , довжини якого – 10,7, яке включаємо до множини . Отже, Наступним претендентом до включення у множину є ребро довжиною 11,8. Оскільки на поточному кроці алгоритму умови включення ребра у множину не виконуються, то ребро не включаємо у множину . Після семи кроків залишилось сім ребер - , , , , , і , довжини яких відповідно , 14,5, 15,0, 15,4, 15,7 17,6 та 18,0. Неважко переконатись, що умовам включення до множини із семи ребер відповідає тільки ребро , яке і замикає шлях комівояжера. Таким чином, отримали шлях , довжина якого . Отриманий маршрут співпадає з найкоротшим маршрутом , тобто можна стверджувати, що отриманий маршрут є оптимальним.