1
+ import functools
2
+
1
3
import networkx as nx
2
4
from networkx .algorithms import tree
3
5
@@ -63,25 +65,31 @@ def uniform_spanning_tree(graph, choice=random.choice):
63
65
64
66
65
67
class PopulatedGraph :
68
+ __slots__ = [
69
+ "graph" ,
70
+ "subsets" ,
71
+ "population" ,
72
+ "tot_pop" ,
73
+ "ideal_pop" ,
74
+ "epsilon" ,
75
+ "degrees"
76
+ ]
66
77
def __init__ (self , graph , populations , ideal_pop , epsilon ):
67
78
self .graph = graph
68
79
self .subsets = {node : {node } for node in graph .node_indicies }
69
80
self .population = populations .copy ()
70
81
self .tot_pop = sum (self .population .values ())
71
82
self .ideal_pop = ideal_pop
72
83
self .epsilon = epsilon
73
- self ._degrees = {node : graph .degree (node ) for node in graph . node_indicies }
84
+ self .degrees = {node : graph .degree (node ) for node in graph }
74
85
75
86
def __iter__ (self ):
76
87
return iter (self .graph )
77
88
78
- def degree (self , node ):
79
- return self ._degrees [node ]
80
-
81
89
def contract_node (self , node , parent ):
82
90
self .population [parent ] += self .population [node ]
83
91
self .subsets [parent ] |= self .subsets [node ]
84
- self ._degrees [parent ] -= 1
92
+ self .degrees [parent ] -= 1
85
93
86
94
def has_ideal_population (self , node ):
87
95
return (
@@ -94,26 +102,26 @@ def has_ideal_population(self, node):
94
102
95
103
def find_balanced_edge_cuts_contraction (h , choice = random .choice ):
96
104
# this used to be greater than 2 but failed on small grids:(
97
- root = choice ([x for x in h if h .degree ( x ) > 1 ])
105
+ root = choice ([x for x in h if h .degrees [ x ] > 1 ])
98
106
# BFS predecessors for iteratively contracting leaves
99
107
pred = predecessors (h .graph , root )
100
108
101
109
cuts = []
102
- leaves = deque (x for x in h if h .degree ( x ) == 1 )
110
+ leaves = deque (x for x in h if h .degrees [ x ] == 1 )
103
111
while len (leaves ) > 0 :
104
112
leaf = leaves .popleft ()
105
113
if h .has_ideal_population (leaf ):
106
114
cuts .append (Cut (edge = (leaf , pred [leaf ]), subset = h .subsets [leaf ].copy ()))
107
115
# Contract the leaf:
108
116
parent = pred [leaf ]
109
117
h .contract_node (leaf , parent )
110
- if h .degree ( parent ) == 1 and parent != root :
118
+ if h .degrees [ parent ] == 1 and parent != root :
111
119
leaves .append (parent )
112
120
return cuts
113
121
114
122
115
123
def find_balanced_edge_cuts_memoization (h , choice = random .choice ):
116
- root = choice ([x for x in h if h .degree ( x ) > 1 ])
124
+ root = choice ([x for x in h if h .degrees [ x ] > 1 ])
117
125
pred = predecessors (h .graph , root )
118
126
succ = successors (h .graph , root )
119
127
total_pop = h .tot_pop
0 commit comments