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.
@@ -4,307 +4,386 @@ import { arrayUtilities } from "necessary";
4
4
 
5
5
  import Edge from "./edge";
6
6
  import Cycle from "./cycle";
7
- import PartialCycle from "./partialCycle";
8
- import DirectedAcyclicGraph from "./directedAcyclicGraph";
7
+ import Vertex from "./vertex";
9
8
 
10
- import { forwardsDepthFirstSearch } from "./utilities/vertex";
11
- import { checkEdgesIncludesEdge, removeEdgeFromEdges, edgesBySourceVertexName, edgesByTargetVertexName } from "./utilities/edge";
9
+ import { orderIndexes, indexesFromVertexes } from "./utilities/index";
10
+ import { orderVertexes, vertexNamesFromVertexes } from "./utilities/vertex";
12
11
 
13
- const { first, filter } = arrayUtilities;
12
+ const { first } = arrayUtilities;
14
13
 
15
14
  export default class DirectedGraph {
16
- constructor(cyclicEdges, directedAcyclicGraph) {
17
- this.cyclicEdges = cyclicEdges;
18
-
19
- this.directedAcyclicGraph = directedAcyclicGraph;
15
+ constructor(vertexMap) {
16
+ this.vertexMap = vertexMap;
20
17
  }
21
18
 
22
- getCyclicEdges() {
23
- return this.cyclicEdges;
19
+ getVertexNap() {
20
+ return this.vertexMap;
24
21
  }
25
22
 
26
- getDirectedAcyclicGraph() {
27
- return this.directedAcyclicGraph;
23
+ getVertexes() {
24
+ const vertexMapValues = Object.values(this.vertexMap),
25
+ vertexes = vertexMapValues; ///
26
+
27
+ return vertexes;
28
28
  }
29
29
 
30
- getVertexNames() { return this.directedAcyclicGraph.getVertexNames(); }
30
+ getVertexNames() {
31
+ const vertexMapKeys = Object.keys(this.vertexMap),
32
+ vertexNames = vertexMapKeys; ///
31
33
 
32
- getOrderedVertexNames() { return this.directedAcyclicGraph.getOrderedVertexNames(); }
34
+ return vertexNames;
35
+ }
33
36
 
34
- addVertexByVertexName(vertexName) { this.directedAcyclicGraph.addVertexByVertexName(vertexName); }
37
+ getOrderedVertexNames() {
38
+ const vertexes = this.getVertexes();
35
39
 
36
- isEdgePresentByVertexNames(sourceVertexName, targetVertexName) { return this.directedAcyclicGraph.isEdgePresentByVertexNames(sourceVertexName, targetVertexName); }
40
+ orderVertexes(vertexes);
37
41
 
38
- isVertexPresentByVertexName(vertexName) { return this.directedAcyclicGraph.isVertexPresentByVertexName(vertexName); }
42
+ const orderedVertexes = vertexes, ///
43
+ orderedVertexNames = vertexNamesFromVertexes(orderedVertexes);
39
44
 
40
- getSuccessorVertexNamesByVertexName(vertexName) { return this.directedAcyclicGraph.getSuccessorVertexNamesByVertexName(vertexName); }
45
+ return orderedVertexNames;
46
+ }
41
47
 
42
- getPredecessorVertexNamesByVertexName(vertexName) { return this.directedAcyclicGraph.getPredecessorVertexNamesByVertexName(vertexName); }
48
+ getVertexByVertexName(vertexName) {
49
+ const vertexPresent = this.isVertexPresentByVertexName(vertexName),
50
+ vertex = vertexPresent ?
51
+ this.vertexMap[vertexName] :
52
+ null;
43
53
 
44
- getImmediatePredecessorVertexNamesByVertexName(vertexName, includeCyclicEdges = false) {
45
- const immediatePredecessorVertexNames = this.directedAcyclicGraph.getImmediatePredecessorVertexNamesByVertexName(vertexName);
54
+ return vertex;
55
+ }
46
56
 
47
- if (includeCyclicEdges) {
48
- this.cyclicEdges.forEach((cyclicEdge) => {
49
- const cyclicEdgeTargetVertexName = cyclicEdge.getTargetVertexName();
57
+ getEdgesBySourceVertexName(sourceVertexName) {
58
+ const edges = [],
59
+ sourceVertex = this.getVertexByVertexName(sourceVertexName);
50
60
 
51
- if (cyclicEdgeTargetVertexName === vertexName) {
52
- const cyclicEdgeSourceVertexName = cyclicEdge.getSourceVertexName(),
53
- immediatePredecessorVertexName = cyclicEdgeSourceVertexName; ///
61
+ if (sourceVertex !== null) {
62
+ const immediateSuccessorVertexes = sourceVertex.getImmediateSuccessorVertexes(),
63
+ immediateSuccessorVertexNames = vertexNamesFromVertexes(immediateSuccessorVertexes),
64
+ targetVertexNames = immediateSuccessorVertexNames; ///
54
65
 
55
- immediatePredecessorVertexNames.push(immediatePredecessorVertexName);
56
- }
66
+ targetVertexNames.forEach((targetVertexName) => {
67
+ const edge = Edge.fromSourceVertexNameAndTargetVertexName(sourceVertexName, targetVertexName);
68
+
69
+ edges.push(edge);
57
70
  });
58
71
  }
59
72
 
60
- return immediatePredecessorVertexNames;
73
+ return edges;
61
74
  }
62
75
 
63
- getImmediateSuccessorVertexNamesByVertexName(vertexName, includeCyclicEdges = false) {
64
- const immediateSuccessorVertexNames = this.directedAcyclicGraph.getImmediateSuccessorVertexNamesByVertexName(vertexName);
76
+ getEdgesByTargetVertexName(targetVertexName) {
77
+ const edges = [],
78
+ targetVertex = this.getVertexByVertexName(targetVertexName);
65
79
 
66
- if (includeCyclicEdges) {
67
- this.cyclicEdges.forEach((cyclicEdge) => {
68
- const cyclicEdgeSourceVertexName = cyclicEdge.getSourceVertexName();
80
+ if (targetVertex !== null) {
81
+ const immediatePredecessorVertexes = targetVertex.getImmediatePredecessorVertexes(),
82
+ immediatePredecessorVertexNames = vertexNamesFromVertexes(immediatePredecessorVertexes),
83
+ sourceVertexNames = immediatePredecessorVertexNames; ///
69
84
 
70
- if (cyclicEdgeSourceVertexName === vertexName) {
71
- const cyclicEdgeTargetVertexName = cyclicEdge.getTargetVertexName(),
72
- immediateSuccessorVertexName = cyclicEdgeTargetVertexName; ///
85
+ sourceVertexNames.forEach((sourceVertexName) => {
86
+ const edge = Edge.fromSourceVertexNameAndTargetVertexName(sourceVertexName, targetVertexName);
73
87
 
74
- immediateSuccessorVertexNames.push(immediateSuccessorVertexName);
75
- }
88
+ edges.push(edge);
76
89
  });
77
90
  }
78
91
 
79
- return immediateSuccessorVertexNames;
92
+ return edges;
80
93
  }
81
94
 
82
- areCyclesPresentByVertexName(vertexName) {
83
- let cyclesPresent = false;
95
+ getFirstCycle() {
96
+ let firstCycle = null;
97
+
98
+ const cyclesPresent = this.areCyclesPresent();
99
+
100
+ if (cyclesPresent) {
101
+ const cyclicEdges = this.getCyclicEdges(),
102
+ firstCyclicEdge = first(cyclicEdges),
103
+ sourceVertexName = firstCyclicEdge.getSourceVertexName(), ///
104
+ targetVertexName = firstCyclicEdge.getTargetVertexName(), ///
105
+ sourceVertex = this.getVertexByVertexName(sourceVertexName),
106
+ targetVertex = this.getVertexByVertexName(targetVertexName);
84
107
 
85
- const vertexPresent = this.directedAcyclicGraph.isVertexPresentByVertexName(vertexName);
108
+ targetVertex.forwardsDepthFirstSearch((vertex, predecessorVertexes) => {
109
+ let terminate = false;
86
110
 
87
- if (vertexPresent) {
88
- const firstCycle = this.getFirstCycleByVertexName(vertexName);
111
+ if (vertex === sourceVertex) {
112
+ terminate = true;
89
113
 
90
- cyclesPresent = (firstCycle !== null);
114
+ const cycle = Cycle.fromSourceVertexAndPredecessorVertexes(sourceVertex, predecessorVertexes); ///
115
+
116
+ firstCycle = cycle; ///
117
+ }
118
+
119
+ return terminate;
120
+ });
91
121
  }
92
122
 
93
- return cyclesPresent;
123
+ return firstCycle;
94
124
  }
95
125
 
96
- getFirstCycleByVertexName(vertexName) {
97
- let firstCycle = null;
98
-
99
- const vertex = this.directedAcyclicGraph.getVertexByVertexName(vertexName),
100
- cyclicEdges = this.cyclicEdges.slice(), ///
101
- partialCycles = [],
102
- cycles = [];
103
-
104
- forwardsDepthFirstSearch(vertex, (visitedVertex, getPredecessorVertices) => {
105
- const visitedVertexName = visitedVertex.getName(),
106
- sourceVertexName = visitedVertexName; ///
107
-
108
- filter(cyclicEdges, (cyclicEdge) => {
109
- const matches = cyclicEdge.matchSourceVertexName(sourceVertexName);
110
-
111
- if (matches) {
112
- const predecessorVertices = getPredecessorVertices(),
113
- partialCycle = PartialCycle.fromCyclicEdgeAndPredecessorVertices(cyclicEdge, predecessorVertices);
114
-
115
- partialCycles.push(partialCycle);
116
- } else {
117
- return true;
126
+ getCyclicEdges() {
127
+ const cyclicEdges = [],
128
+ vertexes = this.getVertexes();
129
+
130
+ vertexes.forEach((vertex) => {
131
+ const sourceVertex = vertex, ///
132
+ sourceVertexIndex = sourceVertex.getIndex();
133
+
134
+ vertex.forEachImmediateSuccessorVertex((immediateSuccessorVertex) => {
135
+ const targetVertex = immediateSuccessorVertex, ///
136
+ targetVertexIndex = targetVertex.getIndex();
137
+
138
+ if (targetVertexIndex < sourceVertexIndex) {
139
+ const sourceVertexName = sourceVertex.getName(),
140
+ targetVertexName = targetVertex.getName(),
141
+ edge = Edge.fromSourceVertexNameAndTargetVertexName(sourceVertexName, targetVertexName),
142
+ cyclicEdge = edge; ///
143
+
144
+ cyclicEdges.push(cyclicEdge);
118
145
  }
119
146
  });
120
147
 
121
- const cyclicEdgesLength = cyclicEdges.length,
122
- terminate = (cyclicEdgesLength === 0);
123
-
124
- return terminate;
148
+ sourceVertex
125
149
  });
126
150
 
127
- partialCycles.some((partialCycle) => {
128
- const targetVertexName = partialCycle.getTargetVertexName(),
129
- targetVertex = this.directedAcyclicGraph.getVertexByVertexName(targetVertexName);
151
+ return cyclicEdges;
152
+ }
130
153
 
131
- forwardsDepthFirstSearch(targetVertex, (visitedVertex, getPredecessorVertices) => {
132
- const visitedVertexName = visitedVertex.getName();
154
+ areCyclesPresent() {
155
+ const vertexes = this.getVertexes(),
156
+ cyclesPresent = vertexes.some((vertex) => {
157
+ const sourceVertex = vertex, ///
158
+ sourceVertexIndex = sourceVertex.getIndex(),
159
+ cyclicEdgePresent = vertex.someImmediateSuccessorVertex((immediateSuccessorVertex) => {
160
+ const targetVertex = immediateSuccessorVertex, ///
161
+ targetVertexIndex = targetVertex.getIndex();
162
+
163
+ if (targetVertexIndex < sourceVertexIndex) {
164
+ return true;
165
+ }
166
+ });
167
+
168
+ if (cyclicEdgePresent) {
169
+ return true;
170
+ }
171
+ });
133
172
 
134
- if (visitedVertexName === vertexName) {
135
- const predecessorVertices = getPredecessorVertices(),
136
- successorVertices = predecessorVertices, ///
137
- cycle = Cycle.fromVertexNamePartialCycleAndSuccessorVertices(vertexName, partialCycle, successorVertices);
173
+ return cyclesPresent;
174
+ }
138
175
 
139
- cycles.push(cycle);
140
- }
176
+ isEdgePresent(edge) {
177
+ let edgePresent = false;
141
178
 
142
- const cyclesLength = cycles.length,
143
- terminate = (cyclesLength > 0);
179
+ const sourceVertexName = edge.getSourceVertexName(),
180
+ sourceVertex = this.getVertexByVertexName(sourceVertexName);
144
181
 
145
- return terminate;
146
- });
147
- });
182
+ if (sourceVertex !== null) {
183
+ const targetVertexName = edge.getTargetVertexName(),
184
+ targetVertex = this.getVertexByVertexName(targetVertexName);
148
185
 
149
- const cyclesLength = cycles.length;
150
-
151
- if (cyclesLength > 0) {
152
- firstCycle = first(cycles);
186
+ if (targetVertex !== null) {
187
+ edgePresent = sourceVertex.isEdgePresentByTargetVertex(targetVertex);
188
+ }
153
189
  }
154
190
 
155
- return firstCycle;
191
+ return edgePresent;
156
192
  }
157
193
 
158
- getFirstCycle() {
159
- const firstCyclicEdge = first(this.cyclicEdges),
160
- cyclicEdge = firstCyclicEdge, ///
161
- sourceVertexName = cyclicEdge.getSourceVertexName(),
162
- vertexName = sourceVertexName, ///
163
- firstCycle = this.getFirstCycleByVertexName(vertexName);
194
+ isVertexPresentByVertexName(vertexName) {
195
+ const vertexNames = this.getVertexNames(),
196
+ vertexNamesIncludesVertexName = vertexNames.includes(vertexName),
197
+ vertexPresent = vertexNamesIncludesVertexName; ///
164
198
 
165
- return firstCycle;
199
+ return vertexPresent;
166
200
  }
167
201
 
168
- areCyclesPresent() {
169
- const cyclicEdgesLength = this.cyclicEdges.length,
170
- cyclesPresent = (cyclicEdgesLength > 0);
202
+ addVertexByVertexName(vertexName) {
203
+ const vertexPresent = this.isVertexPresentByVertexName(vertexName);
171
204
 
172
- return cyclesPresent;
173
- }
205
+ if (!vertexPresent) {
206
+ const vertexNames = this.getVertexNames(),
207
+ vertexNamesLength = vertexNames.length,
208
+ name = vertexName, ///
209
+ index = vertexNamesLength, ///
210
+ vertex = Vertex.fromNameAndIndex(name, index);
174
211
 
175
- addVerticesByVertexNames(vertexNames) {
176
- vertexNames.forEach((vertexName) => this.addVertexByVertexName(vertexName));
212
+ this.setVertexByVertexName(vertexName, vertex);
213
+ }
214
+
215
+ const vertex = this.getVertexByVertexName(vertexName);
216
+
217
+ return vertex;
177
218
  }
178
219
 
179
220
  removeVertexByVertexName(vertexName) {
180
- this.directedAcyclicGraph.removeVertexByVertexName(vertexName);
221
+ const vertexPresent = this.isVertexPresentByVertexName(vertexName);
181
222
 
182
- this.filterCyclicEdges();
183
- }
223
+ if (!vertexPresent) {
224
+ return;
225
+ }
184
226
 
185
- removeVerticesByVertexNames(vertexNames) {
186
- vertexNames.forEach((vertexName) => this.removeVertexByVertexName(vertexName));
227
+ const vertex = this.getVertexByVertexName(vertexName);
228
+
229
+ vertex.forEachImmediateSuccessorVertex((immediateSuccessVertex) => {
230
+ const immediatePredecessorVertex = vertex; ///
231
+
232
+ immediateSuccessVertex.removeImmediatePredecessorVertex(immediatePredecessorVertex);
233
+ });
234
+
235
+ vertex.forEachImmediatePredecessorVertex((immediatePredecessorVertex) => {
236
+ const immediateSuccessVertex = vertex; ///
237
+
238
+ immediatePredecessorVertex.removeImmediateSuccessorVertex(immediateSuccessVertex);
239
+ });
240
+
241
+ this.deleteVertexByVertexName(vertexName);
242
+
243
+ const vertexes = this.getVertexes(),
244
+ deletedVertex = vertex, ///
245
+ deletedVertexIndex = deletedVertex.getIndex();
246
+
247
+ vertexes.forEach((vertex) => {
248
+ const vertexIndex = vertex.getIndex();
249
+
250
+ if (vertexIndex > deletedVertexIndex) {
251
+ vertex.decrementIndex();
252
+ }
253
+ });
254
+
255
+ this.filterCyclicEdges();
187
256
  }
188
257
 
189
258
  addEdge(edge) {
190
- const success = this.directedAcyclicGraph.addEdge(edge);
191
-
192
- if (!success) {
193
- const cyclicEdgesIncludesEdge = checkEdgesIncludesEdge(edge, this.cyclicEdges);
259
+ const sourceVertexName = edge.getSourceVertexName(),
260
+ targetVertexName = edge.getTargetVertexName();
194
261
 
195
- if (!cyclicEdgesIncludesEdge) {
196
- const cyclicEdge = edge; ///
262
+ if (sourceVertexName === targetVertexName) {
263
+ return;
264
+ }
197
265
 
198
- this.cyclicEdges.push(cyclicEdge);
199
- }
266
+ const sourceVertex = this.addVertexByVertexName(sourceVertexName),
267
+ targetVertex = this.addVertexByVertexName(targetVertexName),
268
+ edgePresent = sourceVertex.isEdgePresentByTargetVertex(targetVertex);
269
+
270
+ if (edgePresent) {
271
+ return;
200
272
  }
273
+
274
+ const sourceVertexIndex = sourceVertex.getIndex(),
275
+ targetVertexIndex = targetVertex.getIndex();
276
+
277
+ if (sourceVertexIndex > targetVertexIndex) {
278
+ this.reorderVertexesBySourceVertexAndTargetVertex(sourceVertex, targetVertex);
279
+ }
280
+
281
+ const immediatePredecessorVertex = sourceVertex, ///
282
+ immediateSuccessorVertex = targetVertex; ///
283
+
284
+ immediatePredecessorVertex.addImmediateSuccessorVertex(immediateSuccessorVertex);
285
+
286
+ immediateSuccessorVertex.addImmediatePredecessorVertex(immediatePredecessorVertex);
201
287
  }
202
-
288
+
203
289
  addEdges(edges) {
204
- edges.forEach((edge) => this.addEdge(edge));
290
+ edges.forEach((edge) => {
291
+ this.addEdge(edge);
292
+ });
205
293
  }
206
294
 
207
- removeEdge(edge, removeStrandedVertices = false) {
208
- const cyclicEdgesIncludesEdge = checkEdgesIncludesEdge(edge, this.cyclicEdges),
209
- edgePresent = this.directedAcyclicGraph.isEdgePresent(edge),
210
- edgeCyclic = cyclicEdgesIncludesEdge; ///
211
-
212
- if (false) {
213
- ///
214
- } else if (edgeCyclic) {
215
- const cyclicEdge = edge; ///
216
-
217
- removeEdgeFromEdges(cyclicEdge, this.cyclicEdges);
218
- } else if (edgePresent) {
219
- this.directedAcyclicGraph.removeEdge(edge);
220
-
221
- if (removeStrandedVertices) {
222
- const sourceVertexName = edge.getSourceVertexName(),
223
- targetVertexName = edge.getTargetVertexName(),
224
- sourceVertex = this.directedAcyclicGraph.getVertexByVertexName(sourceVertexName),
225
- targetVertex = this.directedAcyclicGraph.getVertexByVertexName(targetVertexName),
226
- sourceVertexStranded = sourceVertex.isStranded(),
227
- targetVertexStranded = targetVertex.isStranded();
228
-
229
- if (sourceVertexStranded) {
230
- this.directedAcyclicGraph.removeVertexByVertexName(sourceVertexName);
231
- }
295
+ removeEdge(edge, removeStrandedVertexes) {
296
+ const sourceVertexName = edge.getSourceVertexName(),
297
+ targetVertexName = edge.getTargetVertexName(),
298
+ sourceVertex = this.addVertexByVertexName(sourceVertexName),
299
+ targetVertex = this.addVertexByVertexName(targetVertexName),
300
+ edgePresent = sourceVertex.isEdgePresentByTargetVertex(targetVertex);
232
301
 
233
- if (targetVertexStranded) {
234
- this.directedAcyclicGraph.removeVertexByVertexName(targetVertexName);
235
- }
302
+ if (!edgePresent) {
303
+ return;
304
+ }
305
+
306
+ sourceVertex.removeImmediateSuccessorVertex(targetVertex);
307
+
308
+ targetVertex.removeImmediatePredecessorVertex(sourceVertex);
309
+
310
+ if (removeStrandedVertexes) {
311
+ const sourceVertexStranded = sourceVertex.isStranded(),
312
+ targetVertexStranded = targetVertex.isStranded();
313
+
314
+ if (sourceVertexStranded) {
315
+ this.removeVertexByVertexName(sourceVertexName);
316
+ }
317
+
318
+ if (targetVertexStranded) {
319
+ this.removeVertexByVertexName(targetVertexName);
236
320
  }
237
321
  }
238
322
 
239
323
  this.filterCyclicEdges();
240
324
  }
241
325
 
242
- removeEdges(edges, removeStrandedVertices = false) {
243
- edges.forEach((edge) => this.removeEdge(edge, removeStrandedVertices));
326
+ removeEdges(edges, removeStrandedVertexes = false) {
327
+ edges.forEach((edge) => {
328
+ this.removeEdge(edge, removeStrandedVertexes);
329
+ });
244
330
  }
245
331
 
246
- addEdgeByVertexNames(sourceVertexName, targetVertexName) {
247
- const edge = Edge.fromSourceVertexNameAndTargetVertexName(sourceVertexName, targetVertexName);
248
-
249
- this.addEdge(edge);
332
+ removeAllEdgesAndVertexes() {
333
+ this.vertexMap = {};
250
334
  }
251
335
 
252
- removeEdgeByVertexNames(sourceVertexName, targetVertexName, removeStrandedVertices = false) {
253
- const edge = Edge.fromSourceVertexNameAndTargetVertexName(sourceVertexName, targetVertexName);
336
+ reorderVertexesBySourceVertexAndTargetVertex(sourceVertex, targetVertex) {
337
+ const sourceVertexReachable = targetVertex.isVertexReachable(sourceVertex);
254
338
 
255
- this.removeEdge(edge, removeStrandedVertices);
256
- }
339
+ if (sourceVertexReachable) {
340
+ return;
341
+ }
257
342
 
258
- removeEdgesByTargetVertexName(targetVertexName, removeStrandedVertices = false) {
259
- const cyclicEdges = edgesByTargetVertexName(targetVertexName, this.cyclicEdges),
260
- edges = this.directedAcyclicGraph.getEdgesByTargetVertexName(targetVertexName);
343
+ const forwardsVisitedVertexes = targetVertex.retrieveForwardsVisitedVertexes(),
344
+ backwardsVisitedVertexes = sourceVertex.retrieveBackwardsVisitedVertexes();
261
345
 
262
- this.removeEdges(cyclicEdges, removeStrandedVertices);
346
+ orderVertexes(backwardsVisitedVertexes);
263
347
 
264
- this.removeEdges(edges, removeStrandedVertices);
265
- }
348
+ orderVertexes(forwardsVisitedVertexes);
266
349
 
267
- removeEdgesBySourceVertexName(sourceVertexName, removeStrandedVertices = false) {
268
- const cyclicEdges = edgesBySourceVertexName(sourceVertexName, this.cyclicEdges),
269
- edges = this.directedAcyclicGraph.getEdgesBySourceVertexName(sourceVertexName);
350
+ const visitedVertexes = [
351
+ ...backwardsVisitedVertexes,
352
+ ...forwardsVisitedVertexes
353
+ ],
354
+ visitedIndexes = indexesFromVertexes(visitedVertexes);
270
355
 
271
- this.removeEdges(cyclicEdges, removeStrandedVertices);
356
+ orderIndexes(visitedIndexes);
272
357
 
273
- this.removeEdges(edges, removeStrandedVertices);
274
- }
358
+ visitedVertexes.forEach((visitedVertex, index) => {
359
+ const visitedIndex = visitedIndexes[index];
275
360
 
276
- removeAllEdgesAndVertices() {
277
- this.directedAcyclicGraph = DirectedAcyclicGraph.fromNothing();
361
+ index = visitedIndex; ///
278
362
 
279
- this.cyclicEdges = [];
363
+ visitedVertex.setIndex(index);
364
+ });
280
365
  }
281
366
 
282
367
  filterCyclicEdges() {
283
- filter(this.cyclicEdges, (cyclicEdge) => {
284
- const sourceVertexName = cyclicEdge.getSourceVertexName(),
285
- targetVertexName = cyclicEdge.getTargetVertexName(),
286
- sourceVertexPresent = this.isVertexPresentByVertexName(sourceVertexName),
287
- targetVertexPresent = this.isVertexPresentByVertexName(targetVertexName);
288
-
289
- if (sourceVertexPresent && targetVertexPresent) {
290
- return true;
291
- }
292
- });
368
+ const cyclicEdges = this.getCyclicEdges(),
369
+ edges = cyclicEdges; ///
293
370
 
294
- filter(this.cyclicEdges, (cyclicEdge) => {
295
- const edge = cyclicEdge, ///
296
- success = this.directedAcyclicGraph.addEdge(edge);
371
+ this.removeEdges(edges);
297
372
 
298
- if (!success) {
299
- return true;
300
- }
301
- });
373
+ this.addEdges(edges);
374
+ }
375
+
376
+ setVertexByVertexName(vertexName, vertex) {
377
+ this.vertexMap[vertexName] = vertex;
378
+ }
379
+
380
+ deleteVertexByVertexName(vertexName) {
381
+ delete this.vertexMap[vertexName];
302
382
  }
303
383
 
304
384
  static fromNothing() {
305
- const cyclicEdges = [],
306
- directedAcyclicGraph = DirectedAcyclicGraph.fromNothing(),
307
- directedGraph = new DirectedGraph(cyclicEdges, directedAcyclicGraph);
385
+ const vertexMap = {},
386
+ directedGraph = new DirectedGraph(vertexMap);
308
387
 
309
388
  return directedGraph;
310
389
  }
package/src/index.js CHANGED
@@ -1,4 +1,6 @@
1
1
  "use strict";
2
2
 
3
3
  export { default as Edge } from "./edge";
4
+ export { default as Cycle } from "./cycle";
5
+ export { default as Vertex } from "./vertex";
4
6
  export { default as DirectedGraph } from "./directedGraph";
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+
3
+ export function orderIndexes(indexes) { ///
4
+ indexes.sort((firstIndex, secondIndex) => {
5
+ if (false) {
6
+ ///
7
+ } else if (firstIndex < secondIndex) {
8
+ return -1;
9
+ } else if (firstIndex > secondIndex) {
10
+ return +1;
11
+ } else {
12
+ return 0;
13
+ }
14
+ });
15
+ }
16
+
17
+ export function indexesFromVertexes(vertexes) {
18
+ const indexes = vertexes.map((vertex) => {
19
+ const index = vertex.getIndex();
20
+
21
+ return index;
22
+ });
23
+
24
+ return indexes;
25
+ }