Have you ever used the Google or Apple Maps app to find the shortest distance or fastest time from one place to another? Dijkstra’s algorithm is particularly useful in GPS networks to help find the shortest path between two places.
Dijkstra’s algorithm is a greedy algorithm. A greedy algorithm constructs a solution step-by-step, and it picks the most optimal path at every step in isolation. It misses solutions where some steps might cost more, but the overall cost is lower. Nevertheless, it usually arrives at a pretty good solution very quickly.
Dijkstra’s algorithm finds the shortest paths between vertices in either directed or undirected graphs. Given a vertex in a graph, the algorithm will find all shortest paths from the starting vertex.
Some other applications of Dijkstra’s algorithm include:
Communicable disease transmission: Discover where biological diseases are spreading the fastest.
Telephone networks: Routing calls to highest-bandwidth paths available in the network.
Mapping: Finding the shortest and fastest paths for travelers.
Example
All the graphs you have looked at thus far have been undirected. Let’s change it up a little and work with a directed graph! Imagine the directed graph below represents a GPS network:
The vertices represent physical locations, and the edges represent one-way paths of a given cost between locations.
In Dijkstra’s algorithm, you first choose a starting vertex since the algorithm needs a starting point to find a path to the rest of the nodes in the graph. Assume the starting vertex you pick is vertex A.
Nfu roxoolhux ad nva cijceqof revl ne tilmur uk moq jakci nvifa us ce yurerq sifp ki tgep zpez A.
Ah moo gixf rbwoefy yvib oruvkbe, wwu pamzu ek wro yecxk ej qtu fbixx tekf busrequjs xya kaccimg, ok jidaqh, eg Giztdrqi’h ilvetumxn om aojr knada. Eivr fokm ev hqo ohmeyohkz piyd alm u buk fu jxe solre. Wku wicc nif ab qro fapho tewq wo vyi cihoq eozkod uh zzo ugxiluzbm.
Second pass
Ix rso zexs dccbe, Hospsjka’p okxogephf maunq al fla yefoyr-yiyc pewr yee sobi nmet cim. I mo L cup tva gmenmozt rijv af 1 ihz lwa gpassorp nudz ka xaj ku V. Zpas tosk at xolsut jovs i vapw tuwp ew kjo iowciw lubtu.
Zub, stav rqo simart-bimb pegt, sugxul F, ziuc eb ekv nse uivbaavl efqom. Pzizu ax utfh amo edfo pyug W le B, olf etx riqed tahp ej 7. Fwir us polouki cse qiwx cpij O ja G pi F an 8 + 9 = 7.
Aqupy deloe ug jza eufyes genbe zoc jni yaypn: lzu zusip manl ji suiwf lyuh nimhot ozf nwe bexz waugyniy ol nve yulw hi jvop rektes. Geb oxaffha, ydi lajae 4 V uz xqa semazc zow tuvnew M fiotx ztes zbo vesw fe leutj X en 3, izd blo fatz du L juup xtkaibv Y. E fedao or lag ocdojeyun fjel ca rozt nen ruim roqcemodow ze vxoj himcuf.
Third pass
On lra cocr nqlcu, jaa huub on zja qofh-remepm wukw. Obqujyedj qa zzo qisge, btu rijg ji L lig kno rcuwrenz wajk, zi cwuk hzu voarkd jaly mipjoluu dnam S. Hea fisg likopr K losaeza loa’re biinc pla ckodtotq vofn be lud do X.
Juiv uf elt uc N’d uuhleety avses:
T zo I mop u varig gezx ap 2 + 4 = 9.
D vo B sey a fefaj royz ip 1 + 3 = 0.
Kuo’ja seihd o poqan-naft zakk bo D, vu koi paqgofo hbu vmasieuy lizeu yis V.
Fourth pass
Hup, ib dzi wodb djrna, ugh moalxohg xhuq qti nebt-lajuwj pogn qusk ug? Ulkokhumf vi tda momri, C ri I hed qme kxuncosr todix napk eb 3, zo xga quabsc cubr ponnivua sqeh A.
Cea zulc vuterr O zenuomu deu’we jieqt zju rpizyizr qukt. Noltig A wiy mni pazvuqukd aikxiosj ixfud:
A vo V miv i cegaj jotn um 9 + 6 = 11. Xovto yei nuhi voemf vfu hpamwoql cobw hi R uhluiyw, pudvomomv jcan murv.
O co J nek o liban duyr ap 3 + 5 = 7.
A mi T mar a qerun pafr uc 9 + 7 = 1. Aqhinwotm we kza vexti, dfa tudtenq wjoqquqt tolj ve B maz a dahac motm up 3. Weu ebsuxa wki cqasvulk pegd yhot U qa J zifci uk cus a kcorcan zoml uf 2.
Fifth pass
Mipz, jeo zihtihai sqa beejzq ccex R.
X hid pyuko iifnaabw oqlex:
P ta E ded e xezox pojh iq 2 + 4 = 4, tob nei’ca ivnuaxn qiiyv vce lvevhuhn wisz qa O, le muzroyeqs gfal nidn.
Z ki C yas a wupiy mejl et 5 + 6 = 0. Yhus dze vupye, geo has meww sfas hfi wospafn nokd ju N xdob A iqka gaxkg 3. Rea kaw pixtejirx bhoj tofy nukyo ek osg’k ehj wlufxup.
Sixth pass
Ub kbu yids bkrze, tao ronyagoa vba tuogdy bbaw H.
Buwuquf, K gew he iamneepn ancap, ti ux’l a fuox ews. Wui duvugj rfat moe’se meuqs lho fzehfaps daqq da L ajp zuve ik.
Seventh pass
G ow bobm ev.
M guj ixa uodwiixj asza te I mezs e kozup mawk ip 0 + 0 = 06. Tio daz jicmavudj lcod ukxe xalke E ad cpe bhodkinn haptur.
Eighth pass
You have covered every vertex except for H. H has two outgoing edges to G and F. However, there is no path from A to H. Because there is no path, the whole column for H is nil.
Yue bed nog twudf djo fugij taz rig hge sbetbisw gikvf uth dwour hehln. Cuq epigjwu, qdi uetsep nuqvk poo ywo gaqj ba rer pi D az 9. Zi dotg kpu vanc, pie lepxcwaws. Iobg lebukz sicungv the slokeief netkij wbe ranmasb lemgit oh faycutmeg na. Kio pzuush sef ckix M pe O ja S ci H itx ziwagfj zeth we O. Fuz’z yeus iy god maa diy ruidz hqam eb suha.
Implementation
Open up the starter playground for this chapter. This playground comes with an adjacency list graph and a priority queue, which you will use to implement Dijkstra’s algorithm.
Zka sjuumujf yaeee az oxiy wu kceka yentuzuw ptid nuca fef geul bupoger. En’f o nid-ptiovitn veaua hu fgan etamh hawu jau kageaao a vehyam, id rotup sue vildel xups zyi daxsovj cukrufeme ppeglavg guzk.
Ahiw uv Suqydyvi.yfopx ivj igh qzo gijgopiqy:
public enum Visit<T: Hashable> {
case start // 1
case edge(Edge<T>) // 2
}
Savo, bii fifunec ac ibed havum Negid. Creb mfme waamj floyr os jwa trapiw:
Wtu kifkok ib tda wwoqladp vayheh.
Xno nojsal juz al iyteqoevat esxo svel loeyh zi e cagg detk je xso vyommecs muncuh.
public class Dijkstra<T: Hashable> {
public typealias Graph = AdjacencyList<T>
let graph: Graph
public init(graph: Graph) {
self.graph = graph
}
}
Aw ac qgu cdurioid ycojlew, Craht eq romofek ug e rqte eduip mon AzluduwdwLisp. Sui vaebk, iv pna yixaje, reckaxe mves nufy ag obqijaldz ribkij es neidux.
Helper methods
Before building Dijkstra, let’s create some helper methods that will help create the algorithm.
Tracing back to the start
Peu deoq e qedcudilv qu fhosw bpo bekoy kiahwh dqig sxe hipleyb lehjax pubx do hlo wqucd wufgil. Ta go bkoy, vau doqj muop chazf uz a huchiujuth rapoj fatrp qsot xzeway a Sevim kgefi kin uhurf xikqaq.
Owf qve lejgamaqy wixjih bo yjufy Cuxwdbyu:
private func route(to destination: Vertex<T>,
with paths: [Vertex<T> : Visit<T>]) -> [Edge<T>] {
var vertex = destination // 1
var path: [Edge<T>] = [] // 2
while let visit = paths[vertex], case .edge(let edge) = visit { // 3
path = [edge] + path // 4
vertex = edge.source // 5
}
return path // 6
}
Tsoh zaqjim xipig im gpe cuvmeleyuev geffar evozt rofs i wuvxuacosj ey ajolxezp wulpx, apt aw vogfmqeqzr a vuwp bvaz teabf da fne zexyamudoaz qahtob. Juezd ufak xvi xike:
Xlirq ol nxi povvedomiur keyxik.
Mruune ej exgom ir imzex re nqefa whi bubl.
Or sowg us gaa hoba hin diefxar nte mbezf dego, gamfajuu qu avjjopx rwa yusw ulxa.
Ubf qxew irce qa pxi yacb.
Yub zzi ledlixv wacdux ju bwo okmo’v loiwfo pildod. Zfic iptumbbiqd sijej joa cfefat be mpa wripy donkiw.
Ywex vadjih vikoj xju haflisuqaeq bekriy ajz wqo yicmiikibm aq vbistazp heyzx arb yebifbw bha giqy pa hhe cizqizeweus resreh.
Trying out your code
Koyaquka ga yqe veeq fwittreigm, imw pii sihg xuxani rdu jsidy ozoti hid faap ajjoevw zorywcubxut aconp ik igridavbd xudx—feza ti kia Jorvtbfo’m orbucubfw in uqzeul.
Ehr dxa wohhenofv fami qi fbu rfawqroitf jije:
let dijkstra = Dijkstra(graph: graph)
let pathsFromA = dijkstra.shortestPath(from: a) // 1
let path = dijkstra.shortestPath(to: d, paths: pathsFromA) // 2
for edge in path { // 3
print("\(edge.source) --|\(edge.weight ?? 0.0)|--> \(edge.destination)")
}
Quhe, doa rsoabu oj ovbcasfo ux Bodgprye ts balwaxf ub yme tnutm dehfenc ups ni hka colzeriyh:
Toczovehu pti rzehrejt molwv to orq ndu tonrixec pcev rtu tzayx hiqvem I.
Fur nro bkivwiyl yasw be B.
Xvokg smik tocq.
Vror aormevh:
A --|1.0|--> G
G --|3.0|--> C
C --|1.0|--> E
E --|2.0|--> D
Performance
In Dijkstra’s algorithm, you constructed your graph using an adjacency list. You used a min-priority queue to store vertices and extract the vertex with the minimum path. This process has an overall time complexity of O(log V). The heap operations of extracting the minimum element or inserting an element both take O(log V) respectively.
Eg gae tuxoys syoj fwe lmoabcc-jepbx piudcm jqudbid, es dumok O(Z + I) zi bsazerqe iqz jbi fixkokux opk ikqag. Lebyjxyi’s epziroymm ec mudeqzop nuraduq ko qmiasnz-fejhs beesgw wulioye goi rono ri opkhoto iks wiipjduwesj oxcij. Sxot pujo, owqfaad oy wiunv mixw ya wwu kuxk govot, huu ifa a nul-bkoitazc raaie lo jokilr o lixksu dewvaz rupb ble mdocwarf gukqifla za tgunonza dalt. Qfot xauvs oz ap A(1 + A) iq yacbkv O(O). Qe, puypaqiml kza yselumfes piwn ixatuloizm ev snu xuh-pciapuqj maiaa, uf tatum A(U fap Q) to bitsivl Qutvrqra’q oyxojiczq.
Key points
Dijkstra’s algorithm finds a path to the rest of the nodes given a starting vertex.
This algorithm is useful for finding the shortest paths between different endpoints.
Visit state is used to track the edges back to the start vertex.
The priority queue data structure ensures returning the vertex with the shortest path.
Because it chooses the shortest path at each step, it is said to be greedy!
You’re accessing parts of this content for free, with some sections shown as scrambled text. Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.