-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathspt-recursive.js
94 lines (81 loc) · 2.86 KB
/
spt-recursive.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
'use strict';
const sptDriver = require('./spt-driver.js');
var fileName = process.argv[2];
sptDriver(fileName, computeShortestPropagationTime);
function computeShortestPropagationTime(nodeNeighbors) {
let neighborNodeHasBetterSPT = true;
let computedNodes = [];
const initialNode = nodeNeighbors.reduce((maxNeighborsNode, neighbors, node, nodeNeighbors) => {
return neighbors.length > nodeNeighbors[maxNeighborsNode].length ? node : maxNeighborsNode;
}, 0);//assuming 0 index exists
let neighbors = nodeNeighbors[initialNode];
let previousState = computePropagationTime({
nodeNeighbors: nodeNeighbors,
spt: 1000000,
computedNodes: computedNodes
}, initialNode);
while (neighborNodeHasBetterSPT) {
let currentState = neighbors.reduce(computePropagationTime, previousState);
if (currentState.node === previousState.node) {
break;
}
neighbors = nodeNeighbors[currentState.node];
neighbors = neighbors.filter((node) => computedNodes[node] === undefined);
previousState = currentState;
}
return {
numOfNodes: nodeNeighbors.reduce((counter, value) => counter + 1, 0),
numOfNodesComputed: computedNodes.reduce((counter, value) => counter + 1, 0),
spt: previousState.spt
};
}
function computePropagationTime(previousState, node) {
const nodesVisited = [];
nodesVisited[node] = 0;
const finishedComputing = propagate({
node: node,
timeToNode: 0,
nodesVisited: nodesVisited,
nodeNeighbors: previousState.nodeNeighbors,
spt: previousState.spt
});
if (!finishedComputing) {
previousState.computedNodes[node] = -1;
return previousState;
}
const maxSpt = nodesVisited.reduce((maxValue, currentValue) => {
return currentValue > maxValue ? currentValue : maxValue;
}, -1);
previousState.computedNodes[node] = maxSpt;
const properties = {};
if (maxSpt < previousState.spt) {
properties.spt = maxSpt;
properties.node = node;
}
return Object.assign({}, previousState, properties);
}
function propagate(state) {
if (state.timeToNode === state.spt) {
return false;
}
const neighbors = state.nodeNeighbors[state.node];
const timeToNeighbor = (state.timeToNode + 1);
const notVisitedNeighbors = neighbors.filter((neighbor) => {
if (state.nodesVisited[neighbor] !== undefined) {
const previousTimeToNeighbor = state.nodesVisited[neighbor];
if (timeToNeighbor < previousTimeToNeighbor) {
state.nodesVisited[neighbor] = timeToNeighbor;
return true;
}
return false;
} else {
return true;
}
});
const neighborsStates = notVisitedNeighbors.map((neighbor) => {
const neighborState = Object.assign({}, state, {node: neighbor, timeToNode: timeToNeighbor});
state.nodesVisited[neighbor] = timeToNeighbor;
return neighborState;
});
return neighborsStates.every((neighborState) => propagate(neighborState));
}