[EM] Algorithmic redistricting: practical or not?

Kristofer Munsterhjelm km-elmet at munsterhjelm.no
Tue Feb 4 13:39:56 PST 2025


So I got myself entangled in redistricting back in November, after 
writing a post here about how solving a related problem (that I thought 
was the same as districting) could be done through linear programming, 
if the centers were given.

Some months and lots of code later, I thought I'd post about what I 
found out.

The summary, first:
	- Bad news: the linear program I gave doesn't ensure contiguity or 
convexity, and my attempts to forcing it were too expensive.
	- Good news: the linear program isn't useless and can be used as a 
component in a branch-and-bound-like approach. Once it has found a good 
choice of centers, a local search can be used to find a convex solution.
	- All of this is much harder than just using proportional 
representation, so it's mostly an intellectual exercise.


To recap, the linear program is:
	For centers i =  1...n, with cneterx_i, centery_i being the (x,y) 
coordinates of center i

	minimize the sum over centers i, and points x, y inside the state:
	(1)    assign[i, x, y] * (pop(x, y) + eps) * dist^2(centerx_i, 
centery_i, x, y)

	subject to
	(2)    for all i, x, y: 0 <= assign[i, x, y] <= 1
	(3)    for all i: (sum over x, y: assign[i, x, y] * pop(x, y)) - tpop/n = 0
	(4)    for all x, y: (sum over i: assign[i, x, y]) = 1

(1) defines the problem: minimize expected squared distance from a 
random inhabitant to their assigned center. Assign[i, x, y] is a free 
variable that is one if the point (x,y) is assigned to center i, zero 
otherwise, and pop(x, y) is the number of people at that reside closer 
to (x,y) than any other point. The epsilon value eps ensures that a 
point with no population is assigned to its closest center.[1]
(2) defines the range of the assign values.
(3) implements the population constraint that every district has equal 
population.
(4) requires that every point be assigned to some district.

The linear program does solve the problem as specified. However, the 
resulting districts aren't contiguous.

You'd think they were because suppose district A picks a point that's 
inside district B, then shouldn't we be able to improve the solution for 
both by swapping this assignment with points closer to A? The problem is 
the population constraint. Sometimes it's easier to skip points because 
otherwise, a bunch of other points would have to change to keep equal 
populations, and the sum of these changes could be worse.

So instead you need additional constraints, and these are expensive.[2] 
That's the bad news.

The good news is that it's actually not as bad as you'd think, because 
the linear program I gave provides a good lower bound for a contiguous 
solution. Furthermore, with integer programming, it's possible to add a 
large number of candidate points and have the solver choose only some of 
these as centers. For instance, we may pick 150 candidate centers with 
something like kmeans++; and then use an integer program to say it 
should choose 8 of them, like this:

minimize the sum over centers i, and points x, y inside the state:
	assign[i, x, y] * (pop(x, y) + eps) * dist^2(centerx_i, centery_i, x, y)

	subject to
		(2b) for all i, x, y: 0 <= assign[i, x, y] <= chosen[i]
		for all i: (sum over x, y: assign[i, x, y] * pop(x, y)) - tpop/k * 
chosen[i] = 0
		for all x, y: (sum over i: assign[i, x, y]) = 1
		(5) sum over i: chosen[i] = k

	free variables: assign[i, x, y] continuous, chosen[i] binary

(2b) says: if chosen[i] is zero, then nobody can be assigned to center 
i. Otherwise, points may be assigned to center i.
(5) forces exactly k districts to be chosen. The population constraint 
(3) has also been updated accordingly: if chosen[i] is zero, then 
population must be zero.

(Thanks to Joshua Boehme for this idea.)

When run, the program will find the best k centers and give, as its 
objective value, a lower bound on the sum of squared distances that 
we're actually interested in. If this is worse than the current record, 
we just discard the solution as it can't be better anyway; otherwise, we 
check it more closely with contiguity constraints, which will return the 
true objective value.

This seems to work reasonably well in theory, but the datrasets are much 
too large to run contiguity-constrained programs on. Instead I use a 
method from Janáček and Gábrišová[2], which uses the property that, 
suppose we start with some given centers,
	(centerx_i, centery_i) for i = 1..k
Then there exist weights w_i so that the "ordinary" k-means clustering 
(Voronoi clustering) objective
	minimize sum over i, x, y: assign[i, x, y] * (pop(x, y) + eps) * 
(dist^2(centerx_i, centery_i, x, y) + w_i)

will ensure that the districts have equal populations. (This makes 
intuitive sense: if w_i is very large, district i is penalized and 
shrinks relative to the other districts.) And this "uncapacitated" or 
unconstrained problem can be easily solved by checking each point's 
value for each district and picking the best.

So I ended up with a two-step procedure: use integer programming to find 
reasonably good centers from a randomly selected large enough candidate 
pool, and then use a local search to update the weights w_i until the 
districts had nearly equal populations, thus enforcing contiguity and 
convexity.[3][4]

In practice, there were a bunch of additional problems due to census 
district shapes, non-Euclidean geometry, and how to handle large amounts 
of data quickly. But I won't go into those here; perhaps later, as this 
post is long enough.

-km

[1] I made a mistake back when I stated this back at the end of October: 
the objective value should be weighted by population, not just sum of 
squared distances. Otherwise every district wants to be exactly the same 
size as the others, which leads them all to carve inwards to cut shares 
of cities. See the unweighted objective picture here: 
https://github.com/kristomu/redistricter/tree/master/undesired_outcomes

[2] See JANÁČEK, Jaroslav; GÁBRIŠOVÁ, Lýdia. A two‐phase method for the 
capacitated facility problem of compact customer sub‐sets. Transport, 
2009, 24.4: 274-282.

[3] As far as I understand, it's possible to use a postprocessing phase 
to force exact equality. The Janáček and Gábrišová paper gives more detail.
In my tests for Colorado, the local search converged to around 0.02% 
difference in population between the most populated district and the 
least, so I didn't implement it.

[4] There may be better ways to find the weights than local search, see 
e.g. SPANN, Andrew; KANE, Daniel; GULOTTA, Dan. Electoral redistricting 
with moment of inertia and diminishing halves models. The UMAP Journal, 
2007, https://rangevoting.org/SpannGulottaKaneMCM2007.pdf, particularly 
pages 9 and 10.


More information about the Election-Methods mailing list