min-heap-typed 1.41.8 → 1.41.9
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.
|
@@ -114,9 +114,10 @@ export declare abstract class AbstractGraph<V = any, E = any, VO extends Abstrac
|
|
|
114
114
|
* @param {VO | VertexKey} v1 - The parameter `v1` represents either a vertex object (`VO`) or a vertex ID (`VertexKey`).
|
|
115
115
|
* It is the starting vertex for finding paths.
|
|
116
116
|
* @param {VO | VertexKey} v2 - The parameter `v2` represents either a vertex object (`VO`) or a vertex ID (`VertexKey`).
|
|
117
|
+
* @param limit - The count of limitation of result array.
|
|
117
118
|
* @returns The function `getAllPathsBetween` returns an array of arrays of vertices (`VO[][]`).
|
|
118
119
|
*/
|
|
119
|
-
getAllPathsBetween(v1: VO | VertexKey, v2: VO | VertexKey): VO[][];
|
|
120
|
+
getAllPathsBetween(v1: VO | VertexKey, v2: VO | VertexKey, limit?: number): VO[][];
|
|
120
121
|
/**
|
|
121
122
|
* The function calculates the sum of weights along a given path.
|
|
122
123
|
* @param {VO[]} path - An array of vertices (VO) representing a path in a graph.
|
|
@@ -148,10 +149,13 @@ export declare abstract class AbstractGraph<V = any, E = any, VO extends Abstrac
|
|
|
148
149
|
* @param {boolean} [isWeight] - A boolean flag indicating whether to consider the weight of edges in finding the
|
|
149
150
|
* minimum path. If set to true, the function will use Dijkstra's algorithm to find the minimum weighted path. If set
|
|
150
151
|
* to false, the function will use breadth-first search (BFS) to find the minimum path.
|
|
152
|
+
* @param isDFS - If set to true, it enforces the use of getAllPathsBetween to first obtain all possible paths,
|
|
153
|
+
* followed by iterative computation of the shortest path. This approach may result in exponential time complexity,
|
|
154
|
+
* so the default method is to use the Dijkstra algorithm to obtain the shortest weighted path.
|
|
151
155
|
* @returns The function `getMinPathBetween` returns an array of vertices (`VO[]`) representing the minimum path between
|
|
152
156
|
* two vertices (`v1` and `v2`). If there is no path between the vertices, it returns `null`.
|
|
153
157
|
*/
|
|
154
|
-
getMinPathBetween(v1: VO | VertexKey, v2: VO | VertexKey, isWeight?: boolean): VO[] | null;
|
|
158
|
+
getMinPathBetween(v1: VO | VertexKey, v2: VO | VertexKey, isWeight?: boolean, isDFS?: boolean): VO[] | null;
|
|
155
159
|
/**
|
|
156
160
|
* Dijkstra algorithm time: O(VE) space: O(VO + EO)
|
|
157
161
|
* /
|
|
@@ -4,8 +4,8 @@ exports.AbstractGraph = exports.AbstractEdge = exports.AbstractVertex = void 0;
|
|
|
4
4
|
/**
|
|
5
5
|
* data-structure-typed
|
|
6
6
|
*
|
|
7
|
-
* @author
|
|
8
|
-
* @copyright Copyright (c) 2022
|
|
7
|
+
* @author Tyler Zeng
|
|
8
|
+
* @copyright Copyright (c) 2022 Tyler Zeng <zrwusa@gmail.com>
|
|
9
9
|
* @license MIT License
|
|
10
10
|
*/
|
|
11
11
|
const utils_1 = require("../../utils");
|
|
@@ -162,31 +162,33 @@ class AbstractGraph {
|
|
|
162
162
|
* @param {VO | VertexKey} v1 - The parameter `v1` represents either a vertex object (`VO`) or a vertex ID (`VertexKey`).
|
|
163
163
|
* It is the starting vertex for finding paths.
|
|
164
164
|
* @param {VO | VertexKey} v2 - The parameter `v2` represents either a vertex object (`VO`) or a vertex ID (`VertexKey`).
|
|
165
|
+
* @param limit - The count of limitation of result array.
|
|
165
166
|
* @returns The function `getAllPathsBetween` returns an array of arrays of vertices (`VO[][]`).
|
|
166
167
|
*/
|
|
167
|
-
getAllPathsBetween(v1, v2) {
|
|
168
|
+
getAllPathsBetween(v1, v2, limit = 1000) {
|
|
168
169
|
const paths = [];
|
|
169
170
|
const vertex1 = this._getVertex(v1);
|
|
170
171
|
const vertex2 = this._getVertex(v2);
|
|
171
172
|
if (!(vertex1 && vertex2)) {
|
|
172
173
|
return [];
|
|
173
174
|
}
|
|
174
|
-
const
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
175
|
+
const stack = [];
|
|
176
|
+
stack.push({ vertex: vertex1, path: [vertex1] });
|
|
177
|
+
while (stack.length > 0) {
|
|
178
|
+
const { vertex, path } = stack.pop();
|
|
179
|
+
if (vertex === vertex2) {
|
|
180
|
+
paths.push(path);
|
|
181
|
+
if (paths.length >= limit)
|
|
182
|
+
return paths;
|
|
178
183
|
}
|
|
179
|
-
const neighbors = this.getNeighbors(
|
|
184
|
+
const neighbors = this.getNeighbors(vertex);
|
|
180
185
|
for (const neighbor of neighbors) {
|
|
181
|
-
if (!
|
|
182
|
-
path
|
|
183
|
-
|
|
184
|
-
path.pop();
|
|
186
|
+
if (!path.includes(neighbor)) {
|
|
187
|
+
const newPath = [...path, neighbor];
|
|
188
|
+
stack.push({ vertex: neighbor, path: newPath });
|
|
185
189
|
}
|
|
186
190
|
}
|
|
187
|
-
|
|
188
|
-
};
|
|
189
|
-
dfs(vertex1, vertex2, new Set(), []);
|
|
191
|
+
}
|
|
190
192
|
return paths;
|
|
191
193
|
}
|
|
192
194
|
/**
|
|
@@ -270,52 +272,60 @@ class AbstractGraph {
|
|
|
270
272
|
* @param {boolean} [isWeight] - A boolean flag indicating whether to consider the weight of edges in finding the
|
|
271
273
|
* minimum path. If set to true, the function will use Dijkstra's algorithm to find the minimum weighted path. If set
|
|
272
274
|
* to false, the function will use breadth-first search (BFS) to find the minimum path.
|
|
275
|
+
* @param isDFS - If set to true, it enforces the use of getAllPathsBetween to first obtain all possible paths,
|
|
276
|
+
* followed by iterative computation of the shortest path. This approach may result in exponential time complexity,
|
|
277
|
+
* so the default method is to use the Dijkstra algorithm to obtain the shortest weighted path.
|
|
273
278
|
* @returns The function `getMinPathBetween` returns an array of vertices (`VO[]`) representing the minimum path between
|
|
274
279
|
* two vertices (`v1` and `v2`). If there is no path between the vertices, it returns `null`.
|
|
275
280
|
*/
|
|
276
|
-
getMinPathBetween(v1, v2, isWeight) {
|
|
281
|
+
getMinPathBetween(v1, v2, isWeight, isDFS = false) {
|
|
282
|
+
var _a, _b;
|
|
277
283
|
if (isWeight === undefined)
|
|
278
284
|
isWeight = false;
|
|
279
285
|
if (isWeight) {
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
const
|
|
286
|
-
|
|
287
|
-
min
|
|
288
|
-
|
|
286
|
+
if (isDFS) {
|
|
287
|
+
const allPaths = this.getAllPathsBetween(v1, v2, 10000);
|
|
288
|
+
let min = Infinity;
|
|
289
|
+
let minIndex = -1;
|
|
290
|
+
let index = 0;
|
|
291
|
+
for (const path of allPaths) {
|
|
292
|
+
const pathSumWeight = this.getPathSumWeight(path);
|
|
293
|
+
if (pathSumWeight < min) {
|
|
294
|
+
min = pathSumWeight;
|
|
295
|
+
minIndex = index;
|
|
296
|
+
}
|
|
297
|
+
index++;
|
|
289
298
|
}
|
|
290
|
-
|
|
299
|
+
return allPaths[minIndex] || null;
|
|
300
|
+
}
|
|
301
|
+
else {
|
|
302
|
+
return (_b = (_a = this.dijkstra(v1, v2, true, true)) === null || _a === void 0 ? void 0 : _a.minPath) !== null && _b !== void 0 ? _b : [];
|
|
291
303
|
}
|
|
292
|
-
return allPaths[minIndex] || null;
|
|
293
304
|
}
|
|
294
305
|
else {
|
|
295
|
-
//
|
|
306
|
+
// DFS
|
|
296
307
|
let minPath = [];
|
|
297
308
|
const vertex1 = this._getVertex(v1);
|
|
298
309
|
const vertex2 = this._getVertex(v2);
|
|
299
|
-
if (!(vertex1 && vertex2))
|
|
310
|
+
if (!(vertex1 && vertex2))
|
|
300
311
|
return [];
|
|
301
|
-
}
|
|
302
312
|
const dfs = (cur, dest, visiting, path) => {
|
|
303
|
-
visiting.
|
|
313
|
+
visiting.add(cur);
|
|
304
314
|
if (cur === dest) {
|
|
305
315
|
minPath = [vertex1, ...path];
|
|
306
316
|
return;
|
|
307
317
|
}
|
|
308
318
|
const neighbors = this.getNeighbors(cur);
|
|
309
319
|
for (const neighbor of neighbors) {
|
|
310
|
-
if (!visiting.
|
|
320
|
+
if (!visiting.has(neighbor)) {
|
|
311
321
|
path.push(neighbor);
|
|
312
322
|
dfs(neighbor, dest, visiting, path);
|
|
313
|
-
|
|
323
|
+
path.pop();
|
|
314
324
|
}
|
|
315
325
|
}
|
|
316
|
-
visiting.
|
|
326
|
+
visiting.delete(cur);
|
|
317
327
|
};
|
|
318
|
-
dfs(vertex1, vertex2, new
|
|
328
|
+
dfs(vertex1, vertex2, new Set(), []);
|
|
319
329
|
return minPath;
|
|
320
330
|
}
|
|
321
331
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "min-heap-typed",
|
|
3
|
-
"version": "1.41.
|
|
3
|
+
"version": "1.41.9",
|
|
4
4
|
"description": "Min Heap. Javascript & Typescript Data Structure.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -132,6 +132,6 @@
|
|
|
132
132
|
"typescript": "^4.9.5"
|
|
133
133
|
},
|
|
134
134
|
"dependencies": {
|
|
135
|
-
"data-structure-typed": "^1.41.
|
|
135
|
+
"data-structure-typed": "^1.41.9"
|
|
136
136
|
}
|
|
137
137
|
}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* data-structure-typed
|
|
3
3
|
*
|
|
4
|
-
* @author
|
|
5
|
-
* @copyright Copyright (c) 2022
|
|
4
|
+
* @author Tyler Zeng
|
|
5
|
+
* @copyright Copyright (c) 2022 Tyler Zeng <zrwusa@gmail.com>
|
|
6
6
|
* @license MIT License
|
|
7
7
|
*/
|
|
8
|
-
import {
|
|
8
|
+
import {uuidV4} from '../../utils';
|
|
9
9
|
import {PriorityQueue} from '../priority-queue';
|
|
10
10
|
import type {DijkstraResult, VertexKey} from '../../types';
|
|
11
11
|
import {IGraph} from '../../interfaces';
|
|
@@ -223,39 +223,43 @@ export abstract class AbstractGraph<
|
|
|
223
223
|
* @param {VO | VertexKey} v1 - The parameter `v1` represents either a vertex object (`VO`) or a vertex ID (`VertexKey`).
|
|
224
224
|
* It is the starting vertex for finding paths.
|
|
225
225
|
* @param {VO | VertexKey} v2 - The parameter `v2` represents either a vertex object (`VO`) or a vertex ID (`VertexKey`).
|
|
226
|
+
* @param limit - The count of limitation of result array.
|
|
226
227
|
* @returns The function `getAllPathsBetween` returns an array of arrays of vertices (`VO[][]`).
|
|
227
228
|
*/
|
|
228
|
-
getAllPathsBetween(v1: VO | VertexKey, v2: VO | VertexKey): VO[][] {
|
|
229
|
+
getAllPathsBetween(v1: VO | VertexKey, v2: VO | VertexKey, limit = 1000): VO[][] {
|
|
229
230
|
const paths: VO[][] = [];
|
|
230
231
|
const vertex1 = this._getVertex(v1);
|
|
231
232
|
const vertex2 = this._getVertex(v2);
|
|
233
|
+
|
|
232
234
|
if (!(vertex1 && vertex2)) {
|
|
233
235
|
return [];
|
|
234
236
|
}
|
|
235
237
|
|
|
236
|
-
const
|
|
237
|
-
|
|
238
|
+
const stack: { vertex: VO, path: VO[] }[] = [];
|
|
239
|
+
stack.push({ vertex: vertex1, path: [vertex1] });
|
|
240
|
+
|
|
241
|
+
while (stack.length > 0) {
|
|
242
|
+
const { vertex, path } = stack.pop()!;
|
|
238
243
|
|
|
239
|
-
if (
|
|
240
|
-
paths.push(
|
|
244
|
+
if (vertex === vertex2) {
|
|
245
|
+
paths.push(path);
|
|
246
|
+
if (paths.length >= limit) return paths;
|
|
241
247
|
}
|
|
242
248
|
|
|
243
|
-
const neighbors = this.getNeighbors(
|
|
249
|
+
const neighbors = this.getNeighbors(vertex);
|
|
244
250
|
for (const neighbor of neighbors) {
|
|
245
|
-
if (!
|
|
246
|
-
path
|
|
247
|
-
|
|
248
|
-
path.pop();
|
|
251
|
+
if (!path.includes(neighbor)) {
|
|
252
|
+
const newPath = [...path, neighbor];
|
|
253
|
+
stack.push({ vertex: neighbor, path: newPath });
|
|
249
254
|
}
|
|
250
255
|
}
|
|
251
|
-
|
|
252
|
-
visiting.delete(cur);
|
|
253
|
-
};
|
|
254
|
-
|
|
255
|
-
dfs(vertex1, vertex2, new Set<VO>(), []);
|
|
256
|
+
}
|
|
256
257
|
return paths;
|
|
257
258
|
}
|
|
258
259
|
|
|
260
|
+
|
|
261
|
+
|
|
262
|
+
|
|
259
263
|
/**
|
|
260
264
|
* The function calculates the sum of weights along a given path.
|
|
261
265
|
* @param {VO[]} path - An array of vertices (VO) representing a path in a graph.
|
|
@@ -338,38 +342,43 @@ export abstract class AbstractGraph<
|
|
|
338
342
|
* @param {boolean} [isWeight] - A boolean flag indicating whether to consider the weight of edges in finding the
|
|
339
343
|
* minimum path. If set to true, the function will use Dijkstra's algorithm to find the minimum weighted path. If set
|
|
340
344
|
* to false, the function will use breadth-first search (BFS) to find the minimum path.
|
|
345
|
+
* @param isDFS - If set to true, it enforces the use of getAllPathsBetween to first obtain all possible paths,
|
|
346
|
+
* followed by iterative computation of the shortest path. This approach may result in exponential time complexity,
|
|
347
|
+
* so the default method is to use the Dijkstra algorithm to obtain the shortest weighted path.
|
|
341
348
|
* @returns The function `getMinPathBetween` returns an array of vertices (`VO[]`) representing the minimum path between
|
|
342
349
|
* two vertices (`v1` and `v2`). If there is no path between the vertices, it returns `null`.
|
|
343
350
|
*/
|
|
344
|
-
getMinPathBetween(v1: VO | VertexKey, v2: VO | VertexKey, isWeight?: boolean): VO[] | null {
|
|
351
|
+
getMinPathBetween(v1: VO | VertexKey, v2: VO | VertexKey, isWeight?: boolean, isDFS = false): VO[] | null {
|
|
345
352
|
if (isWeight === undefined) isWeight = false;
|
|
346
353
|
|
|
347
354
|
if (isWeight) {
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
const
|
|
354
|
-
|
|
355
|
-
min
|
|
356
|
-
|
|
355
|
+
if (isDFS) {
|
|
356
|
+
const allPaths = this.getAllPathsBetween(v1, v2, 10000);
|
|
357
|
+
let min = Infinity;
|
|
358
|
+
let minIndex = -1;
|
|
359
|
+
let index = 0;
|
|
360
|
+
for (const path of allPaths) {
|
|
361
|
+
const pathSumWeight = this.getPathSumWeight(path);
|
|
362
|
+
if (pathSumWeight < min) {
|
|
363
|
+
min = pathSumWeight;
|
|
364
|
+
minIndex = index;
|
|
365
|
+
}
|
|
366
|
+
index++;
|
|
357
367
|
}
|
|
358
|
-
|
|
368
|
+
return allPaths[minIndex] || null;
|
|
369
|
+
} else {
|
|
370
|
+
return this.dijkstra(v1, v2, true, true)?.minPath ?? [];
|
|
359
371
|
}
|
|
360
|
-
|
|
372
|
+
|
|
361
373
|
} else {
|
|
362
|
-
//
|
|
374
|
+
// DFS
|
|
363
375
|
let minPath: VO[] = [];
|
|
364
376
|
const vertex1 = this._getVertex(v1);
|
|
365
377
|
const vertex2 = this._getVertex(v2);
|
|
366
|
-
if (!(vertex1 && vertex2))
|
|
367
|
-
return [];
|
|
368
|
-
}
|
|
369
|
-
|
|
370
|
-
const dfs = (cur: VO, dest: VO, visiting: Map<VO, boolean>, path: VO[]) => {
|
|
371
|
-
visiting.set(cur, true);
|
|
378
|
+
if (!(vertex1 && vertex2)) return [];
|
|
372
379
|
|
|
380
|
+
const dfs = (cur: VO, dest: VO, visiting: Set<VO>, path: VO[]) => {
|
|
381
|
+
visiting.add(cur);
|
|
373
382
|
if (cur === dest) {
|
|
374
383
|
minPath = [vertex1, ...path];
|
|
375
384
|
return;
|
|
@@ -377,17 +386,17 @@ export abstract class AbstractGraph<
|
|
|
377
386
|
|
|
378
387
|
const neighbors = this.getNeighbors(cur);
|
|
379
388
|
for (const neighbor of neighbors) {
|
|
380
|
-
if (!visiting.
|
|
389
|
+
if (!visiting.has(neighbor)) {
|
|
381
390
|
path.push(neighbor);
|
|
382
391
|
dfs(neighbor, dest, visiting, path);
|
|
383
|
-
|
|
392
|
+
path.pop();
|
|
384
393
|
}
|
|
385
394
|
}
|
|
386
395
|
|
|
387
|
-
visiting.
|
|
396
|
+
visiting.delete(cur);
|
|
388
397
|
};
|
|
389
398
|
|
|
390
|
-
dfs(vertex1, vertex2, new
|
|
399
|
+
dfs(vertex1, vertex2, new Set<VO>(), []);
|
|
391
400
|
return minPath;
|
|
392
401
|
}
|
|
393
402
|
}
|