-
Notifications
You must be signed in to change notification settings - Fork 0
/
partition_utils.py
42 lines (32 loc) · 1.21 KB
/
partition_utils.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
"""Collections of partitioning functions."""
import time
import metis
import scipy.sparse as sp
def partition_graph(adj, idx_nodes, num_clusters):
"""partition a graph by METIS."""
start_time = time.time()
num_nodes = len(idx_nodes)
train_adj = adj[idx_nodes, :][:, idx_nodes]
train_adj_lil = train_adj.tolil()
train_ord_map = dict()
train_adj_lists = [[] for _ in range(num_nodes)]
for i in range(num_nodes):
rows = train_adj_lil[i].rows[0]
# self-edge needs to be removed for valid format of METIS
if i in rows:
rows.remove(i)
train_adj_lists[i] = rows
train_ord_map[idx_nodes[i]] = i
if num_clusters > 1:
_, groups = metis.part_graph(train_adj_lists, num_clusters, seed=1)
else:
groups = [0] * num_nodes
parts = [[] for _ in range(num_clusters)]
for nd_idx in range(num_nodes):
gp_idx = groups[nd_idx]
nd_orig_idx = idx_nodes[nd_idx]
parts[gp_idx].append(nd_orig_idx)
part_size = [len(part) for part in parts]
print('Partitioning done. %f seconds.'%(time.time() - start_time))
print('Max part size %d, min part size %d'%(max(part_size), min(part_size)))
return parts