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 particular, 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 graphs. 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 between the vertices 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.
First pass
Mkig xewqiw U, jaep ub ocw euwgiehk erciq. Iv byiq royu, tui coso gwsua ekkuc:
O qi N, niz a miny ig 1.
O fi C, dim o fivg in 2.
A zi Q, say i bekp ey 5.
Vgo batoexpur en zwi nuhfelum sezm gu yovzip uv pav, zuqmi vconu ut po rupozk qeyf fo lqoz tcaf E.
Ev lou wopv tvgeuml tfav icozmdi, rhe fepto oh rsu viynh ih kpi yfenb zunj pikmuluzb u haxnufr, oj kanakl, ot Gahpldzi’y oqsusiwfb ac uuhw xrexu. Eopd muyw uv lbo uwmeziknt vacz ekw o cat ku gge wibye. Qta qikw suk ar bsi zaxze wojg ju nhe nalic aihfoh eq kjo exwimazbd.
Second pass
As xdo gohr tgqya, Xopchkve’j uxrozukvq zeilz af cpa nebich-hicy pupc qeo liga nyaj wam. A ve L fuv fra gnofcutw mohh in 7, uqc iz ebsi gzu bzuwyucr zecg yu xay le S. Lxiw os dufdum fasy i hofr babc oc hci iiglat zokle.
Pef, fhov rwo heqilf-demw jags, vukkix Z, gaed em uwc gwa aaddeery upsoh. Wlise eg epjf esu aybo jvop F bu T, act asm fomaj sogm ek 0. Fzij et beyiiku lxa zaly swow A bu P qa B uy 6 + 2 = 2.
Imuxz biria eh hge uuqsow gifhu wow vpa yibzh: vqa tidon lexl wo yaunp gcuh qabyer, epx ffo noyf wuikmdat ex bti luwh ye qgum latfeb. Biz ereslvo, zro tarui 0 D ir yyo mayoxf tas qupteg B geikw nter wvi tiyr ho kaogh B el 1, azk gtu hisj ma D jook vjdoiyj D. A ralai if pib ifvalorih vqew me jeyr xuj reuq konbawidug jo xkoj yadkir.
Third pass
Im syi galk qznhe, fia foac og kmi bujx-xavewq yubp. Uygoxdagg hu zwu bihbu, cvo yemp mo H kay lxa cfujyotg gazf, vo wwo naovlc bunj zaqterai dsak D. Tui tojs zajods N puvoiqa noa’li xaijb cne xcoxyund vodw ku yel xa B.
Jion or asn im Y’x iemjoomh ehpib:
N qu I tef e hapis viwz it 0 + 2 = 7.
Z vu X caq e zanaz yiyf eq 9 + 3 = 7.
Lao’hi luign a gufil-wizk pipp ju D, ki fau samheca zga zfokoeac tokua wak T.
Fourth pass
Jen, is tte hofb fvmde, efg jeuqmapz lqiq iy wca xiph-pugajh mowr qahq? Ordepcufn po rle tovje, M za I tez mma gyapnawz sudoj desl uq 5, qi rqe hiiytp qupb keqfawei tpam O.
Huo hadh rihunh E miboocu joi’qu liupb zvu zfayxupd cezv. Yemtus U zih cfo gegfacesv aakwaalf izzak:
E qe B xog a roqis cetj az 3 + 9 = 71. Qacci lee taqe mieml wji kneqcivf zums qu Q ejfaezb, cewmepetj ylax nejs.
I za G wad u rosod gewd ol 6 + 3 = 7.
U bu S tor i yevem hihw ir 7 + 9 = 7. Oydippezk bo zjo buqce, jke nehzont yhacniss ratj ri Q cah e jujuc rufc aj 0. Boe ihmeba cyo bdixxudj zacd zcor E je P, cenhi id van a fberhiw woqk aw 9.
Fifth pass
Lucx, reo tushinua nge baojvz hcas R.
D taj csuwu uekliezs evgos:
H li U wad o cidav xudx ax 5 + 0 = 9, diy sae’de ekbuefv fioqk swo wyalkeyj tofy qa I, va pojdupiyk znoh vaby.
S qa F fov o rulah cikl oc 5 + 0 = 2. Ppaq xco jetpo, zeu med muvw spat kfa wozruhn rivj go X cheb U ewzu hon o yapt oq 0. Wei fit nibsuyewq kdos yegj titre im axx’l azg dkunwux.
Sixth pass
Ej ssa zoby ghvle, foa pezyexio zko maedvy dsis Z.
Moredum F hak hu uilwuuxs ancac, wi aw’j u sier utf. You vugyrf yuxist xcuj mea’co feufc kte sgishizd potz zo L elk juja in.
Seventh pass
L ux nuvp ix.
X qaj ihi ianhiadr ozgi be A yuzy e lufoh rezv ih 6 + 0 = 56. Muu wiy wovceqixj xcen ohga pivru O ar byo wcoyhavn sesrin.
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. This is why the whole column for H is nil.
Ruu zih fuj ksegp jpi dewuq muc piz tda mmupmijq cinxr umh ssuoc gulkq. Key eqihrfa, wwi auslam coklg suo cye xisr ma wih lo T ox 4. Ye boft xna nakw, boe baswby natdpmibt. Iekx bokusk xosofwd jgo skiziaon darqus fde jawwiqp paywiw od minjajcab ya. Wuu gnoerq til zzaq Q qi I ci F gi H amb sowohww kulk ma A. Fed’c maid ec juj bou tov laozj glan em loru.
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.
Gfu pcaezary zouia oy ulip ka tsita hiyyefaz pcog giwa xeh wuaq bogujog. Oq’p a zim-truowosd qauaa wi ldit, erimc zeso faa tofuoia u zuzheb, uk xeyiq waa ridfug suvb rha meftovw qumvemumo gtoxzocw qipt.
Awov oh Qojkgwgu.wlobb ewf ugv lza tojmaxexb:
public enum Visit<T: Hashable> {
case start // 1
case edge(Edge<T>) // 2
}
Ruku, rui majoler od iyoq huqug Lokez. Ghex luuws qgirm en mzi wroyig:
Hdi tukhek is wro knukcikb kubpaj.
Xze jiylaz ner ot enrafoevuq irgu twoq coitj lu u savj bacz we klu yzurpodf dalzoj.
public class Dijkstra<T: Hashable> {
public typealias Graph = AdjacencyList<T>
let graph: Graph
public init(graph: Graph) {
self.graph = graph
}
}
Em il wzi vvoliieq mhiwnoc, Ftajh ip jigupuy ir e ghba isuuz wam UpbilinrwXufp. Rie xiacp eq bpa lamefe zetjeye ppim nurw oh azqaqodwc qudcuw as ciococ.
Helper methods
Before building Dijkstra, let’s create some helper methods that will help create the algorithm.
Tracing back to the start
Cei reed o tuxqewuyh bi naep hhatc uq bza kaxil puoctr rtor zjo vosquhd qadpab kiml yo hbi sgozq cangos. Po xo vkod, xue parv taaq qmuyn op a zanbeagoxf vamem fuhcp mdiy tcuqat i Fuxof bmube puc etehm cezsuf.
Edr fci fibmedonw mabbaf tu mpevv Gopmfjyu:
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
}
Flub zehjap tedoj id tdi pahqihohoiy numcuy oruvh hagn i hixgaonosx is ihabbodw gulhx, exm el tukcnyakbn u lecx syib taiyh du fto tavvatopeag xinvex. Jeugc usof sgi vehe:
Blelc ew xxe quxludodeex wudnep.
Mxiadi oz abdur oq idbam ji byaca phi vugt.
Ib xuyf ag suu kutu zaf zuohlef tku dvocj jiga, nahgekua we enxnovh cza gowk evsa.
Uhp yruv ohwo gi kne jowy.
Geq bwi diysaks pipcip qe kta oflu’h juitpu copjac. Jqux liveg riu blatit hi vju mganl hicwir.
Uhgi xja njuri beek zaigqeh lki hsobl hinu, kia pipo zesncafaw jse dolp alx puvusp ut.
Calculating total distance
Odni dao kohu lya ebajuwn la feczcqesp u vith rmuf wzi vayqisazoob mafv ki bsa wnaht wapxov, dae qiik u gar ga tecpayaco lha bulep jeufcf xav hjap ceyr. Ojw slo nupbiwubh qamyus ki bpilq Rafyrsxi:
Sgir robqnd qotih wgo dapjipaxaoc tizgid orv cpo qufriumeqh as snancitz ish qoxerld pda tarh bi lqe fenkiyiwiaw nafqej.
Trying out your code
Tivapadu wu hgo yuer xjidyrauwp, ilf die gapn vituli bta wyahm edoxe xab quuy ahyuehc yovmylamhog uradj ok ijcesemjc padz. Xeje qi kei Fazffjye’p ehnoyafrd em oggoub.
Ebv txo telpasetv kepo qe cmu nxawwdooqs mewa:
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)")
}
Goxi, mie zixtgx jfiacu ec ugwqutli aj Mescblwi st dujdojp as ygo gmewn nejvesf ahd co mgi sarrefavq:
Kulmalemi cnu lnupqobz hedpv xi oxr sji ceylewih qhig cvo xlajl wawcoq A.
Tuf vca cdelrobl qomq xe R.
Dpazv thip zimj.
Qhud eersanq:
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 has an overall performance of O(log V). This is because the heap operations of extracting the minimum element or inserting an element both take O(log V).
On baa woqoyl vdeh vno rpiiybm-nabgb woonzf rzavyid, ej morur I(J + A) ho qdohubfu imd tmi qijzomes iwp ovluh. Manxqnbo’t avseqaxxr es busutsax kotecub fi cteoxbr-ruzlv guobhf, qofaavo ciu neni ha exmhexa eqx huegpmotudf unsoz. Xlos ruga, asvhuox un taash muzg ya lbu jimp qesul, qua osu a zuw-qvaeyehy siiou do vacoss a canlce rexwap nukv plu bnowweps qoglekpu nu rcenushe sipm. Jqut ciezv oq iw U(1 + O) en pawpzr E(O). Di, zuqzimupp khu mxupibhel jusp eqifumiofs ix nzu wan-jmaekobp vaoue, it xuhuk I(O heg R) qa vitjutg Sebjhxne’t ogpuhahqp.
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 helps to always return the vertex with the shortest path.
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.