Skip to content
Snippets Groups Projects
Commit f24d6f10 authored by Selby, Nicholas Stearns's avatar Selby, Nicholas Stearns
Browse files

Dijkstra

parent d166d5ad
Branches
No related tags found
No related merge requests found
var Graph = (function (undefined) {
var extractKeys = function (obj) {
var keys = [], key;
for (key in obj) {
Object.prototype.hasOwnProperty.call(obj,key) && keys.push(key);
}
return keys;
}
var sorter = function (a, b) {
return parseFloat (a) - parseFloat (b);
}
var findPaths = function (map, start, end, infinity) {
infinity = infinity || Infinity;
var costs = {},
open = {'0': [start]},
predecessors = {},
keys;
var addToOpen = function (cost, vertex) {
var key = "" + cost;
if (!open[key]) open[key] = [];
open[key].push(vertex);
}
costs[start] = 0;
while (open) {
if(!(keys = extractKeys(open)).length) break;
keys.sort(sorter);
var key = keys[0],
bucket = open[key],
node = bucket.shift(),
currentCost = parseFloat(key),
adjacentNodes = map[node] || {};
if (!bucket.length) delete open[key];
for (var vertex in adjacentNodes) {
if (Object.prototype.hasOwnProperty.call(adjacentNodes, vertex)) {
var cost = adjacentNodes[vertex],
totalCost = cost + currentCost,
vertexCost = costs[vertex];
if ((vertexCost === undefined) || (vertexCost > totalCost)) {
costs[vertex] = totalCost;
addToOpen(totalCost, vertex);
predecessors[vertex] = node;
}
}
}
}
if (costs[end] === undefined) {
return null;
} else {
return predecessors;
}
}
var extractShortest = function (predecessors, end) {
var nodes = [],
u = end;
while (u !== undefined) {
nodes.push(u);
u = predecessors[u];
}
nodes.reverse();
return nodes;
}
var findShortestPath = function (map, nodes) {
var start = nodes.shift(),
end,
predecessors,
path = [],
shortest;
while (nodes.length) {
end = nodes.shift();
predecessors = findPaths(map, start, end);
if (predecessors) {
shortest = extractShortest(predecessors, end);
if (nodes.length) {
path.push.apply(path, shortest.slice(0, -1));
} else {
return path.concat(shortest);
}
} else {
return null;
}
start = end;
}
}
var toArray = function (list, offset) {
try {
return Array.prototype.slice.call(list, offset);
} catch (e) {
var a = [];
for (var i = offset || 0, l = list.length; i < l; ++i) {
a.push(list[i]);
}
return a;
}
}
var Graph = function (map) {
this.map = map;
}
Graph.prototype.findShortestPath = function (start, end) {
if (Object.prototype.toString.call(start) === '[object Array]') {
return findShortestPath(this.map, start);
} else if (arguments.length === 2) {
return findShortestPath(this.map, [start, end]);
} else {
return findShortestPath(this.map, toArray(arguments));
}
}
Graph.findShortestPath = function (map, start, end) {
if (Object.prototype.toString.call(start) === '[object Array]') {
return findShortestPath(map, start);
} else if (arguments.length === 3) {
return findShortestPath(map, [start, end]);
} else {
return findShortestPath(map, toArray(arguments, 1));
}
}
return Graph;
})();
...@@ -63,6 +63,7 @@ ...@@ -63,6 +63,7 @@
<script type="text/javascript" src="d3.v3.min.js"></script> <script type="text/javascript" src="d3.v3.min.js"></script>
<script type="text/javascript" src="jquery.min.js"></script> <script type="text/javascript" src="jquery.min.js"></script>
<script type="text/javascript" src="require.js"></script> <script type="text/javascript" src="require.js"></script>
<script src="graph.js"></script>
<script src="goog/base.js"></script> <script src="goog/base.js"></script>
<script> <script>
goog.require("goog.structs.PriorityQueue") goog.require("goog.structs.PriorityQueue")
......
function Manager(self) {
self.manager = this;
this.ports = [];
this.numports = 0;
var map = {0:{1:4,2:3},1:{0:4,3:1},2:{0:3,3:1},3:{1:1,2:1}};
var graph = new Graph(map);
const HOP_COUNT = 2;
this.setup = function(numports) {
this.numports = numports;
this.ports = new Array(numports).fill(-1);
};
this.connect = function(port, id) {
if (!(port < this.numports)) {
return;
}
if (self.id != id) {
var prevId = this.ports[port];
if (prevId >= 0) {
self.disconnect(prevId);
}
this.ports[port] = id;
self.connect(id);
}
};
this.disconnect = function(port) {
if (!(port < this.numports)) {
return;
}
var prevId = this.ports[port];
if (prevId >= 0) {
self.disconnect(prevId);
}
this.ports[port] = -1;
}
this.send = function(port, name, msg) {
if (port < this.numports && this.ports[port] >= 0) {
self.send(this.ports[port], 'message', {name: name, obj: msg});
}
};
this.sendTo = function(id, msg) {
var path = graph.findShortestPath(self.id, id);
var nextNode = path[1];
for (var p = 0; p < this.numports; p++) {
if (this.ports[p] === parseInt(nextNode)) {
this.send(p, id, msg);
return;
}
}
}
// Flood Packet: ['F' , HOP COUNT , ORIGINAL SENDER ID , COST 1 , RECIPIENT 1 , COST 2 , RECIPIENT 2 ...]
this.flood = function() {
for (var p = 0; p < this.numports; p++) {
this.send(this.ports[p], 'F', self.id);
}
}
this.onReceive = function(from, o) {
var port = this.ports.indexOf(from);
if (port == -1) {
return;
}
self.log(`got message '${o.name}' on port ${port}: '${o.obj}'`);
if (o.name != self.id) {
this.sendTo(o.name,o.obj);
}
};
self.on('message', this.onReceive, this);
}
module.exports = Manager;
var net = require("./network"),
manager = require('./manager');
const numClients = 4;
const startupDelay = 100;
var clients = [];
for (var i = 0; i < numClients; i++) {
c = new net.Client();
c.use(manager);
clients.push(c);
}
clients[0].init(function() {
this.delay(startupDelay, function() {
this.manager.setup(2);
this.manager.connect(0, 1);
this.manager.connect(1, 2);
});
this.delay(1000, function() {
//this.manager.send(0, 'Special Delivery', 'Surprise!!!');
this.manager.sendTo(3, 'Tell 3 I said I love her.');
});
});
clients[1].init(function() {
this.delay(startupDelay, function() {
this.manager.setup(2);
this.manager.connect(0, 0);
this.manager.connect(1, 3);
});
});
clients[2].init(function() {
this.delay(startupDelay, function() {
this.manager.setup(2);
this.manager.connect(0, 0);
this.manager.connect(1, 3);
});
});
clients[3].init(function() {
this.delay(startupDelay, function() {
this.manager.setup(2);
this.manager.connect(0, 1);
this.manager.connect(1, 2);
});
});
for (var i = 0; i < numClients; i++) {
net.add(1, clients[i]);
}
net.run(100 * 1000); // runs for 100 seconds
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment