51 lines
		
	
	
		
			1.2 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			51 lines
		
	
	
		
			1.2 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| var _ = require("../lodash");
 | |
| 
 | |
| module.exports = floydWarshall;
 | |
| 
 | |
| var DEFAULT_WEIGHT_FUNC = _.constant(1);
 | |
| 
 | |
| function floydWarshall(g, weightFn, edgeFn) {
 | |
|   return runFloydWarshall(g,
 | |
|     weightFn || DEFAULT_WEIGHT_FUNC,
 | |
|     edgeFn || function(v) { return g.outEdges(v); });
 | |
| }
 | |
| 
 | |
| function runFloydWarshall(g, weightFn, edgeFn) {
 | |
|   var results = {};
 | |
|   var nodes = g.nodes();
 | |
| 
 | |
|   nodes.forEach(function(v) {
 | |
|     results[v] = {};
 | |
|     results[v][v] = { distance: 0 };
 | |
|     nodes.forEach(function(w) {
 | |
|       if (v !== w) {
 | |
|         results[v][w] = { distance: Number.POSITIVE_INFINITY };
 | |
|       }
 | |
|     });
 | |
|     edgeFn(v).forEach(function(edge) {
 | |
|       var w = edge.v === v ? edge.w : edge.v;
 | |
|       var d = weightFn(edge);
 | |
|       results[v][w] = { distance: d, predecessor: v };
 | |
|     });
 | |
|   });
 | |
| 
 | |
|   nodes.forEach(function(k) {
 | |
|     var rowK = results[k];
 | |
|     nodes.forEach(function(i) {
 | |
|       var rowI = results[i];
 | |
|       nodes.forEach(function(j) {
 | |
|         var ik = rowI[k];
 | |
|         var kj = rowK[j];
 | |
|         var ij = rowI[j];
 | |
|         var altDistance = ik.distance + kj.distance;
 | |
|         if (altDistance < ij.distance) {
 | |
|           ij.distance = altDistance;
 | |
|           ij.predecessor = kj.predecessor;
 | |
|         }
 | |
|       });
 | |
|     });
 | |
|   });
 | |
| 
 | |
|   return results;
 | |
| }
 |