occam-directed-graphs 3.0.37 → 3.0.42
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +34 -49
- package/lib/cycle.js +31 -14
- package/lib/directedGraph.js +215 -201
- package/lib/index.js +9 -1
- package/lib/utilities/index.js +40 -0
- package/lib/utilities/search.js +91 -0
- package/lib/utilities/vertex.js +11 -50
- package/lib/vertex.js +106 -240
- package/package.json +6 -7
- package/src/cycle.js +8 -28
- package/src/directedGraph.js +277 -198
- package/src/index.js +2 -0
- package/src/utilities/index.js +25 -0
- package/src/utilities/search.js +69 -0
- package/src/utilities/vertex.js +6 -61
- package/src/vertex.js +110 -248
- package/test/cirectedGraph.js +589 -0
- package/bin/main.js +0 -15
- package/lib/directedAcyclicGraph.js +0 -364
- package/lib/example.js +0 -21
- package/lib/partialCycle.js +0 -102
- package/lib/utilities/edge.js +0 -65
- package/src/directedAcyclicGraph.js +0 -422
- package/src/example.js +0 -22
- package/src/partialCycle.js +0 -69
- package/src/utilities/edge.js +0 -58
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
export function forwardsDepthFirstSearch(vertex, callback, visitedVertexes, predecessorVertexes = []) {
|
|
4
|
+
let terminate = true;
|
|
5
|
+
|
|
6
|
+
const visitedVertexesIncludesVertex = visitedVertexes.includes(vertex);
|
|
7
|
+
|
|
8
|
+
if (!visitedVertexesIncludesVertex) {
|
|
9
|
+
const visitedVertex = vertex; ///
|
|
10
|
+
|
|
11
|
+
visitedVertexes.push(visitedVertex);
|
|
12
|
+
|
|
13
|
+
terminate = callback(vertex, predecessorVertexes);
|
|
14
|
+
|
|
15
|
+
if (!terminate) {
|
|
16
|
+
const predecessorVertex = vertex; ///
|
|
17
|
+
|
|
18
|
+
predecessorVertexes = [ ///
|
|
19
|
+
...predecessorVertexes,
|
|
20
|
+
predecessorVertex
|
|
21
|
+
];
|
|
22
|
+
|
|
23
|
+
terminate = vertex.someImmediateSuccessorVertex((immediateSuccessorVertex) => {
|
|
24
|
+
const vertex = immediateSuccessorVertex, ///
|
|
25
|
+
terminate = forwardsDepthFirstSearch(vertex, callback, visitedVertexes, predecessorVertexes);
|
|
26
|
+
|
|
27
|
+
if (terminate) {
|
|
28
|
+
return true;
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
return terminate;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export function backwardsDepthFirstSearch(vertex, callback, visitedVertexes, successorVertexes = []) {
|
|
38
|
+
let terminate = true;
|
|
39
|
+
|
|
40
|
+
const visitedVertexesIncludesVertex = visitedVertexes.includes(vertex);
|
|
41
|
+
|
|
42
|
+
if (!visitedVertexesIncludesVertex) {
|
|
43
|
+
const visitedVertex = vertex; ///
|
|
44
|
+
|
|
45
|
+
visitedVertexes.push(visitedVertex);
|
|
46
|
+
|
|
47
|
+
terminate = callback(vertex, successorVertexes);
|
|
48
|
+
|
|
49
|
+
if (!terminate) {
|
|
50
|
+
const successorVertex = vertex; ///
|
|
51
|
+
|
|
52
|
+
successorVertexes = [ ///
|
|
53
|
+
...successorVertexes,
|
|
54
|
+
successorVertex
|
|
55
|
+
];
|
|
56
|
+
|
|
57
|
+
terminate = vertex.someImmediatePredecessorVertex((immediatePredecessorVertex) => {
|
|
58
|
+
const vertex = immediatePredecessorVertex, ///
|
|
59
|
+
terminate = backwardsDepthFirstSearch(vertex, callback, visitedVertexes, successorVertexes);
|
|
60
|
+
|
|
61
|
+
if (terminate) {
|
|
62
|
+
return true;
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
return terminate;
|
|
69
|
+
}
|
package/src/utilities/vertex.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
-
export function
|
|
4
|
-
|
|
3
|
+
export function orderVertexes(vertexes) { ///
|
|
4
|
+
vertexes.sort((firstVertex, secondVertex) => {
|
|
5
5
|
const firstVertexIndex = firstVertex.getIndex(),
|
|
6
6
|
secondVertexIndex = secondVertex.getIndex();
|
|
7
7
|
|
|
@@ -11,16 +11,14 @@ export function orderVertices(vertices) { ///
|
|
|
11
11
|
return -1;
|
|
12
12
|
} else if (firstVertexIndex > secondVertexIndex) {
|
|
13
13
|
return +1;
|
|
14
|
+
} else {
|
|
15
|
+
return 0;
|
|
14
16
|
}
|
|
15
17
|
});
|
|
16
|
-
|
|
17
|
-
const orderedVertices = vertices; ///
|
|
18
|
-
|
|
19
|
-
return orderedVertices;
|
|
20
18
|
}
|
|
21
19
|
|
|
22
|
-
export function
|
|
23
|
-
const vertexNames =
|
|
20
|
+
export function vertexNamesFromVertexes(vertexes) {
|
|
21
|
+
const vertexNames = vertexes.map((vertex) => {
|
|
24
22
|
const vertexName = vertex.getName();
|
|
25
23
|
|
|
26
24
|
return vertexName;
|
|
@@ -28,56 +26,3 @@ export function vertexNamesFromVertices(vertices) {
|
|
|
28
26
|
|
|
29
27
|
return vertexNames;
|
|
30
28
|
}
|
|
31
|
-
|
|
32
|
-
export function forwardsDepthFirstSearch(vertex, callback) {
|
|
33
|
-
const visitedVertices = [];
|
|
34
|
-
|
|
35
|
-
retrieveForwardsVisitedVertices(vertex, (visitedVertex, getPredecessorVertices) => {
|
|
36
|
-
const terminate = callback(visitedVertex, getPredecessorVertices); ///
|
|
37
|
-
|
|
38
|
-
visitedVertices.push(visitedVertex);
|
|
39
|
-
|
|
40
|
-
return terminate;
|
|
41
|
-
}, getPredecessorVertices);
|
|
42
|
-
|
|
43
|
-
visitedVertices.forEach((visitedVertex) => visitedVertex.resetVisited());
|
|
44
|
-
|
|
45
|
-
return visitedVertices;
|
|
46
|
-
|
|
47
|
-
function getPredecessorVertices() {
|
|
48
|
-
const predecessorVertices = [];
|
|
49
|
-
|
|
50
|
-
return predecessorVertices;
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
function retrieveForwardsVisitedVertices(vertex, callback, getPredecessorVertices) {
|
|
55
|
-
let terminate = false;
|
|
56
|
-
|
|
57
|
-
if (vertex.visited === false) {
|
|
58
|
-
vertex.visited = true;
|
|
59
|
-
|
|
60
|
-
const visitedVertex = vertex; ///
|
|
61
|
-
|
|
62
|
-
terminate = callback(visitedVertex, getPredecessorVertices);
|
|
63
|
-
|
|
64
|
-
if (terminate !== true) {
|
|
65
|
-
visitedVertex.someImmediateSuccessorVertex((immediateSuccessorVertex) => {
|
|
66
|
-
terminate = retrieveForwardsVisitedVertices(immediateSuccessorVertex, callback, () => {
|
|
67
|
-
let predecessorVertices = getPredecessorVertices();
|
|
68
|
-
|
|
69
|
-
const immediatePredecessorVertex = vertex, ///
|
|
70
|
-
predecessorVertex = immediatePredecessorVertex; ///
|
|
71
|
-
|
|
72
|
-
predecessorVertices = predecessorVertices.concat(predecessorVertex);
|
|
73
|
-
|
|
74
|
-
return predecessorVertices;
|
|
75
|
-
});
|
|
76
|
-
|
|
77
|
-
return terminate;
|
|
78
|
-
});
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
return terminate;
|
|
83
|
-
}
|
package/src/vertex.js
CHANGED
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import { arrayUtilities } from "necessary";
|
|
4
|
+
|
|
5
|
+
import { vertexNamesFromVertexes } from "./utilities/vertex";
|
|
6
|
+
import { forwardsDepthFirstSearch, backwardsDepthFirstSearch } from "./utilities/search";
|
|
7
|
+
|
|
8
|
+
const { last, tail } = arrayUtilities;
|
|
4
9
|
|
|
5
10
|
export default class Vertex {
|
|
6
|
-
constructor(name, index,
|
|
11
|
+
constructor(name, index, immediateSuccessorVertexes, immediatePredecessorVertexes) {
|
|
7
12
|
this.name = name;
|
|
8
13
|
this.index = index;
|
|
9
|
-
this.
|
|
10
|
-
this.
|
|
11
|
-
this.immediateSuccessorVertices = immediateSuccessorVertices;
|
|
14
|
+
this.immediateSuccessorVertexes = immediateSuccessorVertexes;
|
|
15
|
+
this.immediatePredecessorVertexes = immediatePredecessorVertexes;
|
|
12
16
|
}
|
|
13
17
|
|
|
14
18
|
getName() {
|
|
@@ -19,177 +23,114 @@ export default class Vertex {
|
|
|
19
23
|
return this.index;
|
|
20
24
|
}
|
|
21
25
|
|
|
22
|
-
|
|
23
|
-
return this.
|
|
26
|
+
getImmediateSuccessorVertexes() {
|
|
27
|
+
return this.immediateSuccessorVertexes;
|
|
24
28
|
}
|
|
25
29
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
immediateSuccessorVerticesLength = this.immediateSuccessorVertices.length,
|
|
29
|
-
stranded = ((immediatePredecessorVerticesLength === 0) && (immediateSuccessorVerticesLength === 0));
|
|
30
|
-
|
|
31
|
-
return stranded;
|
|
30
|
+
getImmediatePredecessorVertexes() {
|
|
31
|
+
return this.immediatePredecessorVertexes;
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
-
|
|
35
|
-
const
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
return immediatePredecessorVertexName;
|
|
39
|
-
});
|
|
34
|
+
isStranded() {
|
|
35
|
+
const immediateSuccessorVertexesLength = this.immediateSuccessorVertexes.length,
|
|
36
|
+
immediatePredecessorVertexesLength = this.immediatePredecessorVertexes.length,
|
|
37
|
+
stranded = ((immediateSuccessorVertexesLength === 0) && (immediatePredecessorVertexesLength === 0));
|
|
40
38
|
|
|
41
|
-
return
|
|
39
|
+
return stranded;
|
|
42
40
|
}
|
|
43
41
|
|
|
44
|
-
|
|
45
|
-
const
|
|
46
|
-
|
|
42
|
+
isVertexReachable(vertex) {
|
|
43
|
+
const forwardsVisitedVertices = this.retrieveForwardsVisitedVertexes(vertex),
|
|
44
|
+
lastForwardsVisitedVertex = last(forwardsVisitedVertices),
|
|
45
|
+
vertexReachable = (vertex === lastForwardsVisitedVertex);
|
|
47
46
|
|
|
48
|
-
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
return immediateSuccessorVertexNames;
|
|
47
|
+
return vertexReachable;
|
|
52
48
|
}
|
|
53
49
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
50
|
+
isEdgePresentBySourceVertex(sourceVertex) {
|
|
51
|
+
const sourceVertexImmediatePredecessorVertex = this.isVertexImmediatePredecessorVertex(sourceVertex),
|
|
52
|
+
edgePresent = sourceVertexImmediatePredecessorVertex; ///
|
|
57
53
|
|
|
58
|
-
|
|
59
|
-
return this.immediateSuccessorVertices;
|
|
54
|
+
return edgePresent;
|
|
60
55
|
}
|
|
61
56
|
|
|
62
|
-
|
|
63
|
-
this.
|
|
64
|
-
|
|
65
|
-
predecessorVertexName = predecessorVertex.getName();
|
|
66
|
-
|
|
67
|
-
predecessorVertexMap[predecessorVertexName] = predecessorVertex;
|
|
68
|
-
|
|
69
|
-
predecessorVertex.getPredecessorVertexMap(predecessorVertexMap);
|
|
70
|
-
});
|
|
57
|
+
isEdgePresentByTargetVertex(targetVertex) {
|
|
58
|
+
const targetVertexImmediateSuccessorVertex = this.isVertexImmediateSuccessorVertex(targetVertex),
|
|
59
|
+
edgePresent = targetVertexImmediateSuccessorVertex; ///
|
|
71
60
|
|
|
72
|
-
return
|
|
61
|
+
return edgePresent;
|
|
73
62
|
}
|
|
74
63
|
|
|
75
|
-
|
|
76
|
-
this.
|
|
77
|
-
|
|
78
|
-
|
|
64
|
+
retrieveSuccessorVertexNames() {
|
|
65
|
+
const forwardsVisitedVertexes = this.retrieveForwardsVisitedVertexes(),
|
|
66
|
+
forwardsVisitedVertexesTail = tail(forwardsVisitedVertexes),
|
|
67
|
+
successorVertexes = forwardsVisitedVertexesTail,
|
|
68
|
+
successorVertexNames = vertexNamesFromVertexes(successorVertexes);
|
|
79
69
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
successorVertex.getSuccessorVertexMap(successorVertexMap);
|
|
83
|
-
});
|
|
84
|
-
|
|
85
|
-
return successorVertexMap;
|
|
70
|
+
return successorVertexNames;
|
|
86
71
|
}
|
|
87
72
|
|
|
88
|
-
|
|
89
|
-
const
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
return predecessorVertexName;
|
|
94
|
-
});
|
|
73
|
+
retrievePredecessorVertexNames() {
|
|
74
|
+
const backwardsVisitedVertexes = this.retrieveBackwardsVisitedVertexes(),
|
|
75
|
+
backwardsVisitedVertexesTail = tail(backwardsVisitedVertexes),
|
|
76
|
+
predecessorVertexes = backwardsVisitedVertexesTail,
|
|
77
|
+
predecessorVertexNames = vertexNamesFromVertexes(predecessorVertexes);
|
|
95
78
|
|
|
96
79
|
return predecessorVertexNames;
|
|
97
80
|
}
|
|
98
81
|
|
|
99
|
-
|
|
100
|
-
const
|
|
101
|
-
|
|
102
|
-
const
|
|
82
|
+
retrieveForwardsVisitedVertexes(vertex = null) {
|
|
83
|
+
const vertexA = vertex, ///
|
|
84
|
+
visitedVertexes = this.forwardsDepthFirstSearch((vertex) => {
|
|
85
|
+
const vertexB = vertex, ///
|
|
86
|
+
terminate = (vertexA === vertexB);
|
|
103
87
|
|
|
104
|
-
|
|
105
|
-
|
|
88
|
+
if (terminate) {
|
|
89
|
+
return true;
|
|
90
|
+
}
|
|
91
|
+
}),
|
|
92
|
+
forwardsVisitedVertexes = visitedVertexes; ///
|
|
106
93
|
|
|
107
|
-
return
|
|
94
|
+
return forwardsVisitedVertexes;
|
|
108
95
|
}
|
|
109
96
|
|
|
110
|
-
|
|
111
|
-
const
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
97
|
+
retrieveBackwardsVisitedVertexes(vertex = null) {
|
|
98
|
+
const vertexA = vertex, ///
|
|
99
|
+
visitedVertexes = this.backwardsDepthFirstSearch((vertex) => {
|
|
100
|
+
const vertexB = vertex, ///
|
|
101
|
+
terminate = (vertexA === vertexB);
|
|
115
102
|
|
|
116
|
-
|
|
117
|
-
|
|
103
|
+
if (terminate) {
|
|
104
|
+
return true;
|
|
105
|
+
}
|
|
106
|
+
}),
|
|
107
|
+
backwardsVisitedVertexes = visitedVertexes; ///
|
|
118
108
|
|
|
119
|
-
return
|
|
109
|
+
return backwardsVisitedVertexes;
|
|
120
110
|
}
|
|
121
111
|
|
|
122
|
-
|
|
123
|
-
const
|
|
124
|
-
successorVertexNames = Object.keys(successorVertexMap),
|
|
125
|
-
successorVertices = successorVertexNames.map((successorVertexName) => {
|
|
126
|
-
const successorVertex = successorVertexMap[successorVertexName];
|
|
127
|
-
|
|
128
|
-
return successorVertex;
|
|
129
|
-
});
|
|
130
|
-
|
|
131
|
-
return successorVertices;
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
getOrderedPredecessorVertexNames() {
|
|
135
|
-
const predecessorVertices = this.getPredecessorVertices();
|
|
136
|
-
|
|
137
|
-
orderVertices(predecessorVertices);
|
|
138
|
-
|
|
139
|
-
const orderedPredecessorVertices = predecessorVertices, ///
|
|
140
|
-
orderedPredecessorVertexNames = vertexNamesFromVertices(orderedPredecessorVertices);
|
|
112
|
+
isVertexImmediateSuccessorVertex(vertex) {
|
|
113
|
+
const vertexImmediateSuccessorVertex = this.immediateSuccessorVertexes.includes(vertex);
|
|
141
114
|
|
|
142
|
-
return
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
retrieveForwardsAffectedVertices(sourceVertex) {
|
|
146
|
-
const forwardsAffectedVertices = this.forwardsDepthFirstSearch((visitedVertex) => {
|
|
147
|
-
const terminate = (visitedVertex === sourceVertex);
|
|
148
|
-
|
|
149
|
-
if (terminate) {
|
|
150
|
-
return true;
|
|
151
|
-
}
|
|
152
|
-
});
|
|
153
|
-
|
|
154
|
-
return forwardsAffectedVertices;
|
|
115
|
+
return vertexImmediateSuccessorVertex;
|
|
155
116
|
}
|
|
156
117
|
|
|
157
|
-
retrieveBackwardsAffectedVertices() {
|
|
158
|
-
const backwardsAffectedVertices = this.backwardsDepthFirstSearch((visitedVertex) => {
|
|
159
|
-
const terminate = false;
|
|
160
|
-
|
|
161
|
-
if (terminate) {
|
|
162
|
-
return true;
|
|
163
|
-
}
|
|
164
|
-
});
|
|
165
|
-
|
|
166
|
-
return backwardsAffectedVertices;
|
|
167
|
-
}
|
|
168
|
-
|
|
169
118
|
isVertexImmediatePredecessorVertex(vertex) {
|
|
170
|
-
const vertexImmediatePredecessorVertex = this.
|
|
119
|
+
const vertexImmediatePredecessorVertex = this.immediatePredecessorVertexes.includes(vertex);
|
|
171
120
|
|
|
172
121
|
return vertexImmediatePredecessorVertex;
|
|
173
122
|
}
|
|
174
123
|
|
|
175
|
-
|
|
176
|
-
const
|
|
177
|
-
|
|
178
|
-
return vertexImmediateSuccessorVertex;
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
isEdgePresentBySourceVertex(sourceVertex) {
|
|
182
|
-
const sourceVertexImmediatePredecessorVertex = this.isVertexImmediatePredecessorVertex(sourceVertex),
|
|
183
|
-
edgePresent = sourceVertexImmediatePredecessorVertex; ///
|
|
124
|
+
getImmediateSuccessorVertexNames() {
|
|
125
|
+
const immediateSuccessorVertexNames = vertexNamesFromVertexes(this.immediateSuccessorVertexes);
|
|
184
126
|
|
|
185
|
-
return
|
|
127
|
+
return immediateSuccessorVertexNames;
|
|
186
128
|
}
|
|
187
129
|
|
|
188
|
-
|
|
189
|
-
const
|
|
190
|
-
edgePresent = targetVertexImmediateSuccessorVertex; ///
|
|
130
|
+
getImmediatePredecessorVertexNames() {
|
|
131
|
+
const immediatePredecessorVertexNames = vertexNamesFromVertexes(this.immediatePredecessorVertexes);
|
|
191
132
|
|
|
192
|
-
return
|
|
133
|
+
return immediatePredecessorVertexNames;
|
|
193
134
|
}
|
|
194
135
|
|
|
195
136
|
setName(name) {
|
|
@@ -200,159 +141,80 @@ export default class Vertex {
|
|
|
200
141
|
this.index = index;
|
|
201
142
|
}
|
|
202
143
|
|
|
203
|
-
|
|
204
|
-
this.
|
|
144
|
+
setImmediateSuccessorVertexes(immediateSuccessorVertexes) {
|
|
145
|
+
this.immediateSuccessorVertexes = immediateSuccessorVertexes;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
setImmediatePredecessorVertexes(immediatePredecessorVertexes) {
|
|
149
|
+
this.immediatePredecessorVertexes = immediatePredecessorVertexes;
|
|
205
150
|
}
|
|
206
151
|
|
|
207
152
|
decrementIndex() {
|
|
208
153
|
this.index--;
|
|
209
154
|
}
|
|
210
155
|
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
deleteCount = 1;
|
|
156
|
+
addImmediateSuccessorVertex(immediateSuccessorVertex) {
|
|
157
|
+
this.immediateSuccessorVertexes.push(immediateSuccessorVertex);
|
|
158
|
+
}
|
|
215
159
|
|
|
216
|
-
|
|
160
|
+
addImmediatePredecessorVertex(immediatePredecessorVertex) {
|
|
161
|
+
this.immediatePredecessorVertexes.push(immediatePredecessorVertex);
|
|
217
162
|
}
|
|
218
163
|
|
|
219
164
|
removeImmediateSuccessorVertex(immediateSuccessorVertex) {
|
|
220
|
-
const index = this.
|
|
165
|
+
const index = this.immediateSuccessorVertexes.indexOf(immediateSuccessorVertex),
|
|
221
166
|
start = index, ///
|
|
222
167
|
deleteCount = 1;
|
|
223
168
|
|
|
224
|
-
this.
|
|
169
|
+
this.immediateSuccessorVertexes.splice(start, deleteCount);
|
|
225
170
|
}
|
|
226
|
-
|
|
227
|
-
removeIncomingEdges() {
|
|
228
|
-
const immediateSuccessorVertex = this; ///
|
|
229
|
-
|
|
230
|
-
this.immediatePredecessorVertices.forEach((immediatePredecessorVertex) => immediatePredecessorVertex.removeImmediateSuccessorVertex(immediateSuccessorVertex));
|
|
231
|
-
|
|
232
|
-
this.immediatePredecessorVertices = [];
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
removeOutgoingEdges() {
|
|
236
|
-
const immediatePredecessorVertex = this; ///
|
|
237
171
|
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
addImmediatePredecessorVertex(immediatePredecessorVertex) {
|
|
244
|
-
this.immediatePredecessorVertices.push(immediatePredecessorVertex);
|
|
245
|
-
}
|
|
172
|
+
removeImmediatePredecessorVertex(immediatePredecessorVertex) {
|
|
173
|
+
const index = this.immediatePredecessorVertexes.indexOf(immediatePredecessorVertex),
|
|
174
|
+
start = index, ///
|
|
175
|
+
deleteCount = 1;
|
|
246
176
|
|
|
247
|
-
|
|
248
|
-
this.immediateSuccessorVertices.push(immediateSuccessorVertex);
|
|
177
|
+
this.immediatePredecessorVertexes.splice(start, deleteCount);
|
|
249
178
|
}
|
|
250
179
|
|
|
251
180
|
forwardsDepthFirstSearch(callback) {
|
|
252
|
-
const
|
|
253
|
-
|
|
254
|
-
this.retrieveForwardsVisitedVertices((visitedVertex) => {
|
|
255
|
-
const terminate = callback(visitedVertex); ///
|
|
181
|
+
const vertex = this, ///
|
|
182
|
+
visitedVertexes = [];
|
|
256
183
|
|
|
257
|
-
|
|
184
|
+
forwardsDepthFirstSearch(vertex, callback, visitedVertexes);
|
|
258
185
|
|
|
259
|
-
|
|
260
|
-
});
|
|
261
|
-
|
|
262
|
-
visitedVertices.forEach((visitedVertex) => visitedVertex.resetVisited());
|
|
263
|
-
|
|
264
|
-
return visitedVertices;
|
|
186
|
+
return visitedVertexes;
|
|
265
187
|
}
|
|
266
188
|
|
|
267
189
|
backwardsDepthFirstSearch(callback) {
|
|
268
|
-
const
|
|
269
|
-
|
|
270
|
-
this.retrieveBackwardsVisitedVertices((visitedVertex) => {
|
|
271
|
-
const terminate = callback(visitedVertex); ///
|
|
190
|
+
const vertex = this, ///
|
|
191
|
+
visitedVertexes = [];
|
|
272
192
|
|
|
273
|
-
|
|
193
|
+
backwardsDepthFirstSearch(vertex, callback, visitedVertexes);
|
|
274
194
|
|
|
275
|
-
|
|
276
|
-
});
|
|
277
|
-
|
|
278
|
-
visitedVertices.forEach((visitedVertex) => visitedVertex.resetVisited());
|
|
279
|
-
|
|
280
|
-
return visitedVertices;
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
retrieveForwardsVisitedVertices(callback) {
|
|
284
|
-
let terminate = false;
|
|
285
|
-
|
|
286
|
-
if (this.visited === false) {
|
|
287
|
-
this.visited = true;
|
|
288
|
-
|
|
289
|
-
const visitedVertex = this; ///
|
|
290
|
-
|
|
291
|
-
terminate = callback(visitedVertex);
|
|
292
|
-
|
|
293
|
-
if (terminate !== true) {
|
|
294
|
-
visitedVertex.someImmediateSuccessorVertex((immediateSuccessorVertex) => {
|
|
295
|
-
terminate = immediateSuccessorVertex.retrieveForwardsVisitedVertices(callback);
|
|
296
|
-
|
|
297
|
-
if (terminate) {
|
|
298
|
-
return true;
|
|
299
|
-
}
|
|
300
|
-
});
|
|
301
|
-
}
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
return terminate;
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
retrieveBackwardsVisitedVertices(callback) {
|
|
308
|
-
let terminate = false;
|
|
309
|
-
|
|
310
|
-
if (this.visited === false) {
|
|
311
|
-
this.visited = true;
|
|
312
|
-
|
|
313
|
-
const visitedVertex = this; ///
|
|
314
|
-
|
|
315
|
-
terminate = callback(visitedVertex);
|
|
316
|
-
|
|
317
|
-
if (terminate !== true) {
|
|
318
|
-
visitedVertex.someImmediatePredecessorVertex((immediatePredecessorVertex) => {
|
|
319
|
-
terminate = immediatePredecessorVertex.retrieveBackwardsVisitedVertices(callback);
|
|
320
|
-
|
|
321
|
-
if (terminate) {
|
|
322
|
-
return true;
|
|
323
|
-
}
|
|
324
|
-
});
|
|
325
|
-
}
|
|
326
|
-
}
|
|
327
|
-
|
|
328
|
-
return terminate;
|
|
195
|
+
return visitedVertexes;
|
|
329
196
|
}
|
|
330
197
|
|
|
331
|
-
|
|
332
|
-
this.
|
|
333
|
-
}
|
|
334
|
-
|
|
335
|
-
forEachImmediateSuccessorVertex(callback) {
|
|
336
|
-
this.immediateSuccessorVertices.forEach(callback);
|
|
198
|
+
someImmediateSuccessorVertex(callback) {
|
|
199
|
+
return this.immediateSuccessorVertexes.some(callback);
|
|
337
200
|
}
|
|
338
201
|
|
|
339
202
|
someImmediatePredecessorVertex(callback) {
|
|
340
|
-
this.
|
|
203
|
+
return this.immediatePredecessorVertexes.some(callback);
|
|
341
204
|
}
|
|
342
205
|
|
|
343
|
-
|
|
344
|
-
this.
|
|
206
|
+
forEachImmediateSuccessorVertex(callback) {
|
|
207
|
+
this.immediateSuccessorVertexes.forEach(callback);
|
|
345
208
|
}
|
|
346
209
|
|
|
347
|
-
|
|
348
|
-
this.
|
|
210
|
+
forEachImmediatePredecessorVertex(callback) {
|
|
211
|
+
this.immediatePredecessorVertexes.forEach(callback);
|
|
349
212
|
}
|
|
350
213
|
|
|
351
214
|
static fromNameAndIndex(name, index) {
|
|
352
|
-
const
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
dependencyVertex = new Vertex(name, index, visited, immediatePredecessorVertices, immediateSuccessorVertices);
|
|
215
|
+
const immediateSuccessorVertexes = [],
|
|
216
|
+
immediatePredecessorVertexes = [],
|
|
217
|
+
dependencyVertex = new Vertex(name, index, immediateSuccessorVertexes, immediatePredecessorVertexes);
|
|
356
218
|
|
|
357
219
|
return dependencyVertex;
|
|
358
220
|
}
|