Skip to content

Commit 827ba06

Browse files
Add __slots__ and replace PopulatedGraph.degree with direct dictionary lookup
1 parent 979e55f commit 827ba06

File tree

1 file changed

+17
-9
lines changed

1 file changed

+17
-9
lines changed

gerrychain/tree.py

+17-9
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import functools
2+
13
import networkx as nx
24
from networkx.algorithms import tree
35

@@ -63,25 +65,31 @@ def uniform_spanning_tree(graph, choice=random.choice):
6365

6466

6567
class PopulatedGraph:
68+
__slots__ = [
69+
"graph",
70+
"subsets",
71+
"population",
72+
"tot_pop",
73+
"ideal_pop",
74+
"epsilon",
75+
"degrees"
76+
]
6677
def __init__(self, graph, populations, ideal_pop, epsilon):
6778
self.graph = graph
6879
self.subsets = {node: {node} for node in graph.node_indicies}
6980
self.population = populations.copy()
7081
self.tot_pop = sum(self.population.values())
7182
self.ideal_pop = ideal_pop
7283
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}
7485

7586
def __iter__(self):
7687
return iter(self.graph)
7788

78-
def degree(self, node):
79-
return self._degrees[node]
80-
8189
def contract_node(self, node, parent):
8290
self.population[parent] += self.population[node]
8391
self.subsets[parent] |= self.subsets[node]
84-
self._degrees[parent] -= 1
92+
self.degrees[parent] -= 1
8593

8694
def has_ideal_population(self, node):
8795
return (
@@ -94,26 +102,26 @@ def has_ideal_population(self, node):
94102

95103
def find_balanced_edge_cuts_contraction(h, choice=random.choice):
96104
# 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])
98106
# BFS predecessors for iteratively contracting leaves
99107
pred = predecessors(h.graph, root)
100108

101109
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)
103111
while len(leaves) > 0:
104112
leaf = leaves.popleft()
105113
if h.has_ideal_population(leaf):
106114
cuts.append(Cut(edge=(leaf, pred[leaf]), subset=h.subsets[leaf].copy()))
107115
# Contract the leaf:
108116
parent = pred[leaf]
109117
h.contract_node(leaf, parent)
110-
if h.degree(parent) == 1 and parent != root:
118+
if h.degrees[parent] == 1 and parent != root:
111119
leaves.append(parent)
112120
return cuts
113121

114122

115123
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])
117125
pred = predecessors(h.graph, root)
118126
succ = successors(h.graph, root)
119127
total_pop = h.tot_pop

0 commit comments

Comments
 (0)