3.8 KiB
3.8 KiB
#алгоритмы #поиск
В алгоритме Дейкстры каждому сегменту присваивается число (вес), а алгоритм Дейкстры находит путь с наименьшим суммарным весом
Алгоритм Дейкстры работает только с графами, в которых нет циклов, где все ребра неотрицательны
Cостоит из четырех шагов:
- Найти узел с наименьшей стоимостью (то есть узел, до которого можно добраться за минимальное время)
- Обновить стоимости соседей этого узла
- Повторять, пока это не будет сделано для всех узлов графа
- Вычислить итоговый путь
Для реализации понадобятся три хеш-таблицы: граф, родители, стоимости. Хеш таблицы стоимостей и родителей будут обновляться по ходу работы алгоритма.
Существует более эффективный вариант этого алгоритма. Он использует структуру данных, называемую очередью с приоритетом. Эта очередь строится на основе другой структуры данных — кучи.
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' ] }
Связаные темы:
Источники:



