Dijkstras algoritme er en grafalgoritme opfundet af den hollandske videnskabsmand Edsger Dijkstra i 1959 . Finder de korteste veje fra et af grafens hjørner til alle de andre. Algoritmen virker kun for grafer uden kanter med negativ vægt . Algoritmen er meget udbredt i programmering, for eksempel bruges den af OSPF- og IS-IS- routingprotokollerne .
Mulighed 1. Givet et netværk af veje, der forbinder byerne i Moskva-regionen. Nogle veje er ensrettede. Find de korteste veje fra by A til hver by i regionen (hvis du kun kan bevæge dig ad veje).
Mulighed 2. Der er et antal flyvninger mellem verdens byer, prisen er kendt for hver. Prisen på en flyvning fra A til B er muligvis ikke lig med prisen på en flyvning fra B til A. Find minimumsomkostningsruten (eventuelt med overførsler) fra København til Barnaul .
Givet en vægtet rettet [1] graf uden buer med negativ vægt [2] . Find de korteste veje fra et eller andet toppunkt på grafen til alle andre toppunkter på denne graf.
Hvert toppunkt fra V er tildelt en etiket — den mindste kendte afstand fra dette toppunkt til en .
Algoritmen arbejder trin for trin - ved hvert trin "besøger" den ét toppunkt og forsøger at reducere etiketter.
Algoritmen afsluttes, når alle hjørner er besøgt.
Initialisering .
Etiketten for selve toppunktet a antages at være 0, etiketterne for de andre toppunkter er sat til uendelig.
Dette afspejler, at afstandene fra a til andre toppunkter endnu ikke er kendt.
Alle hjørner af grafen er markeret som ubesøgte.
Algoritme trin .
Hvis alle hjørner er besøgt, afsluttes algoritmen.
Ellers vælges toppunktet u med minimumsmærket fra de endnu ikke besøgte toppunkter .
Vi overvejer alle mulige ruter, hvor u er det næstsidste punkt. De toppunkter, som kanterne fra u fører til, kaldes naboerne til dette toppunkt. For hver nabo til u , undtagen dem, der er markeret som besøgt, skal du overveje en ny vejlængde svarende til summen af værdierne af den aktuelle etiket u og længden af kanten, der forbinder u med denne nabo.
Hvis den modtagne længdeværdi er mindre end etiketværdien for naboen, skal etiketværdien erstattes med den opnåede længdeværdi. Efter at have overvejet alle naboerne, markerer vi toppunktet u som besøgt og gentager trinnet i algoritmen .
Overvej udførelsen af algoritmen på eksemplet på grafen vist i figuren.
Lad det være påkrævet at finde de korteste afstande fra 1. toppunkt til alle de andre.
Cirklerne angiver hjørnerne, linjerne angiver stierne mellem dem (kanterne på grafen).
Antallet af hjørner er angivet i cirklerne, deres vægt er angivet over kanterne - længden af stien.
Ved siden af hvert toppunkt er der markeret en rød etiket - længden af den korteste vej til dette toppunkt fra toppunkt 1.
Første skridt .
Vertex 1 har minimumsmærket. Vertices 2, 3 og 6 er dens naboer.
Den første nabo til toppunkt 1 er igen toppunkt 2, fordi længden af stien dertil er minimal.
Længden af stien til den gennem toppunkt 1 er lig med summen af værdien af etiketten for toppunkt 1 og længden af kanten, der går fra 1. til 2., det vil sige 0 + 7 = 7.
Dette er mindre end den nuværende etiket for toppunkt 2, uendelig, så den nye etiket for 2. toppunkt er 7.
Vi udfører en lignende operation med to andre naboer til 1. vertex - 3. og 6.
Alle naboer til node 1 er kontrolleret.
Den nuværende minimumsafstand til topmøde 1 betragtes som endelig og er ikke genstand for revision.
Kryds det ud af grafen for at markere, at dette toppunkt er blevet besøgt.
Andet trin .
Igen finder vi det "nærmeste" af de ubesøgte hjørner. Dette er toppunkt 2 mærket 7.
Igen forsøger vi at reducere etiketterne for naboerne til det valgte toppunkt og forsøger at passere gennem dem gennem det 2. toppunkt. Vertex 2's naboer er toppunkter 1, 3 og 4.
Den første (i rækkefølge) nabo til toppunkt 2 er toppunkt 1. Men det er allerede besøgt, så vi gør ikke noget med 1. toppunkt.
Den næste nabo er toppunkt 3, da den har minimumsmærket.
Hvis du går til det gennem 2, så vil længden af en sådan sti være lig med 17 (7 + 10 = 17). Men den aktuelle etiket for det tredje toppunkt er 9, hvilket er mindre end 17, så etiketten ændres ikke.
En anden nabo til toppunkt 2 er toppunkt 4.
Hvis du går til det gennem 2., så vil længden af en sådan sti være lig med summen af den korteste afstand til 2. toppunkt og afstanden mellem toppunkter 2 og 4, det vil sige 22 (7 + 15 = 22) .
Siden 22< sætter vi etiketten for toppunkt 4 til 22.
Alle naboer til top 2 er blevet set, vi fryser afstanden til den og markerer den som besøgt.
Tredje trin .
Vi gentager trinnet i algoritmen ved at vælge toppunkt 3. Efter dens "behandling" får vi følgende resultater:
Næste trin .
Vi gentager trinnet i algoritmen for de resterende hjørner. Disse vil være henholdsvis hjørnerne 6, 4 og 5.
Afslutning af algoritmeudførelsen .
Algoritmen afsluttes, når alle hjørner er besøgt.
Resultatet af algoritmen er synligt i den sidste figur: den korteste vej fra toppunkt 1 til 2 er 7, til 3 er 9, til 4 er 20, til 5 er 20, til 6 er 11.
Hvis alle ubesøgte hjørner på et tidspunkt er markeret med uendelighed, betyder det, at disse hjørner ikke kan nås (det vil sige, at grafen ikke er forbundet ). Så kan algoritmen færdiggøres før tidsplanen.
Nedenfor er koden til implementering af algoritmen i programmeringssproget Java . Denne implementeringsmulighed er ikke den bedste, men viser tydeligt den mulige implementering af algoritmen:
klasse Dijkstra { dobbelt [] dist = ny dobbelt [ GV () ] ; Kant [] pred = ny Kant [ GV () ] ; public Dijkstra ( WeightedDigraph G , int s ) { boolean [] markeret = ny boolean [ GV () ] ; for ( int v = 0 ; v < GV ( ); v ++ ) dist [ v ] = Dobbelt . POSITIVE_INFINITY ; MinPQplus < Double , Integer > pq ; pq = new MinPQplus < Double , Integer > (); \\ Prioritetskø _ dist [ s ] = 0,0 ; pq . sætte ( dist [ s ] , s ); while ( ! pq . isEmpty ()) { intv = pq . _ delmin (); if ( markeret [ v ] ) fortsæt ; markeret ( v ) = sand ; for ( Edge e ( v )) { int w = e . til (); if ( dist [ w ]> dist [ v ] + e . vægt ()) { dist [ w ] = dist [ v ] + e . vægt (); pred [ w ] = e ; pq . indsætte ( dist [ w ] , w ); } } } } }Tildel
For alle andre end , tildeler vi .
Farvel . Lad være et toppunkt med minimum
Til alle dem, der
hvis da
lave om
lave om
I den enkleste implementering kan en matrix af tal bruges til at gemme tallene d [ i ], og en matrix af booleske variabler kan bruges til at lagre medlemskabet af et element i sættet U.
I begyndelsen af algoritmen antages afstanden for det indledende toppunkt at være nul, og alle andre afstande er fyldt med et stort positivt tal (større end den maksimalt mulige vej i grafen ). Flag-arrayet er fyldt med nuller. Så starter hovedsløjfen.
Ved hvert trin i sløjfen leder vi efter et toppunkt med en minimumsafstand og et flag lig nul. Derefter sætter vi flaget til 1 i det og kontrollerer alle de hjørner, der støder op til det . Hvis afstanden i dem (i ) er større end summen af afstanden til det aktuelle toppunkt og længden af kanten, så reducerer vi den. Sløjfen slutter, når flagene for alle hjørner bliver lig med 1, eller når alle hjørner med flaget er 0 . Sidstnævnte tilfælde er muligt, hvis og kun hvis grafen G er afbrudt.
Lade være længden af den korteste vej fra toppunkt til toppunkt . Lad os bevise ved induktion , at ligheden gælder i det øjeblik, vi besøger et hvilket som helst vertex .
Grundlag. Toppunktet besøges først . I dette øjeblik .
Trin. Lad os sige, at vi har valgt en top at besøge . Lad os bevise det i dette øjeblik . Til at begynde med bemærker vi, at for ethvert toppunkt holder det altid (algoritmen kan ikke finde en sti, der er kortere end den korteste af alle eksisterende). Lad være den korteste vej fra til . Toppen er på og ikke besøgt. Derfor er sættet af ubesøgte hjørner ikke tomt. Lad være den første ubesøgte toppunkt på , og være den, der går forud (derfor besøgt). Da stien er den korteste, er den del, der fører fra gennem til , også den korteste, derfor .
Ved induktionshypotesen, i det øjeblik, man besøgte vertexet , , Derfor modtog vertexet en etiket, der ikke var større end . Derfor ,. Hvis , så er induktionstrinnet bevist. Ellers, da vertex i øjeblikket er valgt og ikke , er etiketten minimal blandt de ubesøgte, dvs. Ved at kombinere dette med , har vi , hvilket skulle bevises.
Fordi algoritmen afsluttes, når alle toppunkter er besøgt, på det tidspunkt for alle toppunkter.
Kompleksiteten af Dijkstras algoritme afhænger af, hvordan vertexet v findes , hvordan sættet af ubesøgte hjørner er lagret, og hvordan etiketterne opdateres. Angiv med n antallet af hjørner, og med m antallet af kanter i grafen G .
de skjulte konstanter i de asymptotiske omkostningsestimater er store, og brugen af Fibonacci-dynger er sjældent passende: almindelige binære ( d-ary ) dynger er mere effektive i praksis.
Alternativer til dem er tykke dynger, tynde dynger og Brodal-dynger , som har de samme asymptotiske estimater, men mindre konstanter [4] .
Algoritmer til grafsøgning | ||
---|---|---|
Uoplyste metoder | ||
Informerede metoder | ||
Genveje | ||
Minimumspændende træ | ||
Andet |