January 6, 2024
Dijkstra's Algorithm
Rasmda berilgan graph Vaznli graph (weighted graph) deyiladi. Bunday graphlarning bir nuqtasidan boshqa nustasigacha bo'lgan vazni bo'ladi (rasmda bir nuqtalar orasidagi masofa keltirilgan). Bunday graphlarda ikki nuqta orasidagi eng kichik masofani topishlik uchun "Dijkstra algoritmi" ishlatiladi. BFS (breadth first search) algoritmi bilan bir nuqtadan ikkinchi nuqtaga olib boruvchi eng kichik yo'lni topgan bo'lsak (unda masofalar yo'q edi, segmentlar bor edi), Dijkstra algoritmi bilan eng kichik masofani topib olamiz.
Quyida weigthed graph va Dijkstra algoritmining codedagi implementatsiyasini ko'rob chiqamiz:
type WeightedGraphType = Record<string, Record<string, number>>
class WeightedGraph {
private graph: WeightedGraphType
constructor () {
this.graph = {}
}
print () {
return this.graph
}
// graphga uzel (edge) lar qo'shish uchun
addEdge (key: string, value: Record<string, number>) {
this.graph[key] = value
}
// start nuqtadan qolgan barcha nuqtalargacha bo'lgan
// masofani qaytaradi
dijkstra(start: string): Record<string, number> {
// start nuqtadan qolgan barcha nuqtalargacha bo'lgan eng
// kichik masofani saqlash uchun
const distances: Record<string, number> = {};
// tashrif buyurilgan nuqtalarni saqlash uchun
const visited = new Set<string>();
// graph keylarini massivga olamiz // ['a', 'b' ..., 'g']
let nodes = Object.keys(this.graph);
// har bir nuqta uchun boshlang'ich masofani Inifinity
// qilib belgilab olamiz
for (let node of nodes) {
distances[node] = Infinity;
}
// boshlang'ich nuqtadan o'zigacha bo'lgan masofa
// 0 bo'lgani uchun uni 0 ga tenglaymiz
distances[start] = 0;
// barcha nodelar bo'ylab siklda aylanib chiqamiz
while (nodes.length) {
// nodelarni kamayish tartibida tartiblab olamiz va
// undan eng yaqin bo'lgan nodeni olamiz
nodes.sort((a, b) => distances[b] - distances[a]);
let closestNode = nodes.pop()!;
// agar eng yaqin nodegacha bo'lgan masoda hali ham Infinity bo'lsa,
// u holda u siklni to'xtatamiz
if (distances[closestNode] === Infinity) {
break
}
// eng yaqin node'ni tashrif buyurilganlarga qo'shamiz
visited.add(closestNode);
// node'ning har bir qo'shnilari bo'ylab yurib chiqamiz
for (let neighbor in this.graph[closestNode]) {
// agar qo'shni node'ga hali tashrif buyurilmagan bo'lsa
if (!visited.has(neighbor)) {
// node'dan uning qo'shinisigacha bo'lgan masofani hisoblaymiz
let newDistance = distances[closestNode] + this.graph[closestNode][neighbor];
// agar hisoblangan masofa ayni paytdagi masofadan kichik bo'lsa
// u holda ayni masofani o'zgartiramiz (eng kichik masofa)
if (newDistance < distances[neighbor]) {
// eng kichik masofani update qilamiz
distances[neighbor] = newDistance;
}
}
}
}
// start nuqtadan qolgan nuqtalargacha (nodelar) bo'lgan eng
// kichik masofalarni qaytaramiz
return distances;
}
// bir nuqtadan ikkinchi nuqtagacha bo'lgan eng kichik masofa
shortDistance (start: string, end: string): number | undefined {
return this.dijkstra(start)[end]
}
}
// Weighted graph instance
const weightedGraph = new WeightedGraph()
// uzel (edge) larni qo'shib chiqamiz
weightedGraph.addEdge('a', {b: 2, c: 1})
weightedGraph.addEdge('b', {f: 7})
weightedGraph.addEdge('c', {d: 5, e: 2})
weightedGraph.addEdge('d', {f: 2})
weightedGraph.addEdge('e', {f: 1})
weightedGraph.addEdge('f', {g: 1})
weightedGraph.addEdge('g', {})
console.log(weightedGraph.print())
// {
// a: { b: 2, c: 1 },
// b: { f: 7 },
// c: { d: 5, e: 2 },
// d: { f: 2 },
// e: { f: 1 },
// f: { g: 1 },
// g: {}
// }
console.log(weightedGraph.dijkstra('a')) // { a: 0, b: 2, c: 1, d: 6, e: 3, f: 4, g: 5 }
// a nuqtadan g nuqtagacha bo'lgan masofani topish
console.log(weightedGraph.shortDistance('a', 'g')) // 5Telegram kanalim: https://t.me/elyor_dev