@thi.ng/adjacency 2.4.0 → 2.5.0

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**: 2023-10-18T18:06:31Z
3
+ - **Last updated**: 2023-10-19T09:52:45Z
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,18 @@ 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.5.0](https://github.com/thi-ng/umbrella/tree/@thi.ng/adjacency@2.5.0) (2023-10-19)
13
+
14
+ #### 🚀 Features
15
+
16
+ - explicit version bump for @firfi's recent additions ([#400](https://github.com/thi-ng/umbrella/issues/400)) ([0d00025](https://github.com/thi-ng/umbrella/commit/0d00025))
17
+ - see: [2fd123d741586fe29a8cc63b7aa30f3ea9d35ab2](https://github.com/thi-ng/umbrella/commit/2fd123d741586fe29a8cc63b7aa30f3ea9d35ab2)
18
+ - update readme with API examples
19
+
20
+ #### 🩹 Bug fixes
21
+
22
+ - fix AdjacencyBitMatrix.numVertices() ([bd034ab](https://github.com/thi-ng/umbrella/commit/bd034ab))
23
+
12
24
  ## [2.4.0](https://github.com/thi-ng/umbrella/tree/@thi.ng/adjacency@2.4.0) (2023-10-18)
13
25
 
14
26
  #### 🚀 Features
package/README.md CHANGED
@@ -19,6 +19,7 @@ This project is part of the
19
19
  - [Dependencies](#dependencies)
20
20
  - [Usage examples](#usage-examples)
21
21
  - [API](#api)
22
+ - [Basic usage](#basic-usage)
22
23
  - [Authors](#authors)
23
24
  - [License](#license)
24
25
 
@@ -73,7 +74,7 @@ For Node.js REPL:
73
74
  const adjacency = await import("@thi.ng/adjacency");
74
75
  ```
75
76
 
76
- Package sizes (brotli'd, pre-treeshake): ESM: 2.54 KB
77
+ Package sizes (brotli'd, pre-treeshake): ESM: 2.57 KB
77
78
 
78
79
  ## Dependencies
79
80
 
@@ -102,16 +103,91 @@ A selection:
102
103
 
103
104
  TODO
104
105
 
106
+ ### Basic usage
107
+
108
+ ```ts tangle:export/readme.ts
109
+ import { defAdjBitMatrix, type Edge } from "@thi.ng/adjacency";
110
+
111
+ // relationships
112
+ const rels = {
113
+ a: ["b", "c"],
114
+ b: ["d"],
115
+ c: ["d", "e"],
116
+ e: ["a", "d", "b"],
117
+ };
118
+
119
+ // form set of unique node IDs
120
+ const nodeIDs = [
121
+ ...new Set(Object.entries(rels).flatMap(([id, rels]) => [id, ...rels])),
122
+ ];
123
+
124
+ // the current adjacency matrix impls only support numeric node IDs
125
+ // therefore, we first map node names to numeric IDs
126
+ const index = new Map(nodeIDs.map((id, i) => [id, i]));
127
+
128
+ // transform relationships into sequence of edges (aka `[from,to]` tuples)
129
+ const edges = Object.entries(rels).flatMap(([id, rels]) =>
130
+ rels.map((x) => <Edge>[index.get(id), index.get(x)])
131
+ );
132
+
133
+ // build adjacency matrix, treat as undirected graph
134
+ // edges can also be added/removed later
135
+ const graph = defAdjBitMatrix(nodeIDs.length, edges, true);
136
+
137
+ // graph queries
138
+ console.log("edges:", graph.numEdges(), "verts:", graph.numVertices());
139
+ // edges: 8 verts: 5
140
+
141
+ // check if vertex/node is present in graph
142
+ // (this is implementation specific and for the bitmatrix backed version here
143
+ // only true if the vertex has at least 1 edge...)
144
+ console.log(graph.hasVertex(index.get("d")!));
145
+ // true
146
+
147
+ // are `a` and `d` connected?
148
+ console.log(graph.hasEdge(index.get("a")!, index.get("d")!));
149
+ // false
150
+
151
+ // number of connected nodes for `a`
152
+ // (in directed graphs, there's also possibility to distinguish between in/out/inout)
153
+ console.log(graph.degree(index.get("a")!));
154
+ // 3
155
+
156
+ // neighbors of `a` (with reverse lookup of node names)
157
+ console.log(graph.neighbors(index.get("a")!).map((x) => nodeIDs[x]));
158
+ // [ 'b', 'c', 'e' ]
159
+
160
+ // serialize to GraphViz DOT format (see result visualization below)
161
+ console.log(graph.toDot(nodeIDs));
162
+ // graph g {
163
+ // "d"--"e";
164
+ // "c"--"d";
165
+ // "c"--"e";
166
+ // "b"--"d";
167
+ // "b"--"e";
168
+ // "a"--"b";
169
+ // "a"--"c";
170
+ // "a"--"e";
171
+ // }
172
+
173
+ // resize to new capacity & add add/remove vertices/edges
174
+ graph.resize(10);
175
+
176
+ graph.addEdge(4, 5);
177
+ graph.removeEdge(0, 1);
178
+ ```
179
+
105
180
  ## Authors
106
181
 
107
- - [Karsten Schmidt](https://thi.ng)
182
+ - [Karsten Schmidt](https://thi.ng) (Main author)
183
+ - [Igor Loskutov](https://github.com/Firfi)
108
184
 
109
185
  If this project contributes to an academic publication, please cite it as:
110
186
 
111
187
  ```bibtex
112
188
  @misc{thing-adjacency,
113
189
  title = "@thi.ng/adjacency",
114
- author = "Karsten Schmidt",
190
+ author = "Karsten Schmidt and others",
115
191
  note = "https://thi.ng/adjacency",
116
192
  year = 2018
117
193
  }
package/api.d.ts CHANGED
@@ -38,6 +38,12 @@ export interface IGraph<T = number> {
38
38
  * @param to -
39
39
  */
40
40
  hasEdge(from: T, to: T): boolean;
41
+ /**
42
+ * Returns true if a vertex exists for the given id.
43
+ *
44
+ * @param id -
45
+ */
46
+ hasVertex(id: T): boolean;
41
47
  /**
42
48
  * Returns number of edges for given vertex. By default only outgoing edges
43
49
  * are counted, but can be customized via given {@link DegreeType}. Note: In
package/binary.d.ts CHANGED
@@ -23,6 +23,7 @@ export declare class AdjacencyBitMatrix implements IGraph<number> {
23
23
  addEdge(from: number, to: number): boolean;
24
24
  removeEdge(from: number, to: number): boolean;
25
25
  hasEdge(from: number, to: number): boolean;
26
+ hasVertex(id: number): boolean;
26
27
  degree(id: number, type?: DegreeType): number;
27
28
  neighbors(id: number): number[];
28
29
  similarity(id: number, threshold?: number): number[][];
package/binary.js CHANGED
@@ -27,7 +27,7 @@ export class AdjacencyBitMatrix {
27
27
  return this.numE;
28
28
  }
29
29
  numVertices() {
30
- return this.mat.n;
30
+ return this.mat.m;
31
31
  }
32
32
  /**
33
33
  * Resizes matrix to new size given.
@@ -57,6 +57,9 @@ export class AdjacencyBitMatrix {
57
57
  hasEdge(from, to) {
58
58
  return this.mat.at(from, to) !== 0;
59
59
  }
60
+ hasVertex(id) {
61
+ return (this.mat.popCountRow(id) !== 0 || this.mat.popCountColumn(id) !== 0);
62
+ }
60
63
  degree(id, type = "out") {
61
64
  let degree = 0;
62
65
  if (this.undirected || type !== "in")
package/list.d.ts CHANGED
@@ -12,6 +12,7 @@ export declare class AdjacencyList implements IGraph<number> {
12
12
  edges(): Generator<Edge, void, unknown>;
13
13
  addVertex(id: number): void;
14
14
  removeVertex(id: number): boolean;
15
+ hasVertex(id: number): boolean;
15
16
  addEdge(from: number, to: number): boolean;
16
17
  removeEdge(from: number, to: number): boolean;
17
18
  hasEdge(from: number, to: number): boolean;
package/list.js CHANGED
@@ -55,6 +55,9 @@ export class AdjacencyList {
55
55
  this.numV--;
56
56
  return true;
57
57
  }
58
+ hasVertex(id) {
59
+ return !!this.adjacency[id];
60
+ }
58
61
  addEdge(from, to) {
59
62
  const vertex = this.ensureVertexData(from);
60
63
  this.ensureVertexData(to);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thi.ng/adjacency",
3
- "version": "2.4.0",
3
+ "version": "2.5.0",
4
4
  "description": "Sparse & bitwise adjacency matrices, lists and selected traversal algorithms for directed & undirected graphs",
5
5
  "type": "module",
6
6
  "module": "./index.js",
@@ -22,6 +22,9 @@
22
22
  }
23
23
  ],
24
24
  "author": "Karsten Schmidt (https://thi.ng)",
25
+ "contributors": [
26
+ "Igor Loskutov (https://github.com/Firfi)"
27
+ ],
25
28
  "license": "Apache-2.0",
26
29
  "scripts": {
27
30
  "build": "yarn clean && tsc --declaration",
@@ -122,5 +125,5 @@
122
125
  ],
123
126
  "year": 2018
124
127
  },
125
- "gitHead": "46e445c09f2909d1aeaa9fdc8d8b3aa61c114db2\n"
128
+ "gitHead": "7377b4b99095076ffc857b4b320902816ea6ae34\n"
126
129
  }
package/sparse.d.ts CHANGED
@@ -7,6 +7,7 @@ export declare class AdjacencyMatrix extends CSR implements IGraph<number> {
7
7
  addEdge(from: number, to: number): boolean;
8
8
  removeEdge(from: number, to: number): boolean;
9
9
  hasEdge(from: number, to: number): boolean;
10
+ hasVertex(id: number): boolean;
10
11
  numEdges(): number;
11
12
  numVertices(): number;
12
13
  degree(id: number, type?: DegreeType): number;
package/sparse.js CHANGED
@@ -38,6 +38,9 @@ export class AdjacencyMatrix extends CSR {
38
38
  hasEdge(from, to) {
39
39
  return this.at(from, to) !== 0;
40
40
  }
41
+ hasVertex(id) {
42
+ return this.degree(id, "inout") > 0;
43
+ }
41
44
  numEdges() {
42
45
  const n = this.data.length;
43
46
  return this.undirected ? n / 2 : n;