-
Notifications
You must be signed in to change notification settings - Fork 2
/
NPAlgorithms.py
283 lines (225 loc) · 7.02 KB
/
NPAlgorithms.py
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
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
from modify import Graph
def intToBinary(number, size):
"""
Converts a decimal number to binary form
Parameters:
==========
number: Integer
The Number to be converted into binary form
size: Integer
The maximum length of the returning binary list
Returns:
=======
list:
Returns a list of length size consisting of 0's and 1's
representing binary form of number
"""
binary = [0 for i in range(size)]
i = 0
while number > 0:
binary[i] = number%2
number = number // 2
i += 1
return binary
def setBits(binary):
"""
Calculates the number of ones in the binary
Parameters:
==========
binary: List
The binary list of a decimal number
Returns:
=======
Integer:
Returns number of 1's in the binary representation
"""
counter = 0
for i in binary:
if i == 1:
counter += 1
return counter
def visitAllNeighborClique(visited, binary):
"""
Checks wether all considered nodes in binary are visited
or not. This function is used as a utility function for the
clique subroutine
Parameters:
==========
visited: list
The information of visited and unvisited node
binary: list
The nodes which are under consideration
Returns:
=======
bool:
If all considered nodes are visited then True
otherwise False
"""
n = len(binary)
for i in range(n):
if binary[i] == 1 and visited[i] == False:
return False
return True
class AlgorithmManager:
def __init__(self, graph):
self.graph = graph
def runAlgorithm(self, id):
"""
Runs the corresponding algorithm
Parameters:
==========
id: Integer
represents the algorithm id
"""
if id == 1:
return self.minimumDominantSet()
elif id == 2:
return self.maximumIndependentSet()
elif id == 3:
return self.maximumClique()
def minimumDominantSetUtil(self, binary):
"""
Checks wether the binary consideration of nodes is a
valid Dominant Set or not
Parameters:
==========
binary: list
The nodes which are under consideration
Returns:
=======
bool:
If all considered nodes form a Dominant Set then True
otherwise False
"""
n = len(self.graph.adjacencyList)
visited = [False for i in range(n)]
for i in range(n):
if binary[i] == 1:
visited[i] = True
for j in self.graph.adjacencyList[i]:
visited[j.toNode.key] = True
for i in range(n):
if visited[i] == False:
return False
return True
def minimumDominantSet(self):
"""
Calculates the dominant set of minimum size
Returns:
=======
list:
A list comprising of 0's and 1's of length equal
to number of nodes in graph.
0: Represents the node was not considered
1: Represents the node was considered
"""
# ID:1
n = len(self.graph.adjacencyList)
minimumSet = []
minimum = n
rangeToCover = 2**n
for i in range(rangeToCover):
binary = intToBinary(i,n)
involvedNodes = setBits(binary)
if self.minimumDominantSetUtil(binary) == True:
if minimum > involvedNodes:
minimum = involvedNodes
minimumSet = binary
return minimumSet
def maximumIndependentSetUtil(self,binary):
"""
Checks wether the binary consideration of nodes is a
valid independent set or not
Parameters:
==========
binary: list
The nodes which are under consideration
Returns:
=======
bool:
If all considered nodes form an Independent Set then True
otherwise False
"""
n = len(self.graph.adjacencyList)
visited = [False for i in range(n)]
for i in range(n):
if binary[i] == 1:
visited[i] = True
for i in range(n):
if visited[i] == True:
for j in self.graph.adjacencyList[i]:
if visited[j.toNode.key] == True:
return False
return True
def maximumIndependentSet(self):
"""
Calculates the independent set of maximimum size
Returns:
=======
list:
A list comprising of 0's and 1's of length equal
to number of nodes in graph.
0: Represents the node was not considered
1: Represents the node was considered
"""
#ID:2
n = len(self.graph.adjacencyList)
maximumSet = []
maximum = 0
rangeToCover = 2**n
for i in range(rangeToCover):
binary = intToBinary(i,n)
involvedNodes = setBits(binary)
if self.maximumIndependentSetUtil(binary) == True:
if maximum < involvedNodes:
maximum = involvedNodes
maximumSet = binary
return maximumSet
def maximumCliqueUtil(self, binary):
"""
Checks wether the binary consideration of nodes is a
valid clique or not
Parameters:
==========
binary: list
The nodes which are under consideration
Returns:
=======
bool:
If all considered nodes forms a clique then True
otherwise False
"""
n = len(self.graph.adjacencyList)
for i in range(n):
if binary[i] == 1:
visited = [False for j in range(n)]
visited[i] = True
for j in self.graph.adjacencyList[i]:
visited[j.toNode.key] = True
if not visitAllNeighborClique(visited, binary):
return False
return True
def maximumClique(self):
"""
Calculates the clique of maximimum size
Returns:
=======
list:
A list comprising of 0's and 1's of length equal
to number of nodes in graph.
0: Represents the node was not considered
1: Represents the node was considered
"""
#ID:3
n = len(self.graph.adjacencyList)
maximumSet = [0 for i in range(n)]
maximum = 0
rangeToCover = 2**n
for i in range(rangeToCover):
binary = intToBinary(i,n)
involvedNodes = setBits(binary)
if self.maximumCliqueUtil(binary) == True:
if maximum < involvedNodes:
maximum = involvedNodes
maximumSet = binary
return maximumSet