1 | import { GraphVertex } from "./GraphVertex";
|
2 | export class Graph {
|
3 | constructor(directed = true) {
|
4 | this.directed = directed;
|
5 | this.vertices = {};
|
6 | this.edges = {};
|
7 | }
|
8 | get Directed() {
|
9 | return this.directed;
|
10 | }
|
11 | addVertex(vertex) {
|
12 | this.vertices[vertex.Key] = vertex;
|
13 | this.edges[vertex.Key] = vertex.getEdges();
|
14 | return this;
|
15 | }
|
16 | addEdgeByKey(start, end, weight) {
|
17 | const startVertex = this.findVertex(start);
|
18 | const endVertex = this.findVertex(end);
|
19 | if (!startVertex || !endVertex) {
|
20 | throw new Error("vertex has not found");
|
21 | }
|
22 | return this.addEdge(startVertex, endVertex, weight);
|
23 | }
|
24 | addEdge(start, end, weight) {
|
25 | if (!start) {
|
26 | throw new Error("vertex is not empty");
|
27 | }
|
28 | if (this.directed) {
|
29 | start.addEdge(end, weight);
|
30 | }
|
31 | else {
|
32 | start.addUndirectedEdge(end, weight);
|
33 | }
|
34 | return this;
|
35 | }
|
36 | deleteEdge(start, end) {
|
37 | if (!start) {
|
38 | throw new Error("vertex is not empty");
|
39 | }
|
40 | return start.deleteEdgeByKey(end, this.directed);
|
41 | }
|
42 | deleteEdgeByKey(start, end) {
|
43 | const startVertex = this.findVertex(start);
|
44 | if (startVertex) {
|
45 | return this.deleteEdge(startVertex, end);
|
46 | }
|
47 | return false;
|
48 | }
|
49 | getVertexs() {
|
50 | const arr = [];
|
51 | for (const key in this.vertices) {
|
52 | arr.push(this.vertices[key]);
|
53 | }
|
54 | return arr;
|
55 | }
|
56 | getKeys() {
|
57 | return Object.keys(this.vertices);
|
58 | }
|
59 | getEdges() {
|
60 | let arr = [];
|
61 | for (const key in this.edges) {
|
62 | arr = [...arr, ...this.edges[key].toArray().map(item => item.Value)];
|
63 | }
|
64 | return arr;
|
65 | }
|
66 | findVertex(key) {
|
67 | return this.vertices[key];
|
68 | }
|
69 | findEdge(key) {
|
70 | return this.edges[key];
|
71 | }
|
72 | deleteVertex(key) {
|
73 | if (!(key in this.vertices)) {
|
74 | return false;
|
75 | }
|
76 | delete this.vertices[key];
|
77 | delete this.edges[key];
|
78 | for (const tempKey in this.vertices) {
|
79 | const element = this.vertices[tempKey];
|
80 | element.deleteEdgeByKey(key);
|
81 | }
|
82 | return true;
|
83 | }
|
84 | toAdjacencyMatrix() {
|
85 | const keys = this.getKeys();
|
86 | const matrix = new Array(keys.length)
|
87 | .fill(0).map(() => new Array(keys.length).fill(Infinity));
|
88 | const keyIndexs = {};
|
89 | let index = 0;
|
90 | for (const key in this.vertices) {
|
91 | keyIndexs[key] = index;
|
92 | matrix[index][index] = 0;
|
93 | index++;
|
94 | }
|
95 | for (const key in this.vertices) {
|
96 | const vertex = this.vertices[key];
|
97 | const edges = vertex.getEdges().toArray();
|
98 | for (const edgeNode of edges) {
|
99 | const edge = edgeNode.Value;
|
100 | matrix[keyIndexs[key]][keyIndexs[edge.EndVertex.Key]] = edge.Weight;
|
101 | }
|
102 | }
|
103 | return {
|
104 | matrix,
|
105 | keyIndexs,
|
106 | };
|
107 | }
|
108 | clone() {
|
109 | const vertices = this.getVertexs();
|
110 | const edges = this.getEdges();
|
111 | const graph = new Graph(this.directed);
|
112 | vertices.forEach(item => graph.addVertex(new GraphVertex(item.Node, item.Property)));
|
113 | edges.forEach(item => {
|
114 | const startVertex = graph.findVertex(item.StartVertex.Key);
|
115 | const endVertex = graph.findVertex(item.EndVertex.Key);
|
116 | graph.addEdge(startVertex, endVertex, item.Weight);
|
117 | });
|
118 | return graph;
|
119 | }
|
120 | }
|