Skip to content

Instantly share code, notes, and snippets.

@stella-yc
Last active August 24, 2023 20:46
Show Gist options
  • Save stella-yc/49a7b96679ab3bf06e26421fc81b5636 to your computer and use it in GitHub Desktop.
Save stella-yc/49a7b96679ab3bf06e26421fc81b5636 to your computer and use it in GitHub Desktop.
Dijkstra's Algorithm in Javascript using a weighted graph
const problem = {
start: {A: 5, B: 2},
A: {C: 4, D: 2},
B: {A: 8, D: 7},
C: {D: 6, finish: 3},
D: {finish: 1},
finish: {}
};
const lowestCostNode = (costs, processed) => {
return Object.keys(costs).reduce((lowest, node) => {
if (lowest === null || costs[node] < costs[lowest]) {
if (!processed.includes(node)) {
lowest = node;
}
}
return lowest;
}, null);
};
// function that returns the minimum cost and path to reach Finish
const dijkstra = (graph) => {
// track lowest cost to reach each node
const costs = Object.assign({finish: Infinity}, graph.start);
// track paths
const parents = {finish: null};
for (let child in graph.start) {
parents[child] = 'start';
}
// track nodes that have already been processed
const processed = [];
let node = lowestCostNode(costs, processed);
while (node) {
let cost = costs[node];
let children = graph[node];
for (let n in children) {
let newCost = cost + children[n];
if (!costs[n]) {
costs[n] = newCost;
parents[n] = node;
}
if (costs[n] > newCost) {
costs[n] = newCost;
parents[n] = node;
}
}
processed.push(node);
node = lowestCostNode(costs, processed);
}
let optimalPath = ['finish'];
let parent = parents.finish;
while (parent) {
optimalPath.push(parent);
parent = parents[parent];
}
optimalPath.reverse();
const results = {
distance: costs.finish,
path: optimalPath
};
return results;
};
console.log(dijkstra(problem));
@hamzalak
Copy link

hamzalak commented Dec 8, 2021

The algorithm is visiting all the nodes , is there any way to find the smallest path without visiting let's say the other edges

image

@byoung2
Copy link

byoung2 commented Jan 15, 2022

@hamzalak Maybe you could remove all nodes that are not the finish node and that have no children before running the algorithm or as a check within the algorithm.

@thiagoarantes
Copy link

What about undirected graphs? How can we simplify the problem if we consider that all edges have the same cost (1)?

@byoung2
Copy link

byoung2 commented Feb 28, 2022

@thiagoarantes I think the algorithm still works with undirected graphs, but when calculating the shortest path, you only consider the outgoing direction. So for something like flight routing, segments between cities are always bidirectional, but we assume the shortest route will go toward the destination and never backtrack. Even if it did backtrack, it adds to the cost, so the direct route would be selected anyway.

If all edges have the same cost, the algorithm still works, you just optimize for number of segments versus the total cost. That's how it works for my application (routing messages in a P2P network). For my use case, there is no difference in cost to route from A to B versus A to C, so the cost is all 1, so the total number of segments will determine the total cost...A to Z to C would be 2 while A to B to C to Z would be 3.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment