@thi.ng/adjacency 2.1.12 → 2.2.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**: 2022-06-09T16:14:01Z
3
+ - **Last updated**: 2022-07-19T15:36:12Z
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,19 @@ 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.2.0](https://github.com/thi-ng/umbrella/tree/@thi.ng/adjacency@2.2.0) (2022-07-19)
13
+
14
+ #### 🚀 Features
15
+
16
+ - update AdjacencyList ([5d85d87](https://github.com/thi-ng/umbrella/commit/5d85d87))
17
+ - add vertices() iterator
18
+ - rename old `.vertices` field => `.adjacency`
19
+ - add adjListFromAdjacency() factory fn
20
+
21
+ #### ♻️ Refactoring
22
+
23
+ - update DCons call sites ([2dfec21](https://github.com/thi-ng/umbrella/commit/2dfec21))
24
+
12
25
  ## [2.1.0](https://github.com/thi-ng/umbrella/tree/@thi.ng/adjacency@2.1.0) (2021-11-17)
13
26
 
14
27
  #### 🚀 Features
package/bfs.js CHANGED
@@ -10,7 +10,8 @@ export class BFS {
10
10
  this.search(src, cost);
11
11
  }
12
12
  search(id, cost) {
13
- const queue = new DCons().cons(id);
13
+ const queue = new DCons();
14
+ queue.prepend(id);
14
15
  const { dist, edges, graph, marked } = this;
15
16
  dist.fill(0xffffffff);
16
17
  dist[id] = 0;
@@ -37,9 +38,9 @@ export class BFS {
37
38
  const { dist, edges } = this;
38
39
  const path = new DCons();
39
40
  for (; dist[id] > 0; id = edges[id]) {
40
- path.cons(id);
41
+ path.prepend(id);
41
42
  }
42
- path.cons(id);
43
+ path.prepend(id);
43
44
  return path;
44
45
  }
45
46
  }
package/binary.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { BitMatrix } from "@thi.ng/bitfield/bitmatrix";
2
- import { into, invert, toDot } from "./utils.js";
2
+ import { __into, __invert, __toDot } from "./utils.js";
3
3
  /**
4
4
  * Adjacency matrix representation for both directed and undirected graphs and
5
5
  * using a compact bit matrix to store edges. Each edge requires only 1 bit
@@ -11,7 +11,7 @@ export class AdjacencyBitMatrix {
11
11
  this.mat = new BitMatrix(n);
12
12
  this.undirected = undirected;
13
13
  this.numE = 0;
14
- edges && into(this, edges);
14
+ edges && __into(this, edges);
15
15
  }
16
16
  *edges() {
17
17
  const directed = !this.undirected;
@@ -80,13 +80,13 @@ export class AdjacencyBitMatrix {
80
80
  return res;
81
81
  }
82
82
  invert() {
83
- return invert(new AdjacencyBitMatrix(this.mat.n, undefined, this.undirected), this.edges());
83
+ return __invert(new AdjacencyBitMatrix(this.mat.n, undefined, this.undirected), this.edges());
84
84
  }
85
85
  toString() {
86
86
  return this.mat.toString();
87
87
  }
88
88
  toDot(ids) {
89
- return toDot(this.edges(), this.undirected, ids);
89
+ return __toDot(this.edges(), this.undirected, ids);
90
90
  }
91
91
  }
92
92
  /**
package/dfs.js CHANGED
@@ -28,9 +28,9 @@ export class DFS {
28
28
  const { edges, src } = this;
29
29
  const path = new DCons();
30
30
  for (; id !== src; id = edges[id]) {
31
- path.cons(id);
31
+ path.prepend(id);
32
32
  }
33
- path.cons(id);
33
+ path.prepend(id);
34
34
  return path;
35
35
  }
36
36
  }
package/list.d.ts CHANGED
@@ -1,13 +1,14 @@
1
- import { DCons } from "@thi.ng/dcons/dcons";
1
+ import type { Nullable } from "@thi.ng/api";
2
2
  import type { DegreeType, Edge, IGraph } from "./api.js";
3
3
  export declare class AdjacencyList implements IGraph<number> {
4
- vertices: DCons<number>[];
4
+ adjacency: number[][];
5
5
  indegree: number[];
6
6
  protected numE: number;
7
7
  protected numV: number;
8
8
  constructor(edges?: Iterable<Edge>);
9
9
  numEdges(): number;
10
10
  numVertices(): number;
11
+ vertices(): Generator<number, void, unknown>;
11
12
  edges(): Generator<Edge<number>, void, unknown>;
12
13
  addVertex(id: number): void;
13
14
  removeVertex(id: number): boolean;
@@ -17,9 +18,10 @@ export declare class AdjacencyList implements IGraph<number> {
17
18
  degree(id: number, type?: DegreeType): number;
18
19
  neighbors(id: number): Iterable<number>;
19
20
  invert(): AdjacencyList;
20
- toString(): string;
21
21
  toDot(ids?: string[]): string;
22
- protected ensureVertexData(id: number): DCons<number>;
22
+ toString(): string;
23
+ protected ensureVertexData(id: number): number[];
23
24
  }
24
25
  export declare const defAdjList: (edges?: Iterable<Edge>) => AdjacencyList;
26
+ export declare const adjListFromAdjacency: (src: Nullable<number[]>[]) => AdjacencyList;
25
27
  //# sourceMappingURL=list.d.ts.map
package/list.js CHANGED
@@ -1,12 +1,11 @@
1
- import { DCons } from "@thi.ng/dcons/dcons";
2
- import { into, invert, toDot } from "./utils.js";
1
+ import { __into, __invert, __toDot } from "./utils.js";
3
2
  export class AdjacencyList {
4
3
  constructor(edges) {
5
- this.vertices = [];
4
+ this.adjacency = [];
6
5
  this.indegree = [];
7
6
  this.numE = 0;
8
7
  this.numV = 0;
9
- edges && into(this, edges);
8
+ edges && __into(this, edges);
10
9
  }
11
10
  numEdges() {
12
11
  return this.numE;
@@ -14,10 +13,17 @@ export class AdjacencyList {
14
13
  numVertices() {
15
14
  return this.numV;
16
15
  }
16
+ *vertices() {
17
+ const { adjacency } = this;
18
+ for (let i = 0, n = adjacency.length; i < n; i++) {
19
+ if (adjacency[i])
20
+ yield i;
21
+ }
22
+ }
17
23
  *edges() {
18
- const vertices = this.vertices;
19
- for (let i = 0, n = vertices.length; i < n; i++) {
20
- const vertex = vertices[i];
24
+ const { adjacency } = this;
25
+ for (let i = 0, n = adjacency.length; i < n; i++) {
26
+ const vertex = adjacency[i];
21
27
  if (!vertex)
22
28
  continue;
23
29
  for (let j of vertex)
@@ -28,24 +34,22 @@ export class AdjacencyList {
28
34
  this.ensureVertexData(id);
29
35
  }
30
36
  removeVertex(id) {
31
- const { vertices, indegree } = this;
32
- const vertex = vertices[id];
37
+ const { adjacency, indegree } = this;
38
+ const vertex = adjacency[id];
33
39
  if (!vertex)
34
40
  return false;
35
41
  // remove outgoing
36
42
  while (vertex.length) {
37
- const to = vertex.first();
38
- vertex.drop();
39
- indegree[to]--;
43
+ indegree[vertex.pop()]--;
40
44
  this.numE--;
41
45
  }
42
- delete vertices[id];
46
+ delete adjacency[id];
43
47
  // remove incoming
44
- for (let i = 0, n = vertices.length; i < n && indegree[id] > 0; i++) {
45
- const vertex = this.vertices[i];
48
+ for (let i = 0, n = adjacency.length; i < n && indegree[id] > 0; i++) {
49
+ const vertex = adjacency[i];
46
50
  if (!vertex)
47
51
  continue;
48
- while (!!vertex.find(id))
52
+ while (vertex.includes(id))
49
53
  this.removeEdge(i, id);
50
54
  }
51
55
  this.numV--;
@@ -60,11 +64,11 @@ export class AdjacencyList {
60
64
  return true;
61
65
  }
62
66
  removeEdge(from, to) {
63
- const vertex = this.vertices[from];
67
+ const vertex = this.adjacency[from];
64
68
  if (vertex) {
65
- const dest = vertex.find(to);
66
- if (dest) {
67
- vertex.remove(dest);
69
+ const dest = vertex.indexOf(to);
70
+ if (dest >= 0) {
71
+ vertex.splice(dest, 1);
68
72
  this.numE--;
69
73
  this.indegree[to]--;
70
74
  return true;
@@ -73,12 +77,12 @@ export class AdjacencyList {
73
77
  return false;
74
78
  }
75
79
  hasEdge(from, to) {
76
- const vertex = this.vertices[from];
77
- return vertex ? !!vertex.find(to) : false;
80
+ const vertex = this.adjacency[from];
81
+ return vertex ? vertex.includes(to) : false;
78
82
  }
79
83
  degree(id, type = "out") {
80
84
  let degree = 0;
81
- const vertex = this.vertices[id];
85
+ const vertex = this.adjacency[id];
82
86
  if (vertex) {
83
87
  if (type !== "in")
84
88
  degree += vertex.length;
@@ -88,33 +92,44 @@ export class AdjacencyList {
88
92
  return degree;
89
93
  }
90
94
  neighbors(id) {
91
- return [...(this.vertices[id] || [])];
95
+ return [...(this.adjacency[id] || [])];
92
96
  }
93
97
  invert() {
94
- return invert(new AdjacencyList(), this.edges());
98
+ return __invert(new AdjacencyList(), this.edges());
99
+ }
100
+ toDot(ids) {
101
+ return __toDot(this.edges(), false, ids);
95
102
  }
96
103
  toString() {
97
- const vertices = this.vertices;
104
+ const { adjacency } = this;
98
105
  const res = [];
99
- for (let i = 0, n = vertices.length; i < n; i++) {
100
- if (vertices[i]) {
101
- res.push(`${i}: [${[...vertices[i]]
106
+ for (let i = 0, n = adjacency.length; i < n; i++) {
107
+ if (adjacency[i]) {
108
+ res.push(`${i}: [${[...adjacency[i]]
102
109
  .sort((a, b) => a - b)
103
110
  .join(", ")}]`);
104
111
  }
105
112
  }
106
113
  return res.join("\n");
107
114
  }
108
- toDot(ids) {
109
- return toDot(this.edges(), false, ids);
110
- }
111
115
  ensureVertexData(id) {
112
- const vertex = this.vertices[id];
116
+ const vertex = this.adjacency[id];
113
117
  if (vertex)
114
118
  return vertex;
115
119
  this.numV++;
116
120
  this.indegree[id] = 0;
117
- return (this.vertices[id] = new DCons());
121
+ return (this.adjacency[id] = []);
118
122
  }
119
123
  }
120
124
  export const defAdjList = (edges) => new AdjacencyList(edges);
125
+ export const adjListFromAdjacency = (src) => {
126
+ const res = new AdjacencyList();
127
+ for (let i = 0, n = src.length; i < n; i++) {
128
+ const v = src[i];
129
+ if (!v)
130
+ continue;
131
+ for (let w of v)
132
+ res.addEdge(i, w);
133
+ }
134
+ return res;
135
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thi.ng/adjacency",
3
- "version": "2.1.12",
3
+ "version": "2.2.0",
4
4
  "description": "Sparse & bitwise adjacency matrices and related functions for directed & undirected graphs",
5
5
  "type": "module",
6
6
  "module": "./index.js",
@@ -34,21 +34,21 @@
34
34
  "test": "testament test"
35
35
  },
36
36
  "dependencies": {
37
- "@thi.ng/api": "^8.3.7",
38
- "@thi.ng/arrays": "^2.3.0",
39
- "@thi.ng/bitfield": "^2.1.8",
40
- "@thi.ng/dcons": "^3.2.6",
41
- "@thi.ng/errors": "^2.1.7",
42
- "@thi.ng/sparse": "^0.3.11"
37
+ "@thi.ng/api": "^8.3.8",
38
+ "@thi.ng/arrays": "^2.3.1",
39
+ "@thi.ng/bitfield": "^2.2.0",
40
+ "@thi.ng/dcons": "^3.2.7",
41
+ "@thi.ng/errors": "^2.1.8",
42
+ "@thi.ng/sparse": "^0.3.12"
43
43
  },
44
44
  "devDependencies": {
45
45
  "@microsoft/api-extractor": "^7.25.0",
46
- "@thi.ng/testament": "^0.2.8",
47
- "@thi.ng/vectors": "^7.5.7",
46
+ "@thi.ng/testament": "^0.2.9",
47
+ "@thi.ng/vectors": "^7.5.8",
48
48
  "rimraf": "^3.0.2",
49
49
  "tools": "^0.0.1",
50
50
  "typedoc": "^0.22.17",
51
- "typescript": "^4.7.3"
51
+ "typescript": "^4.7.4"
52
52
  },
53
53
  "keywords": [
54
54
  "adjacency",
@@ -119,5 +119,5 @@
119
119
  ],
120
120
  "year": 2018
121
121
  },
122
- "gitHead": "e64b1ab39ae9bcc494ef006f6329e5182fa2a326\n"
122
+ "gitHead": "108a6357b77d457912d30681d7cc5603ae995209\n"
123
123
  }
package/sparse.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { ensureIndex2 } from "@thi.ng/errors/out-of-bounds";
2
2
  import { CSR } from "@thi.ng/sparse/csr";
3
- import { into, invert, toDot } from "./utils.js";
3
+ import { __into, __invert, __toDot } from "./utils.js";
4
4
  export class AdjacencyMatrix extends CSR {
5
5
  constructor(n, data, rows, cols, undirected = false) {
6
6
  super(n, n, data, rows, cols);
@@ -58,7 +58,7 @@ export class AdjacencyMatrix extends CSR {
58
58
  return this.nzRowCols(id);
59
59
  }
60
60
  invert() {
61
- return invert(defAdjMatrix(this.m, undefined, this.undirected), this.edges());
61
+ return __invert(defAdjMatrix(this.m, undefined, this.undirected), this.edges());
62
62
  }
63
63
  /**
64
64
  * Returns a diagonal sparse matrix {@link @thi.ng/sparse#CSR} containing
@@ -140,7 +140,7 @@ export class AdjacencyMatrix extends CSR {
140
140
  .add(deg.sub(I).mulN(n * n));
141
141
  }
142
142
  toDot(ids) {
143
- return toDot(this.edges(), this.undirected, ids);
143
+ return __toDot(this.edges(), this.undirected, ids);
144
144
  }
145
145
  }
146
146
  /**
@@ -156,6 +156,6 @@ export class AdjacencyMatrix extends CSR {
156
156
  export const defAdjMatrix = (n, edges, undirected = false) => {
157
157
  const raw = CSR.empty(n);
158
158
  const mat = new AdjacencyMatrix(n, raw.data, raw.rows, raw.cols, undirected);
159
- edges && into(mat, edges);
159
+ edges && __into(mat, edges);
160
160
  return mat;
161
161
  };
package/utils.d.ts CHANGED
@@ -1,9 +1,9 @@
1
1
  import type { Pair } from "@thi.ng/api";
2
2
  import type { Edge, IGraph } from "./api.js";
3
3
  /** @internal */
4
- export declare const toDot: (edges: Iterable<Pair<number, number>>, undirected: boolean, ids?: string[]) => string;
4
+ export declare const __toDot: (edges: Iterable<Pair<number, number>>, undirected: boolean, ids?: string[]) => string;
5
5
  /** @internal */
6
- export declare const into: (graph: IGraph, edges: Iterable<Edge>) => void;
6
+ export declare const __into: (graph: IGraph, edges: Iterable<Edge>) => void;
7
7
  /** @internal */
8
- export declare const invert: <T extends IGraph<number>>(graph: T, edges: Iterable<Edge>) => T;
8
+ export declare const __invert: <T extends IGraph<number>>(graph: T, edges: Iterable<Edge>) => T;
9
9
  //# sourceMappingURL=utils.d.ts.map
package/utils.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /** @internal */
2
- export const toDot = (edges, undirected, ids) => {
2
+ export const __toDot = (edges, undirected, ids) => {
3
3
  const [type, sep] = undirected ? ["graph", "--"] : ["digraph", "->"];
4
4
  const res = [`${type} g {`];
5
5
  for (let e of edges) {
@@ -11,13 +11,13 @@ export const toDot = (edges, undirected, ids) => {
11
11
  return res.join("\n");
12
12
  };
13
13
  /** @internal */
14
- export const into = (graph, edges) => {
14
+ export const __into = (graph, edges) => {
15
15
  for (let e of edges) {
16
16
  graph.addEdge(e[0], e[1]);
17
17
  }
18
18
  };
19
19
  /** @internal */
20
- export const invert = (graph, edges) => {
20
+ export const __invert = (graph, edges) => {
21
21
  for (let e of edges) {
22
22
  graph.addEdge(e[1], e[0]);
23
23
  }