var Dataset = function Dataset(raw) { var me = this; // public this.nodes = []; this.links = []; this.matrix = []; this.maxDistance = 0; // from CLRS: Introduction to Algorithms, pg. 691 this.computeShortestPaths = function(W) { var n = W.rows; var L = [] L[1] = W; var m = 1; while (m < n - 1) { L[2 * m] = extendShortestPaths(L[m], L[m]); m *= 2; } L[m].rows = n; L[m].cols = n; setMaxDistance(L[m]); return L[m]; } // private var states = {}; // from CLRS: Introduction to Algorithms, pg. 688 function extendShortestPaths(L, W) { var n = L.rows; var Lp = []; for (var i = 0; i < n; ++i) { Lp[i] = []; for (var j = 0; j < n; ++j) { Lp[i][j] = { x: j, y: i, z: Number.MAX_VALUE }; for (var k = 0; k < n; ++k) { Lp[i][j].z = Math.min(Lp[i][j].z, L[i][k].z + W[k][j].z); } } } Lp.rows = n; Lp.cols = n; return Lp; } function setMaxDistance(M) { M.forEach(function(row, i) { row.forEach(function(val, j) { if (val.z > me.maxDistance) { me.maxDistance = val.z; } }); }); } // constructor if (raw) { // obtain unique states var allStates = []; for (var link in raw) { allStates.push(raw[link].first); allStates.push(raw[link].second); } var filteredStates = allStates.filter(function(v, i, s) { return s.indexOf(v) === i; }); // assign all unique states an id or node index for (var idGen = 0; idGen < filteredStates.length; ++idGen) { states[filteredStates[idGen]] = idGen; this.nodes.push({ id: idGen, name: filteredStates[idGen], connections: 0 }); } // assemble connections using node index for (var link in raw) { this.links.push({ source: states[raw[link].first], target: states[raw[link].second], graph: 0 }); } // assemble adjacency matrix this.nodes.forEach(function(node, i) { me.matrix[i] = d3.range(me.nodes.length).map(function(j) { return { x: j, y: i, z: 0 }; }) }); // initalize costs to infinity this.matrix.forEach(function(row, j) { row.forEach(function(value, i) { value.z = Number.MAX_VALUE; }); }); // create initial adjacent connections // the cost of adjacent nodes is 1 // the cost of self nodes is 0 this.links.forEach(function(link, i) { // connect from first to second me.matrix[link.source][link.target].z = 1; // connect from second to first me.matrix[link.target][link.source].z = 1; // connect from first to first me.matrix[link.source][link.source].z = 0; // connect from second to second me.matrix[link.target][link.target].z = 0; // retain the number of direct connections // source node is connected to target node me.nodes[link.source].connections += 1; // target node is connected to source node me.nodes[link.target].connections += 1; }); this.matrix.rows = this.nodes.length; this.matrix.cols = this.nodes.length; } }