Skip to content

Instantly share code, notes, and snippets.

@colus001
Last active July 3, 2017 11:29
Show Gist options
  • Save colus001/98c8c8dfc389d88427d1376fe1d1128b to your computer and use it in GitHub Desktop.
Save colus001/98c8c8dfc389d88427d1376fe1d1128b to your computer and use it in GitHub Desktop.
Dijkstra algorithm in Javascript
const _ = require('lodash')
const adjacency = (paths, start, end) => {
const visited = [], queues = [start], matrix = {}
let minPath = null
_.each(paths, (path, key) => { matrix[key] = {} })
matrix[start][start] = {
from: start,
cost: 0,
}
while (queues.length > 0) {
const lastIndex = visited[visited.length - 1]
let index
if (!lastIndex) {
index = queues.shift()
} else {
let idx = findMinIndex(matrix, lastIndex)
index = queues.splice(queues.indexOf(idx), 1)[0]
}
if (visited.includes(index)) continue
minPath = findSmallestCost(matrix, lastIndex)
matrix[index][index] = matrix[index][index] || minPath
const obj = paths[index]
_.each(paths, (path, key) => {
if (key === index) return
const last = (matrix[lastIndex] && matrix[lastIndex][key]) || {
cost: Infinity
}
const row = {
from: index,
cost: minPath ? obj[key] + minPath.cost : obj[key] || Infinity,
}
if (!visited.includes(key)) {
matrix[index][key] = last.cost > row.cost ? row : last
}
if (
_.keys(obj).includes(key)
&& !visited.includes(key)
) queues.push(key)
})
if (!visited.includes(index)) visited.push(index)
}
return matrix
}
const getShortestPath = (paths, start, end) => {
const matrix = adjacency(paths, start)
pathObj = matrix[end][end]
const path = [end]
const cost = pathObj.cost
while (pathObj.cost > 0) {
path.unshift(pathObj.from)
pathObj = matrix[pathObj.from][pathObj.from]
}
return {
path,
cost,
}
}
module.exports = {
adjacency,
getShortestPath,
}
function findMinIndex (matrix, lastIndex) {
const prevMatrix = matrix[lastIndex]
let idx
_.each(prevMatrix, (item, key) => {
if (key === lastIndex) return
if (!idx) idx = key
if (prevMatrix[idx].cost > item.cost) idx = key
})
return idx
}
function findSmallestCost (matrix, lastIndex) {
let smallest = null
_.each(matrix[lastIndex], (item, key) => {
if (key === lastIndex) return
if (!smallest) return smallest = item
if (smallest.cost > item.cost) smallest = item
})
return smallest
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment