Алгоритм Левіта (Levit's algorithm) — алгоритм на графах, знаходить найкоротшу відстань від однієї з вершин графу до всіх інших. Алгоритм також працює для графів з ребрами від'ємної ваги. Алгоритм широко застосовується в програмуванні і технологіях.
Формулювання завдання
Приклади
Варіант 1. Дана мережа автомобільних доріг, що з'єднують міста Львівської області. Деякі дороги односторонні. Знайти найкоротші шляхи від міста Львів до кожного міста області (якщо рухатися можна тільки по дорогах).
Варіант 2. Є деяка кількість авіарейсів між містами світу, для кожного відома вартість. Вартість перельоту з A в B може бути не дорівнює вартості перельоту з B в A. Знайти маршрут мінімальної вартості (можливо, з пересадками) від Копенгагена до Барнаула.
Формальне визначення
Дано зважений орієнтований граф без петель. Знайти найкоротші шляхи від деякої вершини графу до всіх інших вершин цього графу.
Алгоритм
Нижче приведена популярна і ефективна на спеціальних графах реалізація модифікованого алгоритму Левіта. Її відмінність від «канонічної» версії полягає в додаванні елемента в чергу в початок, а не кінець. Це дозволяє досягти виграшу на деяких графах, проте призводить до експоненціального часу роботи в гіршому випадку (див. Розділ «Складність»).
Позначення
- — множина вершин графу
- — множина ребер графу
- — вага (довжина) ребра
- — вершина, відстані від якої шукаються, тобто стартова вершина
- — це поточна довжина найкоротшого шляху від вершини до вершини
- — це вершина, попередня вершині в найкоротшому шляху від вершини до .
- — вершини, відстань до яких вже обчислено (але, можливо, не остаточно);
- — вершини, відстань до яких обчислюється;
- — вершини, відстань до яких ще не обчислено.
- — зберігає номер безлічі, до якого належить вершина i.
Код
Відразу варто обумовити той факт, що наведений нижче код є не цілком працездатним, так як не задана (будь-яким чином) структура графу. У підсумку (за замовчуванням) складається ситуація, при якій є граф, що складається з десяти (значення за замовчуванням) ізольованих вершин, а найкоротший шлях шукається від вершини з індексом 1 до вершини з індексом 3 (значення за замовчуванням).
#include <iostream> // для структури pair: #include <utility> #include <vector> #include <deque> //для значення INT_MAX: #include <climits> // для функції reverse: #include <algorithm> using namespace std; typedef pair<int,int> rib; typedef vector < vector<rib> > graph; const int INFINITY = INT_MAX; //Значення за замовчуванням для роботи алгоритму (число вершин графу, індекси початкової і кінцевої вершин шляху) int defaultNumber = 10, defaultStart = 1, defaultFinish = 3; int main() { int numberOfVertices = defaultNumber, startVertex = defaultStart, finishVertex = defaultFinish; graph g (numberOfVertices); // Тут зчитуємо структуру графу (звідки-небудь, наприклад, з файлу). // До речі, розмірність і номера вершин для пошуку швидше за все // необхідно отримувати з того ж джерела. vector<int> d (numberOfVertices, INFINITY); d[startVertex] = 0; vector<int> state (numberOfVertices, 2); state[startVertex] = 1; deque<int> q; q.push_back (startVertex); vector<int> p (numberOfVertices, -1); while (!q.empty()) { int vertex = q.front(); q.pop_front(); state[vertex] = 0; for (size_t i = 0; i < g[vertex].size(); ++i) { int to = g[vertex][i].first, length = g[vertex][i].second; if (d[to] > d[vertex] + length) { d[to] = d[vertex] + length; if (state[to] == 2) q.push_back (to); else if (state[to] == 0) q.push_front (to); p[to] = vertex; state[to] = 1; } } } if (p[finishVertex] == -1) { cout << "No solution" << endl; } else { vector<int> path; for (int vertex = finishVertex; vertex != -1; vertex = p[vertex]) path.push_back (vertex); reverse (path.begin(), path.end()); for (size_t i = 0; i < path.size(); ++i) cout << path[i] + 1 << ' '; } //для запуску не з командного рядка (щоб була можливість побачити результат) cin.get(); return 0; }
Опис
Нехай масив D [1..N] буде містити поточні найкоротші довжини шляхів. Спочатку масив D заповнений значеннями «нескінченність», крім D [s] = 0. Після закінчення роботи алгоритму цей масив буде містити остаточні найкоротші відстані.
Нехай масив P [1..N] містить поточних предків. Так само як і масив D, масив P змінюється поступово по ходу алгоритму і до кінця його приймає остаточні значення.
Спочатку всі вершини поміщаються в множину M2, крім вершини V0, яка поміщається в множину M1.
На кожному кроці алгоритму ми беремо вершину з множини M1 (дістаємо верхній елемент з черги). Нехай V — це обрана вершина. Переводимо цю вершину в множину M0. Потім переглядаємо всі ребра, що виходять з цієї вершини. Нехай T — це другий кінець поточного ребра (тобто не рівний V), а L — це довжина поточного ребра.
- Якщо T належить M2, то T переносимо в множину M1 в кінець черги. DT вважаємо рівним DV + L.
- Якщо T належить M1, то намагаємося поліпшити значення DT: DT = min (DT, DV + L). Сама вершина T ніяк не пересувається в черзі.
- Якщо T належить M0, і якщо DT можна поліпшити (DT> DV + L), то покращуємо DT, а вершину T повертаємо в множину M1, поміщаючи її в початок черги.
Зрозуміло, при кожному оновленні масиву D слід оновлювати і значення в масиві P.
Складність алгоритму
При неправильній реалізації алгоритму, використовуючи замість черг M1 'і M1' 'дек і додаючи вершини з M0 в початок дека, алгоритм в гіршому випадку буде працювати за експоненціальне час, так робити не рекомендується. На реальних графах алгоритм зарекомендував себе досить добре: час його роботи .
Порівняння алгоритмів Дейкстри і Левіта
У порівнянні з методом Дейкстри метод Левіта програє в тому, що деякі вершини доводиться обробляти повторно, а виграє на більш простих алгоритмах включення і виключення вершин з множини М1. Експерименти показують, що для графів з «геометричним» походженням, тобто для графів, побудованих на основі транспортних мереж і реальних відстаней, метод Левіта виявляється найбільш швидким. Він виграє і за розміром програми.
Метод Левіта має ще й ту перевагу перед методом Дейкстри, що він застосовується в разі від'ємних довжин дуг (адже «довжина дуги» — це просто назва, яке дає нам корисні асоціації з реальністю). Якщо вважати, що значення l (u) не обов'язково є додатним, рішення задачі про найкоротший шлях значно ускладнюється.
Перша складність в тому, що втрачається просте правило методу Дейкстри для визначення остаточності обчисленого відстані до конкретної дуги. Ця складність, як ми побачимо далі, обходиться, хоча і з деякою втратою ефективності методу (доводиться перевіряти всі дуги, провідні в дану вершину).
Друга складність серйозніша: при від'ємних довжинах в графі можуть знайтися контури з від'ємною сумою довжин дуг (назвемо такі контури «від'ємними»). Додавання до шляху від'ємного контуру зменшує значення цільової функції, і чим більше обходів від'ємного контуру ми додамо, тим «краще». Позбутися від нескінченного зменшення мінімуму просто так неможливо, але є два виходи із скрутного становища (звичайно ж, вибір виходу залежить не від нас, а від розв'язуваної практичного завдання).
- Заборонити включення в шлях контурів, тобто розглядати тільки прості шляхи, але така заборона робить задачу дуже складною.
- У разі негативних контурів вважати, що завдання рішення не має, і обмежитися рішенням задачі у випадках, коли від'ємних контурів немає. У цьому випадку метод Левіта дасть необхідну оптимальне рішення, а при деякій модифікації дозволить «відловлювати» від'ємні контури.
Література
- Б. Ю. Левит. Алгоритмы поиска кратчайших путей на графе. Труды института гидродинамики СО АН СССР. Сб. «Моделирование процессов управления». Вып. 4. Новосибирск. 1971. с. 1117—148
- Б. Ю. Левит, В. Н. Лившиц. Нелинейные сетевые транспортные задачи, М. Транспорт. 1972. с.43-61
Вікіпедія, Українська, Україна, книга, книги, бібліотека, стаття, читати, завантажити, безкоштовно, безкоштовно завантажити, mp3, відео, mp4, 3gp, jpg, jpeg, gif, png, малюнок, музика, пісня, фільм, книга, гра, ігри, мобільний, телефон, android, ios, apple, мобільний телефон, samsung, iphone, xiomi, xiaomi, redmi, honor, oppo, nokia, sonya, mi, ПК, web, Інтернет
Algoritm Levita Levit s algorithm algoritm na grafah znahodit najkorotshu vidstan vid odniyeyi z vershin grafu do vsih inshih Algoritm takozh pracyuye dlya grafiv z rebrami vid yemnoyi vagi Algoritm shiroko zastosovuyetsya v programuvanni i tehnologiyah Formulyuvannya zavdannyaPrikladi Variant 1 Dana merezha avtomobilnih dorig sho z yednuyut mista Lvivskoyi oblasti Deyaki dorogi odnostoronni Znajti najkorotshi shlyahi vid mista Lviv do kozhnogo mista oblasti yaksho ruhatisya mozhna tilki po dorogah Variant 2 Ye deyaka kilkist aviarejsiv mizh mistami svitu dlya kozhnogo vidoma vartist Vartist perelotu z A v B mozhe buti ne dorivnyuye vartosti perelotu z B v A Znajti marshrut minimalnoyi vartosti mozhlivo z peresadkami vid Kopengagena do Barnaula Formalne viznachennya Dano zvazhenij oriyentovanij graf G V E displaystyle G V E bez petel Znajti najkorotshi shlyahi vid deyakoyi vershini a displaystyle a grafu G displaystyle G do vsih inshih vershin cogo grafu AlgoritmNizhche privedena populyarna i efektivna na specialnih grafah realizaciya modifikovanogo algoritmu Levita Yiyi vidminnist vid kanonichnoyi versiyi polyagaye v dodavanni elementa v chergu M 1 displaystyle M1 v pochatok a ne kinec Ce dozvolyaye dosyagti vigrashu na deyakih grafah prote prizvodit do eksponencialnogo chasu roboti v girshomu vipadku div Rozdil Skladnist Poznachennya N displaystyle N mnozhina vershin grafu M displaystyle M mnozhina reber grafu g i j displaystyle g ij vaga dovzhina rebra i j displaystyle ij s displaystyle s vershina vidstani vid yakoyi shukayutsya tobto startova vershina d i displaystyle d i ce potochna dovzhina najkorotshogo shlyahu vid vershini s displaystyle s do vershini i displaystyle i p i displaystyle p i ce vershina poperednya vershini i displaystyle i v najkorotshomu shlyahu vid vershini s displaystyle s do i displaystyle i M 0 displaystyle M0 vershini vidstan do yakih vzhe obchisleno ale mozhlivo ne ostatochno M 1 displaystyle M1 vershini vidstan do yakih obchislyuyetsya M 2 displaystyle M2 vershini vidstan do yakih she ne obchisleno s t a t e i displaystyle state i zberigaye nomer bezlichi do yakogo nalezhit vershina i Kod Vidrazu varto obumoviti toj fakt sho navedenij nizhche kod ye ne cilkom pracezdatnim tak yak ne zadana bud yakim chinom struktura grafu U pidsumku za zamovchuvannyam skladayetsya situaciya pri yakij ye graf sho skladayetsya z desyati znachennya za zamovchuvannyam izolovanih vershin a najkorotshij shlyah shukayetsya vid vershini z indeksom 1 do vershini z indeksom 3 znachennya za zamovchuvannyam include lt iostream gt dlya strukturi pair include lt utility gt include lt vector gt include lt deque gt dlya znachennya INT MAX include lt climits gt dlya funkciyi reverse include lt algorithm gt using namespace std typedef pair lt int int gt rib typedef vector lt vector lt rib gt gt graph const int INFINITY INT MAX Znachennya za zamovchuvannyam dlya roboti algoritmu chislo vershin grafu indeksi pochatkovoyi i kincevoyi vershin shlyahu int defaultNumber 10 defaultStart 1 defaultFinish 3 int main int numberOfVertices defaultNumber startVertex defaultStart finishVertex defaultFinish graph g numberOfVertices Tut zchituyemo strukturu grafu zvidki nebud napriklad z fajlu Do rechi rozmirnist i nomera vershin dlya poshuku shvidshe za vse neobhidno otrimuvati z togo zh dzherela vector lt int gt d numberOfVertices INFINITY d startVertex 0 vector lt int gt state numberOfVertices 2 state startVertex 1 deque lt int gt q q push back startVertex vector lt int gt p numberOfVertices 1 while q empty int vertex q front q pop front state vertex 0 for size t i 0 i lt g vertex size i int to g vertex i first length g vertex i second if d to gt d vertex length d to d vertex length if state to 2 q push back to else if state to 0 q push front to p to vertex state to 1 if p finishVertex 1 cout lt lt No solution lt lt endl else vector lt int gt path for int vertex finishVertex vertex 1 vertex p vertex path push back vertex reverse path begin path end for size t i 0 i lt path size i cout lt lt path i 1 lt lt dlya zapusku ne z komandnogo ryadka shob bula mozhlivist pobachiti rezultat cin get return 0 Opis Nehaj masiv D 1 N bude mistiti potochni najkorotshi dovzhini shlyahiv Spochatku masiv D zapovnenij znachennyami neskinchennist krim D s 0 Pislya zakinchennya roboti algoritmu cej masiv bude mistiti ostatochni najkorotshi vidstani Nehaj masiv P 1 N mistit potochnih predkiv Tak samo yak i masiv D masiv P zminyuyetsya postupovo po hodu algoritmu i do kincya jogo prijmaye ostatochni znachennya Spochatku vsi vershini pomishayutsya v mnozhinu M2 krim vershini V0 yaka pomishayetsya v mnozhinu M1 Na kozhnomu kroci algoritmu mi beremo vershinu z mnozhini M1 distayemo verhnij element z chergi Nehaj V ce obrana vershina Perevodimo cyu vershinu v mnozhinu M0 Potim pereglyadayemo vsi rebra sho vihodyat z ciyeyi vershini Nehaj T ce drugij kinec potochnogo rebra tobto ne rivnij V a L ce dovzhina potochnogo rebra Yaksho T nalezhit M2 to T perenosimo v mnozhinu M1 v kinec chergi DT vvazhayemo rivnim DV L Yaksho T nalezhit M1 to namagayemosya polipshiti znachennya DT DT min DT DV L Sama vershina T niyak ne peresuvayetsya v cherzi Yaksho T nalezhit M0 i yaksho DT mozhna polipshiti DT gt DV L to pokrashuyemo DT a vershinu T povertayemo v mnozhinu M1 pomishayuchi yiyi v pochatok chergi Zrozumilo pri kozhnomu onovlenni masivu D slid onovlyuvati i znachennya v masivi P Skladnist algoritmu Pri nepravilnij realizaciyi algoritmu vikoristovuyuchi zamist cherg M1 i M1 dek i dodayuchi vershini z M0 v pochatok deka algoritm v girshomu vipadku bude pracyuvati za eksponencialne chas tak robiti ne rekomenduyetsya Na realnih grafah algoritm zarekomenduvav sebe dosit dobre chas jogo roboti O M N displaystyle O MN Porivnyannya algoritmiv Dejkstri i LevitaU porivnyanni z metodom Dejkstri metod Levita prograye v tomu sho deyaki vershini dovoditsya obroblyati povtorno a vigraye na bilsh prostih algoritmah vklyuchennya i viklyuchennya vershin z mnozhini M1 Eksperimenti pokazuyut sho dlya grafiv z geometrichnim pohodzhennyam tobto dlya grafiv pobudovanih na osnovi transportnih merezh i realnih vidstanej metod Levita viyavlyayetsya najbilsh shvidkim Vin vigraye i za rozmirom programi Metod Levita maye she j tu perevagu pered metodom Dejkstri sho vin zastosovuyetsya v razi vid yemnih dovzhin dug adzhe dovzhina dugi ce prosto nazva yake daye nam korisni asociaciyi z realnistyu Yaksho vvazhati sho znachennya l u ne obov yazkovo ye dodatnim rishennya zadachi pro najkorotshij shlyah znachno uskladnyuyetsya Persha skladnist v tomu sho vtrachayetsya proste pravilo metodu Dejkstri dlya viznachennya ostatochnosti obchislenogo vidstani do konkretnoyi dugi Cya skladnist yak mi pobachimo dali obhoditsya hocha i z deyakoyu vtratoyu efektivnosti metodu dovoditsya pereviryati vsi dugi providni v danu vershinu Druga skladnist serjoznisha pri vid yemnih dovzhinah v grafi mozhut znajtisya konturi z vid yemnoyu sumoyu dovzhin dug nazvemo taki konturi vid yemnimi Dodavannya do shlyahu vid yemnogo konturu zmenshuye znachennya cilovoyi funkciyi i chim bilshe obhodiv vid yemnogo konturu mi dodamo tim krashe Pozbutisya vid neskinchennogo zmenshennya minimumu prosto tak nemozhlivo ale ye dva vihodi iz skrutnogo stanovisha zvichajno zh vibir vihodu zalezhit ne vid nas a vid rozv yazuvanoyi praktichnogo zavdannya Zaboroniti vklyuchennya v shlyah konturiv tobto rozglyadati tilki prosti shlyahi ale taka zaborona robit zadachu duzhe skladnoyu U razi negativnih konturiv vvazhati sho zavdannya rishennya ne maye i obmezhitisya rishennyam zadachi u vipadkah koli vid yemnih konturiv nemaye U comu vipadku metod Levita dast neobhidnu optimalne rishennya a pri deyakij modifikaciyi dozvolit vidlovlyuvati vid yemni konturi LiteraturaB Yu Levit Algoritmy poiska kratchajshih putej na grafe Trudy instituta gidrodinamiki SO AN SSSR Sb Modelirovanie processov upravleniya Vyp 4 Novosibirsk 1971 s 1117 148 B Yu Levit V N Livshic Nelinejnye setevye transportnye zadachi M Transport 1972 s 43 61