Base/Knowledges/IT/Алгоритмы/Поиск/Алгоритм Дейкстры (Dijkstra's algorithm).md
2026-02-23 19:52:05 +03:00

125 lines
3.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#алгоритмы #поиск
![[dijkstra.gif]]
> В алгоритме Дейкстры каждому сегменту присваивается число (вес), а алгоритм Дейкстры находит путь с наименьшим суммарным весом
![[Pasted image 20250116202010.png]]
Алгоритм Дейкстры работает только с графами, в которых нет циклов, где
все ребра неотрицательны
Cостоит из четырех шагов:
1. Найти узел с наименьшей стоимостью (то есть узел, до которого можно добраться за минимальное время)
2. Обновить стоимости соседей этого узла
3. Повторять, пока это не будет сделано для всех узлов графа
4. Вычислить итоговый путь
![[Pasted image 20250116203308.png]]
Для реализации понадобятся три хеш-таблицы: граф, родители, стоимости. Хеш таблицы стоимостей и родителей будут обновляться по ходу работы алгоритма.
![[Pasted image 20250116203221.png]]
Существует более эффективный вариант этого алгоритма. Он использует структуру данных, называемую очередью с приоритетом. Эта очередь строится на основе другой структуры данных — кучи.
```javascript
const findLowestCostNode = (costs, processed) => {
let lowestCost = Infinity;
let lowestCostNode = null;
Object.entries(costs).forEach(([node, cost]) => {
if (!processed.includes(node) && cost < lowestCost) {
lowestCost = cost;
lowestCostNode = node;
}
});
return lowestCostNode;
};
const dejsktra = (graph, [from, to]) => {
const costs = {
[to]: Infinity,
...graph[from],
};
const parents = {};
Object.keys(graph[from]).forEach(key => parents[key] = from);
const processed = [];
let lowestCostNode = from;
while(lowestCostNode) {
const neighbours = graph[lowestCostNode] || {};
Object.keys(neighbours).forEach(neighbour => {
let cost = costs[lowestCostNode] + neighbours[neighbour];
if (!costs[neighbour]) {
costs[neighbour] = Infinity;
}
if (cost < costs[neighbour]) {
costs[neighbour] = cost;
parents[neighbour] = lowestCostNode;
}
})
processed.push(lowestCostNode);
lowestCostNode = findLowestCostNode(costs, processed);
}
const path = [to];
let parent = parents[to];
while (parent) {
path.push(parent);
parent = parents[parent];
}
return {
value: costs[to],
path: path.reverse()
}
};
const testGraph = {
a: { b: 2, f: 6 },
b: { c: 4 },
c: { d: 8, g: 6 },
d: { h: 3 },
e: { b: 1, g: 5, },
f: { e: 1, g: 7 },
g: { d: 2, h: 4, j: 2,},
h: { j: 1 },
};
const complexGraph = {
a: { b: 4, c: 2, d: 7 },
b: { e: 3, f: 1, g: 5 },
c: { f: 4, h: 2 },
d: { h: 6, i: 3 },
e: { j: 2, k: 4 },
f: { j: 5, l: 2 },
g: { k: 3, m: 4 },
h: { l: 5, n: 2 },
i: { n: 4, o: 3 },
j: { m: 1, n: 6 },
k: { n: 2, o: 5 },
l: { o: 4 },
m: { o: 3 },
n: { o: 2 },
o: {}
};
console.log(dejsktra(testGraph, ['a', 'j'])); // { value: 14, path: [ 'a', 'b', 'c', 'g', 'j' ] }
console.log(dejsktra(complexGraph, ['a', 'o'])); // { value: 8, path: [ 'a', 'c', 'h', 'n', 'o' ] }
```
Связаные темы:
- [[Граф (Graph)]]
- [[Поиск в ширину (Breadth-first search)]]
Источники:
- [[Адитья Бхаргава - Грокаем Алгоритмы]]