occam-directed-graphs 3.0.37 → 3.0.41

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.
@@ -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
+ }
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
 
3
- export function orderVertices(vertices) { ///
4
- vertices.sort((firstVertex, secondVertex) => {
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 vertexNamesFromVertices(vertices) {
23
- const vertexNames = vertices.map((vertex) => {
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,17 @@
1
1
  "use strict";
2
2
 
3
- import { vertexNamesFromVertices, orderVertices } from "./utilities/vertex";
3
+ import { arrayUtilities } from "necessary";
4
+
5
+ import { forwardsDepthFirstSearch, backwardsDepthFirstSearch } from "./utilities/search";
6
+
7
+ const { last } = arrayUtilities;
4
8
 
5
9
  export default class Vertex {
6
- constructor(name, index, visited, immediatePredecessorVertices, immediateSuccessorVertices) {
10
+ constructor(name, index, immediateSuccessorVertexes, immediatePredecessorVertexes) {
7
11
  this.name = name;
8
12
  this.index = index;
9
- this.visited = visited;
10
- this.immediatePredecessorVertices = immediatePredecessorVertices;
11
- this.immediateSuccessorVertices = immediateSuccessorVertices;
13
+ this.immediateSuccessorVertexes = immediateSuccessorVertexes;
14
+ this.immediatePredecessorVertexes = immediatePredecessorVertexes;
12
15
  }
13
16
 
14
17
  getName() {
@@ -19,177 +22,84 @@ export default class Vertex {
19
22
  return this.index;
20
23
  }
21
24
 
22
- isVisited() {
23
- return this.visited;
24
- }
25
-
26
- isStranded() {
27
- const immediatePredecessorVerticesLength = this.immediatePredecessorVertices.length,
28
- immediateSuccessorVerticesLength = this.immediateSuccessorVertices.length,
29
- stranded = ((immediatePredecessorVerticesLength === 0) && (immediateSuccessorVerticesLength === 0));
30
-
31
- return stranded;
32
- }
33
-
34
- getImmediatePredecessorVertexNames() {
35
- const immediatePredecessorVertexNames = this.immediatePredecessorVertices.map((immediatePredecessorVertex) => {
36
- const immediatePredecessorVertexName = immediatePredecessorVertex.getName();
37
-
38
- return immediatePredecessorVertexName;
39
- });
40
-
41
- return immediatePredecessorVertexNames;
25
+ getImmediateSuccessorVertexes() {
26
+ return this.immediateSuccessorVertexes;
42
27
  }
43
28
 
44
- getImmediateSuccessorVertexNames() {
45
- const immediateSuccessorVertexNames = this.immediateSuccessorVertices.map((immediateSuccessorVertex) => {
46
- const immediateSuccessorVertexName = immediateSuccessorVertex.getName();
47
-
48
- return immediateSuccessorVertexName;
49
- });
50
-
51
- return immediateSuccessorVertexNames;
52
- }
53
-
54
- getImmediatePredecessorVertices() {
55
- return this.immediatePredecessorVertices;
56
- }
57
-
58
- getImmediateSuccessorVertices() {
59
- return this.immediateSuccessorVertices;
60
- }
61
-
62
- getPredecessorVertexMap(predecessorVertexMap = {}) {
63
- this.forEachImmediatePredecessorVertex((immediatePredecessorVertex) => {
64
- const predecessorVertex = immediatePredecessorVertex, ///
65
- predecessorVertexName = predecessorVertex.getName();
66
-
67
- predecessorVertexMap[predecessorVertexName] = predecessorVertex;
68
-
69
- predecessorVertex.getPredecessorVertexMap(predecessorVertexMap);
70
- });
71
-
72
- return predecessorVertexMap;
73
- }
74
-
75
- getSuccessorVertexMap(successorVertexMap = {}) {
76
- this.forEachImmediateSuccessorVertex((immediateSuccessorVertex) => {
77
- const successorVertex = immediateSuccessorVertex, ///
78
- successorVertexName = successorVertex.getName();
79
-
80
- successorVertexMap[successorVertexName] = successorVertex;
81
-
82
- successorVertex.getSuccessorVertexMap(successorVertexMap);
83
- });
84
-
85
- return successorVertexMap;
29
+ getImmediatePredecessorVertexes() {
30
+ return this.immediatePredecessorVertexes;
86
31
  }
87
32
 
88
- getPredecessorVertexNames() {
89
- const predecessorVertices = this.getPredecessorVertices(),
90
- predecessorVertexNames = predecessorVertices.map((predecessorVertex) => {
91
- const predecessorVertexName = predecessorVertex.getName();
92
-
93
- return predecessorVertexName;
94
- });
33
+ isStranded() {
34
+ const immediateSuccessorVertexesLength = this.immediateSuccessorVertexes.length,
35
+ immediatePredecessorVertexesLength = this.immediatePredecessorVertexes.length,
36
+ stranded = ((immediateSuccessorVertexesLength === 0) && (immediatePredecessorVertexesLength === 0));
95
37
 
96
- return predecessorVertexNames;
38
+ return stranded;
97
39
  }
98
40
 
99
- getSuccessorVertexNames() {
100
- const successorVertices = this.getSuccessorVertices(),
101
- successorVertexNames = successorVertices.map((successorVertex) => {
102
- const successorVertexName = successorVertex.getName();
103
-
104
- return successorVertexName;
105
- });
41
+ isVertexReachable(vertex) {
42
+ const forwardsVisitedVertices = this.retrieveForwardsVisitedVertexes(vertex),
43
+ lastForwardsVisitedVertex = last(forwardsVisitedVertices),
44
+ vertexReachable = (vertex === lastForwardsVisitedVertex);
106
45
 
107
- return successorVertexNames;
46
+ return vertexReachable;
108
47
  }
109
48
 
110
- getPredecessorVertices() {
111
- const predecessorVertexMap = this.getPredecessorVertexMap(),
112
- predecessorVertexNames = Object.keys(predecessorVertexMap),
113
- predecessorVertices = predecessorVertexNames.map((predecessorVertexName) => {
114
- const predecessorVertex = predecessorVertexMap[predecessorVertexName];
115
-
116
- return predecessorVertex;
117
- });
49
+ isEdgePresentBySourceVertex(sourceVertex) {
50
+ const sourceVertexImmediatePredecessorVertex = this.isVertexImmediatePredecessorVertex(sourceVertex),
51
+ edgePresent = sourceVertexImmediatePredecessorVertex; ///
118
52
 
119
- return predecessorVertices;
53
+ return edgePresent;
120
54
  }
121
55
 
122
- getSuccessorVertices() {
123
- const successorVertexMap = this.getSuccessorVertexMap(),
124
- successorVertexNames = Object.keys(successorVertexMap),
125
- successorVertices = successorVertexNames.map((successorVertexName) => {
126
- const successorVertex = successorVertexMap[successorVertexName];
127
-
128
- return successorVertex;
129
- });
56
+ isEdgePresentByTargetVertex(targetVertex) {
57
+ const targetVertexImmediateSuccessorVertex = this.isVertexImmediateSuccessorVertex(targetVertex),
58
+ edgePresent = targetVertexImmediateSuccessorVertex; ///
130
59
 
131
- return successorVertices;
60
+ return edgePresent;
132
61
  }
133
62
 
134
- getOrderedPredecessorVertexNames() {
135
- const predecessorVertices = this.getPredecessorVertices();
136
-
137
- orderVertices(predecessorVertices);
63
+ retrieveForwardsVisitedVertexes(vertex = null) {
64
+ const vertexA = vertex, ///
65
+ visitedVertexes = this.forwardsDepthFirstSearch((vertex) => {
66
+ const vertexB = vertex, ///
67
+ terminate = (vertexA === vertexB);
138
68
 
139
- const orderedPredecessorVertices = predecessorVertices, ///
140
- orderedPredecessorVertexNames = vertexNamesFromVertices(orderedPredecessorVertices);
69
+ if (terminate) {
70
+ return true;
71
+ }
72
+ }),
73
+ forwardsVisitedVertexes = visitedVertexes; ///
141
74
 
142
- return orderedPredecessorVertexNames;
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;
75
+ return forwardsVisitedVertexes;
155
76
  }
156
77
 
157
- retrieveBackwardsAffectedVertices() {
158
- const backwardsAffectedVertices = this.backwardsDepthFirstSearch((visitedVertex) => {
159
- const terminate = false;
78
+ retrieveBackwardsVisitedVertexes(vertex = null) {
79
+ const vertexA = vertex, ///
80
+ visitedVertexes = this.backwardsDepthFirstSearch((vertex) => {
81
+ const vertexB = vertex, ///
82
+ terminate = (vertexA === vertexB);
160
83
 
161
- if (terminate) {
162
- return true;
163
- }
164
- });
165
-
166
- return backwardsAffectedVertices;
167
- }
168
-
169
- isVertexImmediatePredecessorVertex(vertex) {
170
- const vertexImmediatePredecessorVertex = this.immediatePredecessorVertices.includes(vertex);
84
+ if (terminate) {
85
+ return true;
86
+ }
87
+ }),
88
+ backwardsVisitedVertexes = visitedVertexes; ///
171
89
 
172
- return vertexImmediatePredecessorVertex;
90
+ return backwardsVisitedVertexes;
173
91
  }
174
92
 
175
93
  isVertexImmediateSuccessorVertex(vertex) {
176
- const vertexImmediateSuccessorVertex = this.immediateSuccessorVertices.includes(vertex);
94
+ const vertexImmediateSuccessorVertex = this.immediateSuccessorVertexes.includes(vertex);
177
95
 
178
96
  return vertexImmediateSuccessorVertex;
179
97
  }
180
98
 
181
- isEdgePresentBySourceVertex(sourceVertex) {
182
- const sourceVertexImmediatePredecessorVertex = this.isVertexImmediatePredecessorVertex(sourceVertex),
183
- edgePresent = sourceVertexImmediatePredecessorVertex; ///
184
-
185
- return edgePresent;
186
- }
187
-
188
- isEdgePresentByTargetVertex(targetVertex) {
189
- const targetVertexImmediateSuccessorVertex = this.isVertexImmediateSuccessorVertex(targetVertex),
190
- edgePresent = targetVertexImmediateSuccessorVertex; ///
99
+ isVertexImmediatePredecessorVertex(vertex) {
100
+ const vertexImmediatePredecessorVertex = this.immediatePredecessorVertexes.includes(vertex);
191
101
 
192
- return edgePresent;
102
+ return vertexImmediatePredecessorVertex;
193
103
  }
194
104
 
195
105
  setName(name) {
@@ -200,159 +110,80 @@ export default class Vertex {
200
110
  this.index = index;
201
111
  }
202
112
 
203
- setVisited(visited) {
204
- this.visited = visited;
113
+ setImmediateSuccessorVertexes(immediateSuccessorVertexes) {
114
+ this.immediateSuccessorVertexes = immediateSuccessorVertexes;
115
+ }
116
+
117
+ setImmediatePredecessorVertexes(immediatePredecessorVertexes) {
118
+ this.immediatePredecessorVertexes = immediatePredecessorVertexes;
205
119
  }
206
120
 
207
121
  decrementIndex() {
208
122
  this.index--;
209
123
  }
210
124
 
211
- removeImmediatePredecessorVertex(immediatePredecessorVertex) {
212
- const index = this.immediatePredecessorVertices.indexOf(immediatePredecessorVertex),
213
- start = index, ///
214
- deleteCount = 1;
125
+ addImmediateSuccessorVertex(immediateSuccessorVertex) {
126
+ this.immediateSuccessorVertexes.push(immediateSuccessorVertex);
127
+ }
215
128
 
216
- this.immediatePredecessorVertices.splice(start, deleteCount);
129
+ addImmediatePredecessorVertex(immediatePredecessorVertex) {
130
+ this.immediatePredecessorVertexes.push(immediatePredecessorVertex);
217
131
  }
218
132
 
219
133
  removeImmediateSuccessorVertex(immediateSuccessorVertex) {
220
- const index = this.immediateSuccessorVertices.indexOf(immediateSuccessorVertex),
134
+ const index = this.immediateSuccessorVertexes.indexOf(immediateSuccessorVertex),
221
135
  start = index, ///
222
136
  deleteCount = 1;
223
137
 
224
- this.immediateSuccessorVertices.splice(start, deleteCount);
225
- }
226
-
227
- removeIncomingEdges() {
228
- const immediateSuccessorVertex = this; ///
229
-
230
- this.immediatePredecessorVertices.forEach((immediatePredecessorVertex) => immediatePredecessorVertex.removeImmediateSuccessorVertex(immediateSuccessorVertex));
231
-
232
- this.immediatePredecessorVertices = [];
138
+ this.immediateSuccessorVertexes.splice(start, deleteCount);
233
139
  }
234
140
 
235
- removeOutgoingEdges() {
236
- const immediatePredecessorVertex = this; ///
237
-
238
- this.immediateSuccessorVertices.forEach((immediateSuccessorVertex) => immediateSuccessorVertex.removeImmediateSuccessorVertex(immediatePredecessorVertex));
239
-
240
- this.immediateSuccessorVertices = [];
241
- }
242
-
243
- addImmediatePredecessorVertex(immediatePredecessorVertex) {
244
- this.immediatePredecessorVertices.push(immediatePredecessorVertex);
245
- }
141
+ removeImmediatePredecessorVertex(immediatePredecessorVertex) {
142
+ const index = this.immediatePredecessorVertexes.indexOf(immediatePredecessorVertex),
143
+ start = index, ///
144
+ deleteCount = 1;
246
145
 
247
- addImmediateSuccessorVertex(immediateSuccessorVertex) {
248
- this.immediateSuccessorVertices.push(immediateSuccessorVertex);
146
+ this.immediatePredecessorVertexes.splice(start, deleteCount);
249
147
  }
250
148
 
251
149
  forwardsDepthFirstSearch(callback) {
252
- const visitedVertices = [];
253
-
254
- this.retrieveForwardsVisitedVertices((visitedVertex) => {
255
- const terminate = callback(visitedVertex); ///
256
-
257
- visitedVertices.push(visitedVertex);
258
-
259
- return terminate;
260
- });
150
+ const vertex = this, ///
151
+ visitedVertexes = [];
261
152
 
262
- visitedVertices.forEach((visitedVertex) => visitedVertex.resetVisited());
153
+ forwardsDepthFirstSearch(vertex, callback, visitedVertexes);
263
154
 
264
- return visitedVertices;
155
+ return visitedVertexes;
265
156
  }
266
157
 
267
158
  backwardsDepthFirstSearch(callback) {
268
- const visitedVertices = [];
159
+ const vertex = this, ///
160
+ visitedVertexes = [];
269
161
 
270
- this.retrieveBackwardsVisitedVertices((visitedVertex) => {
271
- const terminate = callback(visitedVertex); ///
162
+ backwardsDepthFirstSearch(vertex, callback, visitedVertexes);
272
163
 
273
- visitedVertices.push(visitedVertex);
274
-
275
- return terminate;
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;
164
+ return visitedVertexes;
305
165
  }
306
166
 
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;
329
- }
330
-
331
- forEachImmediatePredecessorVertex(callback) {
332
- this.immediatePredecessorVertices.forEach(callback);
333
- }
334
-
335
- forEachImmediateSuccessorVertex(callback) {
336
- this.immediateSuccessorVertices.forEach(callback);
167
+ someImmediateSuccessorVertex(callback) {
168
+ return this.immediateSuccessorVertexes.some(callback);
337
169
  }
338
170
 
339
171
  someImmediatePredecessorVertex(callback) {
340
- this.immediatePredecessorVertices.some(callback);
172
+ return this.immediatePredecessorVertexes.some(callback);
341
173
  }
342
174
 
343
- someImmediateSuccessorVertex(callback) {
344
- this.immediateSuccessorVertices.some(callback);
175
+ forEachImmediateSuccessorVertex(callback) {
176
+ this.immediateSuccessorVertexes.forEach(callback);
345
177
  }
346
178
 
347
- resetVisited() {
348
- this.visited = false;
179
+ forEachImmediatePredecessorVertex(callback) {
180
+ this.immediatePredecessorVertexes.forEach(callback);
349
181
  }
350
182
 
351
183
  static fromNameAndIndex(name, index) {
352
- const visited = false, ///
353
- immediatePredecessorVertices = [],
354
- immediateSuccessorVertices = [],
355
- dependencyVertex = new Vertex(name, index, visited, immediatePredecessorVertices, immediateSuccessorVertices);
184
+ const immediateSuccessorVertexes = [],
185
+ immediatePredecessorVertexes = [],
186
+ dependencyVertex = new Vertex(name, index, immediateSuccessorVertexes, immediatePredecessorVertexes);
356
187
 
357
188
  return dependencyVertex;
358
189
  }