@thi.ng/adjacency 2.2.20 → 2.3.1

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/CHANGELOG.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Change Log
2
2
 
3
- - **Last updated**: 2022-12-20T16:33:11Z
3
+ - **Last updated**: 2022-12-22T21:47:07Z
4
4
  - **Generator**: [thi.ng/monopub](https://thi.ng/monopub)
5
5
 
6
6
  All notable changes to this project will be documented in this file.
@@ -9,6 +9,13 @@ See [Conventional Commits](https://conventionalcommits.org/) for commit guidelin
9
9
  **Note:** Unlisted _patch_ versions only involve non-code or otherwise excluded changes
10
10
  and/or version bumps of transitive dependencies.
11
11
 
12
+ ## [2.3.0](https://github.com/thi-ng/umbrella/tree/@thi.ng/adjacency@2.3.0) (2022-12-22)
13
+
14
+ #### 🚀 Features
15
+
16
+ - add FloydWarshall shortest-path impl ([26fa3ac](https://github.com/thi-ng/umbrella/commit/26fa3ac))
17
+ - update BFS distance array to Float32Array ([3997923](https://github.com/thi-ng/umbrella/commit/3997923))
18
+
12
19
  ### [2.2.12](https://github.com/thi-ng/umbrella/tree/@thi.ng/adjacency@2.2.12) (2022-10-26)
13
20
 
14
21
  #### ♻️ Refactoring
package/README.md CHANGED
@@ -10,6 +10,8 @@ This project is part of the
10
10
  [@thi.ng/umbrella](https://github.com/thi-ng/umbrella/) monorepo.
11
11
 
12
12
  - [About](#about)
13
+ - [Graph implementations](#graph-implementations)
14
+ - [Traversals](#traversals)
13
15
  - [Status](#status)
14
16
  - [Related packages](#related-packages)
15
17
  - [Installation](#installation)
@@ -21,7 +23,24 @@ This project is part of the
21
23
 
22
24
  ## About
23
25
 
24
- Sparse & bitwise adjacency matrices and related functions for directed & undirected graphs
26
+ Sparse & bitwise adjacency matrices, lists and selected traversal algorithms for directed & undirected graphs.
27
+
28
+ ### Graph implementations
29
+
30
+ The following types all implement the [`IGraph`
31
+ interface](https://docs.thi.ng/umbrella/adjacency/interfaces/IGraph.html) and
32
+ support both directed & undirected graphs:
33
+
34
+ - [AdjacencyBitMatrix (bit matrix based)](https://docs.thi.ng/umbrella/adjacency/classes/AdjacencyBitMatrix.html)
35
+ - [AdjacencyMatrix (sparse matrix based)](https://docs.thi.ng/umbrella/adjacency/classes/AdjacencyMatrix.html)
36
+ - [AdjacencyList](https://docs.thi.ng/umbrella/adjacency/classes/AdjacencyList.html)
37
+
38
+ ### Traversals
39
+
40
+ - [Breadth-First Search](https://docs.thi.ng/umbrella/adjacency/functions/bfs.html)
41
+ - [Depth-First Search](https://docs.thi.ng/umbrella/adjacency/functions/dfs.html)
42
+ - [Floyd-Warshall (global shortest paths search)](https://docs.thi.ng/umbrella/adjacency/functions/floydWarshall.html)
43
+ - [Minimum Spanning Tree](https://docs.thi.ng/umbrella/adjacency/functions/mst.html)
25
44
 
26
45
  ## Status
27
46
 
@@ -53,7 +72,7 @@ For Node.js REPL:
53
72
  const adjacency = await import("@thi.ng/adjacency");
54
73
  ```
55
74
 
56
- Package sizes (brotli'd, pre-treeshake): ESM: 2.28 KB
75
+ Package sizes (brotli'd, pre-treeshake): ESM: 2.54 KB
57
76
 
58
77
  ## Dependencies
59
78
 
package/bfs.d.ts CHANGED
@@ -1,10 +1,22 @@
1
1
  import { BitField } from "@thi.ng/bitfield/bitfield";
2
2
  import type { CostFn, IGraph } from "./api.js";
3
+ /**
4
+ * Breadth-First / shortest path search between `src` and `dest` in `graph`,
5
+ * with optional `cost` function. By default all edges have an uniform cost,
6
+ * i.e. the overall path cost is topological distance.
7
+ *
8
+ * @remarks
9
+ * Also see {@link bfs} for ad hoc queries.
10
+ *
11
+ * Reference:
12
+ * - https://en.wikipedia.org/wiki/Breadth-first_search
13
+ * - https://algs4.cs.princeton.edu/40graphs/
14
+ */
3
15
  export declare class BFS {
4
16
  graph: IGraph;
5
17
  marked: BitField;
6
18
  edges: Uint32Array;
7
- dist: Uint32Array;
19
+ dist: Float32Array;
8
20
  constructor(graph: IGraph, src: number, cost?: CostFn);
9
21
  protected search(id: number, cost: CostFn): void;
10
22
  hasPathTo(id: number): boolean;
package/bfs.js CHANGED
@@ -1,11 +1,23 @@
1
1
  import { BitField } from "@thi.ng/bitfield/bitfield";
2
2
  import { DCons } from "@thi.ng/dcons/dcons";
3
+ /**
4
+ * Breadth-First / shortest path search between `src` and `dest` in `graph`,
5
+ * with optional `cost` function. By default all edges have an uniform cost,
6
+ * i.e. the overall path cost is topological distance.
7
+ *
8
+ * @remarks
9
+ * Also see {@link bfs} for ad hoc queries.
10
+ *
11
+ * Reference:
12
+ * - https://en.wikipedia.org/wiki/Breadth-first_search
13
+ * - https://algs4.cs.princeton.edu/40graphs/
14
+ */
3
15
  export class BFS {
4
16
  constructor(graph, src, cost = () => 1) {
5
17
  this.graph = graph;
6
18
  const numV = graph.numVertices();
7
19
  this.edges = new Uint32Array(numV);
8
- this.dist = new Uint32Array(numV);
20
+ this.dist = new Float32Array(numV);
9
21
  this.marked = new BitField(numV);
10
22
  this.search(src, cost);
11
23
  }
@@ -0,0 +1,61 @@
1
+ import type { CostFn, IGraph } from "./api.js";
2
+ /**
3
+ * Implementation of the Floyd-Warshall algorithm for finding _all_ shortest
4
+ * paths in a directed graph, optionally with positive or negative edge weights.
5
+ * A single execution of the algorithm will find the lengths (summed weights) of
6
+ * shortest paths between all pairs of vertices.
7
+ *
8
+ * @remarks
9
+ * The default cost function is topological distance (i.e. every edge has a
10
+ * length/cost of 1).
11
+ *
12
+ * Paths & accumulated distances can be queried via {@link FloydWarshall.path}
13
+ * and {@link FloydWarshall.distance}.
14
+ *
15
+ * This algorithm is quite memory hungry and requires `|V| * |V| * 8 bytes`,
16
+ * i.e. ~8MB for a graph with 1000 nodes. If possible, use {@link BFS} to
17
+ * perform individual shortest-path queries (rather than this global approach).
18
+ *
19
+ * Reference:
20
+ * - https://en.wikipedia.org/wiki/Floyd%E2%80%93Warshall_algorithm
21
+ */
22
+ export declare class FloydWarshall {
23
+ dist: Float32Array;
24
+ next: Int32Array;
25
+ numV: number;
26
+ /**
27
+ * Instantiates and pre-computes all shortest paths in given `graph`. See
28
+ * class comments for details.
29
+ *
30
+ * @param graph
31
+ * @param cost
32
+ */
33
+ constructor(graph: IGraph<number>, cost?: CostFn);
34
+ /**
35
+ * Returns shortest distance between vertices `a` and `b`, or `undefined` if
36
+ * no connecting path exists. Throws an error if either `a` or `b` are out
37
+ * of bounds.
38
+ *
39
+ * @param a
40
+ * @param b
41
+ */
42
+ distance(a: number, b: number): number | undefined;
43
+ /**
44
+ * Returns iterator of vertex IDs of path between `a` and `b` (if any).
45
+ * Throws an error if either `a` or `b` are out of bounds.
46
+ *
47
+ * @param a
48
+ * @param b
49
+ */
50
+ path(a: number, b: number): Generator<number, void, unknown>;
51
+ protected ensureIndex(id: number): void;
52
+ protected ensurePair(a: number, b: number): void;
53
+ }
54
+ /**
55
+ * Factory function for {@link FloydWarshall}.
56
+ *
57
+ * @param graph
58
+ * @param cost
59
+ */
60
+ export declare const floydWarshall: (graph: IGraph<number>, cost?: CostFn) => FloydWarshall;
61
+ //# sourceMappingURL=floyd-warshall.d.ts.map
@@ -0,0 +1,103 @@
1
+ import { outOfBounds } from "@thi.ng/errors/out-of-bounds";
2
+ /**
3
+ * Implementation of the Floyd-Warshall algorithm for finding _all_ shortest
4
+ * paths in a directed graph, optionally with positive or negative edge weights.
5
+ * A single execution of the algorithm will find the lengths (summed weights) of
6
+ * shortest paths between all pairs of vertices.
7
+ *
8
+ * @remarks
9
+ * The default cost function is topological distance (i.e. every edge has a
10
+ * length/cost of 1).
11
+ *
12
+ * Paths & accumulated distances can be queried via {@link FloydWarshall.path}
13
+ * and {@link FloydWarshall.distance}.
14
+ *
15
+ * This algorithm is quite memory hungry and requires `|V| * |V| * 8 bytes`,
16
+ * i.e. ~8MB for a graph with 1000 nodes. If possible, use {@link BFS} to
17
+ * perform individual shortest-path queries (rather than this global approach).
18
+ *
19
+ * Reference:
20
+ * - https://en.wikipedia.org/wiki/Floyd%E2%80%93Warshall_algorithm
21
+ */
22
+ export class FloydWarshall {
23
+ /**
24
+ * Instantiates and pre-computes all shortest paths in given `graph`. See
25
+ * class comments for details.
26
+ *
27
+ * @param graph
28
+ * @param cost
29
+ */
30
+ constructor(graph, cost = () => 1) {
31
+ const numV = (this.numV = graph.numVertices());
32
+ const dist = (this.dist = new Float32Array(numV * numV).fill(Infinity));
33
+ const next = (this.next = new Int32Array(numV * numV).fill(-1));
34
+ for (let [u, v] of graph.edges()) {
35
+ const idx = u * numV + v;
36
+ dist[idx] = cost(u, v);
37
+ next[idx] = v;
38
+ }
39
+ for (let v = 0; v < numV; v++) {
40
+ const idx = v * numV + v;
41
+ dist[idx] = 0;
42
+ next[idx] = v;
43
+ }
44
+ for (let k = 0; k < numV; k++) {
45
+ for (let i = 0; i < numV; i++) {
46
+ const idxIK = i * numV + k;
47
+ for (let j = 0; j < numV; j++) {
48
+ const idxIJ = i * numV + j;
49
+ const idxKJ = k * numV + j;
50
+ const minD = dist[idxIK] + dist[idxKJ];
51
+ if (dist[idxIJ] > minD) {
52
+ dist[idxIJ] = minD;
53
+ next[idxIJ] = next[idxIK];
54
+ }
55
+ }
56
+ }
57
+ }
58
+ }
59
+ /**
60
+ * Returns shortest distance between vertices `a` and `b`, or `undefined` if
61
+ * no connecting path exists. Throws an error if either `a` or `b` are out
62
+ * of bounds.
63
+ *
64
+ * @param a
65
+ * @param b
66
+ */
67
+ distance(a, b) {
68
+ this.ensurePair(a, b);
69
+ return this.dist[a * this.numV + b];
70
+ }
71
+ /**
72
+ * Returns iterator of vertex IDs of path between `a` and `b` (if any).
73
+ * Throws an error if either `a` or `b` are out of bounds.
74
+ *
75
+ * @param a
76
+ * @param b
77
+ */
78
+ *path(a, b) {
79
+ this.ensurePair(a, b);
80
+ const { next, numV } = this;
81
+ if (next[a * numV + b] === -1)
82
+ return;
83
+ yield a;
84
+ while (a !== b) {
85
+ a = next[a * numV + b];
86
+ yield a;
87
+ }
88
+ }
89
+ ensureIndex(id) {
90
+ !(id >= 0 && id < this.numV) && outOfBounds(id);
91
+ }
92
+ ensurePair(a, b) {
93
+ this.ensureIndex(a);
94
+ this.ensureIndex(b);
95
+ }
96
+ }
97
+ /**
98
+ * Factory function for {@link FloydWarshall}.
99
+ *
100
+ * @param graph
101
+ * @param cost
102
+ */
103
+ export const floydWarshall = (graph, cost) => new FloydWarshall(graph, cost);
package/index.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  export * from "./api.js";
2
2
  export * from "./binary.js";
3
3
  export * from "./disjoint-set.js";
4
+ export * from "./floyd-warshall.js";
4
5
  export * from "./list.js";
5
6
  export * from "./sparse.js";
6
7
  export * from "./bfs.js";
package/index.js CHANGED
@@ -1,6 +1,7 @@
1
1
  export * from "./api.js";
2
2
  export * from "./binary.js";
3
3
  export * from "./disjoint-set.js";
4
+ export * from "./floyd-warshall.js";
4
5
  export * from "./list.js";
5
6
  export * from "./sparse.js";
6
7
  export * from "./bfs.js";
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@thi.ng/adjacency",
3
- "version": "2.2.20",
4
- "description": "Sparse & bitwise adjacency matrices and related functions for directed & undirected graphs",
3
+ "version": "2.3.1",
4
+ "description": "Sparse & bitwise adjacency matrices, lists and selected traversal algorithms for directed & undirected graphs",
5
5
  "type": "module",
6
6
  "module": "./index.js",
7
7
  "typings": "./index.d.ts",
@@ -34,17 +34,17 @@
34
34
  "test": "testament test"
35
35
  },
36
36
  "dependencies": {
37
- "@thi.ng/api": "^8.6.1",
38
- "@thi.ng/arrays": "^2.4.6",
39
- "@thi.ng/bitfield": "^2.2.16",
40
- "@thi.ng/dcons": "^3.2.27",
41
- "@thi.ng/errors": "^2.2.6",
42
- "@thi.ng/sparse": "^0.3.32"
37
+ "@thi.ng/api": "^8.6.2",
38
+ "@thi.ng/arrays": "^2.5.0",
39
+ "@thi.ng/bitfield": "^2.2.17",
40
+ "@thi.ng/dcons": "^3.2.29",
41
+ "@thi.ng/errors": "^2.2.7",
42
+ "@thi.ng/sparse": "^0.3.34"
43
43
  },
44
44
  "devDependencies": {
45
45
  "@microsoft/api-extractor": "^7.33.7",
46
- "@thi.ng/testament": "^0.3.7",
47
- "@thi.ng/vectors": "^7.5.28",
46
+ "@thi.ng/testament": "^0.3.8",
47
+ "@thi.ng/vectors": "^7.5.30",
48
48
  "rimraf": "^3.0.2",
49
49
  "tools": "^0.0.1",
50
50
  "typedoc": "^0.23.22",
@@ -103,6 +103,9 @@
103
103
  "./disjoint-set": {
104
104
  "default": "./disjoint-set.js"
105
105
  },
106
+ "./floyd-warshall": {
107
+ "default": "./floyd-warshall.js"
108
+ },
106
109
  "./list": {
107
110
  "default": "./list.js"
108
111
  },
@@ -119,5 +122,5 @@
119
122
  ],
120
123
  "year": 2018
121
124
  },
122
- "gitHead": "7b2af448da8a63fb21704a79cc4cdf1f3d7d7a64\n"
125
+ "gitHead": "28bb74c67217a352d673b6efdab234921d4a370e\n"
123
126
  }