I managed to find a solution with objective value 1861.54 by stapling a couple ideas together.
-
Form unordered color clusters of size 8 by finding a min-cost matching and joining matched subclusters, repeated three times. We use d(C1, C2) = ∑c1 in C1 ∑c2 in C2 d(c1, c2) as the distance function for subclusters C1 and C2.
-
Find the optimal 2 × 5 arrangement of clusters according to the above distance function. This involves brute forcing 10! permutations (really 10!/4 if one exploits symmetry, which I didn’t bother with).
-
Considering each cluster separately, find the optimal 4 × 2 arrangement by brute forcing 8! permutations. (More symmetry breaking possible, I didn’t bother.)
-
Brute force the 410 possible ways to flip the clusters. (Even more symmetry breaking possible, I didn’t bother.)
-
Improve this arrangement with local search. I interleaved two kinds of rounds: a 2-opt round where each pair of positions is considered for a swap, and a large-neighborhood round where we choose a random maximal independent set and reassign optimally using the Hungarian method (this problem is easy when none of the things we’re trying to move can be next to each other).
The output looks like this:
Python implementation at https://github.com/eisenstatdavid/felt-tip-pens