1
1
namespace $ {
2
2
3
+ /**
4
+ * Generic Graph model.
5
+ * - Supports any type of Nodes and Edges.
6
+ * - All links are ordered, but this ay be ignored.
7
+ * - Multigraph supported using arrays of Edges.
8
+ * - Hypergraph supported by reusing same Edge on set of links.
9
+ * - Ubergraph supported using Edges as Nodes to.
10
+ **/
3
11
export class $mol_graph < Node , Edge > {
4
12
13
+ /** All registered Nodes */
5
14
nodes = new Set < Node > ( )
6
15
16
+ /** Edges for Nodes pairs (from-to-edge) */
7
17
edges_out = new Map < Node , Map < Node , Edge > > ( )
18
+ /** Edges for Nodes pairs (to-from-edge) */
8
19
edges_in = new Map < Node , Map < Node , Edge > > ( )
9
20
21
+ // LINKING NODES
22
+
23
+ /** Full connect two Nodes */
24
+ link ( from : Node , to : Node , edge : Edge ) {
25
+ this . link_out ( from , to , edge )
26
+ this . link_in ( to , from , edge )
27
+ }
28
+
29
+ /** Full disconnect two Nodes */
30
+ unlink ( from : Node , to : Node ) {
31
+ this . edges_in . get ( to ) ?. delete ( from )
32
+ this . edges_out . get ( from ) ?. delete ( to )
33
+ }
34
+
35
+ /** Forward connect two Nodes */
10
36
link_out ( from : Node , to : Node , edge : Edge ) {
11
37
12
38
let pair = this . edges_out . get ( from )
@@ -22,6 +48,7 @@ namespace $ {
22
48
23
49
}
24
50
51
+ /** Backward connect two Nodes */
25
52
link_in ( to : Node , from : Node , edge : Edge ) {
26
53
27
54
let pair = this . edges_in . get ( to )
@@ -37,24 +64,26 @@ namespace $ {
37
64
38
65
}
39
66
67
+ // GETTING EDGES
68
+
69
+ /** Return any Edge for two Nodes or null */
70
+ edge ( from : Node , to : Node ) {
71
+ return this . edge_out ( from , to ) ?? this . edge_in ( to , from )
72
+ }
73
+
74
+ /** Return output Edge for two Nodes or null */
40
75
edge_out ( from : Node , to : Node ) {
41
76
return this . edges_out . get ( from ) ?. get ( to ) ?? null
42
77
}
43
78
79
+ /** Return input Edge for two Nodes or null */
44
80
edge_in ( to : Node , from : Node ) {
45
81
return this . edges_in . get ( to ) ?. get ( from ) ?? null
46
82
}
47
83
48
- link ( from : Node , to : Node , edge : Edge ) {
49
- this . link_out ( from , to , edge )
50
- this . link_in ( to , from , edge )
51
- }
52
-
53
- unlink ( from : Node , to : Node ) {
54
- this . edges_in . get ( to ) ?. delete ( from )
55
- this . edges_out . get ( from ) ?. delete ( to )
56
- }
84
+ // MUTATIONS
57
85
86
+ /** Cut cycles at lowest priority of Edges */
58
87
acyclic ( get_weight : ( edge : Edge ) => number ) {
59
88
60
89
const checked = [ ] as Node [ ]
@@ -128,6 +157,9 @@ namespace $ {
128
157
129
158
}
130
159
160
+ // NODES SELECTION
161
+
162
+ /** Topoligical ordered set of all Nodes for acyclic graph */
131
163
get sorted ( ) {
132
164
133
165
const sorted = new Set < Node > ( )
@@ -152,6 +184,7 @@ namespace $ {
152
184
return sorted
153
185
}
154
186
187
+ /** All Nodes which don't have input Edges */
155
188
get roots ( ) {
156
189
157
190
const roots = [ ] as Node [ ]
@@ -165,7 +198,15 @@ namespace $ {
165
198
return roots
166
199
}
167
200
168
- depth ( select : ( left : number , right : number ) => number ) {
201
+ // DEPTH STATS
202
+
203
+ /**
204
+ * Nodes depth statistics for acyclic graph
205
+ * @example
206
+ * graph.depth_stat( Math.min )
207
+ * graph.depth_stat( Math.max )
208
+ **/
209
+ nodes_depth ( select : ( left : number , right : number ) => number ) {
169
210
170
211
const stat = new Map < Node , number > ( )
171
212
const visit = ( node : Node , depth = 0 ) => {
@@ -181,18 +222,16 @@ namespace $ {
181
222
return stat
182
223
}
183
224
184
- get depth_min ( ) {
185
- return this . depth ( Math . min )
186
- }
187
-
188
- get depth_max ( ) {
189
- return this . depth ( Math . max )
190
- }
191
-
192
- group_depth ( select : ( left : number , right : number ) => number ) {
225
+ /**
226
+ * Depth's Nodes statistics for acyclic graph
227
+ * @example
228
+ * graph.depth_nodes( Math.min )
229
+ * graph.depth_nodes( Math.max )
230
+ **/
231
+ depth_nodes ( select : ( left : number , right : number ) => number ) {
193
232
194
233
const groups = [ ] as Node [ ] [ ]
195
- for ( const [ node , depth ] of this . depth ( select ) . entries ( ) ) {
234
+ for ( const [ node , depth ] of this . nodes_depth ( select ) . entries ( ) ) {
196
235
197
236
if ( groups [ depth ] ) groups [ depth ] . push ( node )
198
237
else groups [ depth ] = [ node ]
@@ -202,14 +241,6 @@ namespace $ {
202
241
return groups
203
242
}
204
243
205
- get group_depth_min ( ) {
206
- return this . group_depth ( Math . min )
207
- }
208
-
209
- get proup_depth_max ( ) {
210
- return this . group_depth ( Math . max )
211
- }
212
-
213
244
}
214
245
215
246
}
0 commit comments