[Snippets/interpolatable] Use Hungarian algorithm from munkres or scipy when available

Fixes https://github.com/fonttools/fonttools/issues/815
This commit is contained in:
Behdad Esfahbod 2017-01-19 07:18:42 -08:00
parent a141ddc400
commit 179b8b5794

View File

@ -77,8 +77,28 @@ def _matching_cost(G, matching):
def min_cost_perfect_bipartite_matching(G):
n = len(G)
if n <= 8:
# brute-force
try:
from scipy.optimize import linear_sum_assignment
rows, cols = linear_sum_assignment(G)
# This branch untested
assert rows == list(range(n))
return cols, _matching_cost(G, cols)
except ImportError:
pass
try:
from munkres import Munkres
cols = [None] * n
for row,col in Munkres().compute(G):
cols[row] = col
return cols, _matching_cost(G, cols)
except ImportError:
pass
if n > 6:
raise Exception("Install Python module 'munkres' or 'scipy >= 0.17.0'")
# Otherwise just brute-force
permutations = itertools.permutations(range(n))
best = list(next(permutations))
best_cost = _matching_cost(G, best)
@ -87,26 +107,6 @@ def min_cost_perfect_bipartite_matching(G):
if cost < best_cost:
best, best_cost = list(p), cost
return best, best_cost
else:
# Set up current matching and inverse
matching = list(range(n)) # identity matching
matching_cost = _matching_cost(G, matching)
reverse = list(matching)
return matching, matching_cost
# TODO implement real matching here
# Set up cover
cover0 = [max(c for c in row) for row in G]
cover1 = [0] * n
cover_weight = sum(cover0)
while cover_weight < matching_cost:
break
NotImplemented
return matching, matching_cost
def test(glyphsets, glyphs=None, names=None):