-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdirected_graph.bal
215 lines (174 loc) · 5.72 KB
/
directed_graph.bal
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
public class DiGraph {
*Graph;
private GraphTb graphtb = table [];
public function getGraphTable() returns GraphTb {
return self.graphtb;
}
// TODO: add two graphs, add multiple vertices.
public function addNode(Vertex v) {
string node = v.toString();
if !self.graphtb.hasKey(node) {
self.graphtb.add({vertex: node});
}
}
public function removeNode(Vertex v) returns Node? {
string node = v.toString();
if self.graphtb.hasKey(node) {
Node n = self.graphtb.remove(node);
foreach string edge in n.edges.keys() {
Node edgeNode = self.graphtb.get(edge);
_ = edgeNode.edges.remove(node);
}
return n;
}
return;
}
public function numberOfNodes() returns int {
return self.graphtb.length();
}
public function 'order() returns int {
return self.graphtb.length();
}
public function hasNode(Vertex v) returns boolean {
return self.graphtb.hasKey(v.toString());
}
public function getNodes() returns string[] {
return self.graphtb.keys();
}
public function addEdge(Vertex u, Vertex v, int weight = 1) {
string vertexU = u.toString();
string vertexV = v.toString();
if !self.graphtb.hasKey(vertexU) {
self.addNode(u);
}
if !self.graphtb.hasKey(vertexV) {
self.addNode(v);
}
Node n1 = self.graphtb.get(vertexU);
n1.edges[vertexV] = weight;
}
public function removeEdge(Vertex u, Vertex v) returns boolean {
string vertexU = u.toString();
string vertexV = v.toString();
if !self.graphtb.hasKey(vertexU) {
return false;
}
if !self.graphtb.hasKey(vertexV) {
return false;
}
Node n1 = self.graphtb.get(vertexU);
return n1.edges.removeIfHasKey(vertexV) !is ();
}
public function hasEdge(Vertex u, Vertex v) returns boolean {
string vertexU = u.toString();
string vertexV = v.toString();
if self.graphtb.hasKey(vertexU) {
return self.graphtb.get(vertexU).edges.hasKey(vertexV);
}
return false;
}
public function getEdgeWeight(Vertex u, Vertex v) returns int|error {
string vertexU = u.toString();
string vertexV = v.toString();
if self.graphtb.hasKey(vertexU) {
int? weight = self.graphtb.get(vertexU).edges[vertexV];
if weight is int {
return weight;
}
return error(string `${vertexU} doesn't have edge ${vertexV}`);
}
return error(string `${vertexU} is not exist`);
}
public function clear() {
self.graphtb.removeAll();
}
public function clearEdges() {
foreach Node node in self.graphtb {
node.edges.removeAll();
}
}
public function isDirectedGraph() returns boolean {
return true;
}
public function copy() returns DiGraph {
DiGraph g = new ();
GraphTb graphtb = g.getGraphTable();
foreach Node node in self.graphtb {
Node cloneNode = node.clone();
graphtb.add(cloneNode);
}
return g;
}
public function size(boolean weight = false) returns int {
int edgeCountOrWeight = 0;
if weight {
foreach Node node in self.graphtb {
edgeCountOrWeight += node.edges.reduce(
function(int total, int value) returns int {
return total + value;
}, 0);
}
} else {
foreach Node node in self.graphtb {
edgeCountOrWeight += node.edges.length();
}
}
return edgeCountOrWeight;
}
public function numberOfEdges(Vertex? u = null, Vertex? v = null) returns int {
if u is () && v is () {
return self.size();
}
if u is () || v is () {
return 0;
}
return self.hasEdge(u, v) ? 1 : 0;
}
public function successor(Vertex u) returns string[]|error {
string vertexU = u.toString();
if !self.graphtb.hasKey(vertexU) {
return error(string `${vertexU} not found`);
}
return self.graphtb.get(vertexU).edges.keys();
}
public function neighbours(Vertex u) returns map<int>|error {
string vertexU = u.toString();
if !self.graphtb.hasKey(vertexU) {
return error(string `${vertexU} not found`);
}
return self.graphtb.get(vertexU).edges;
}
public function predecessor(Vertex u) returns string[]|error {
string vertexU = u.toString();
string[] predecessors = [];
if !self.graphtb.hasKey(vertexU) {
return error(string `${vertexU} not found`);
}
foreach Node node in self.graphtb {
if node.edges.hasKey(vertexU) {
predecessors.push(node.vertex);
}
}
return predecessors;
}
public function inDegree(Vertex u) returns int|error {
string vertexU = u.toString();
if !self.graphtb.hasKey(vertexU) {
return error(string `${vertexU} not found`);
}
int count = 0;
foreach Node node in self.graphtb {
if node.edges.hasKey(vertexU) {
count += 1;
}
}
return count;
}
public function outDegree(Vertex u) returns int|error {
string vertexU = u.toString();
if !self.graphtb.hasKey(vertexU) {
return error(string `${vertexU} not found`);
}
return self.graphtb.get(vertexU).edges.length();
}
}