Created
July 11, 2012 07:27
-
-
Save bellbind/3088707 to your computer and use it in GitHub Desktop.
[javascript]dijkstra algorithm (with custom data structure)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Dijkstra Algorithm Example | |
// - Using suite data structure make algorithm clearer | |
// compile graph data to vertices structure: {"label": Vertex, ...} | |
// - Graph: [{from: "label", to: "label". cost: number}, ...] | |
// - Vertex: {label: string, edges: [{dest: Vertex, cost: number}, ...]} | |
var compileVertices = function (graph) { | |
var vs = {}; | |
graph.forEach(function (edge) { | |
if (!vs[edge.from]) vs[edge.from] = {label: edge.from, edges: []}; | |
if (!vs[edge.to]) vs[edge.to] = {label: edge.to, edges: []}; | |
vs[edge.from].edges.push({dest: vs[edge.to], cost: edge.cost}); | |
vs[edge.to].edges.push({dest: vs[edge.from], cost: edge.cost}); | |
}); | |
return vs; | |
}; | |
// find the least cost route from vertex start to vertex goal | |
// - returns: {cost: number, route: [start, ..., goal]} | |
var findRoute = function (start, goal) { | |
var less = function (a, b) {return a.cost < b.cost;}; | |
var pqueue = []; | |
pqueuePush(pqueue, {cost: 0, route: [start]}, less); | |
while (true) { | |
var min = pqueuePop(pqueue); | |
var last = min.route[min.route.length - 1]; | |
if (last === goal) return min; | |
last.edges.forEach(function (edge) { | |
if (min.route.indexOf(edge.dest) >= 0) return; //[OPT]cut back link | |
var node = { | |
cost: min.cost + edge.cost, | |
route: min.route.concat([edge.dest]) | |
}; | |
pqueuePush(pqueue, node, less); | |
}); | |
} | |
}; | |
// utility: priority queue | |
var pqueuePush = function (pqueue, value, less) { | |
for (var i = 0; i < pqueue.length; i++) { | |
if (less(value, pqueue[i])) { | |
pqueue.splice(i, 0, value); | |
return; | |
} | |
} | |
pqueue.push(value); | |
}; | |
var pqueuePop = function (pqueue) { | |
return pqueue.shift(); | |
}; | |
// example bi-directional graph of route connections | |
var graph = [ | |
{from: "a", to: "b", cost: 4}, | |
{from: "a", to: "c", cost: 5}, | |
{from: "a", to: "d", cost: 2}, | |
{from: "b", to: "c", cost: 2}, | |
{from: "b", to: "d", cost: 3}, | |
{from: "b", to: "e", cost: 2}, | |
{from: "c", to: "f", cost: 6}, | |
{from: "d", to: "e", cost: 6}, | |
{from: "e", to: "f", cost: 4}, | |
]; | |
var vertices = compileVertices(graph); | |
console.log(findRoute(vertices.a, vertices.f)); | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
result: