Given two arrays, find the permutations that give closest distance between two arrays

You can just sort both A and B. In that case, the Euclidean distance is minimal.

If B has to remain fixed, then you just need to invert the permutation needed to sort B and apply that to the sorted version of A.

This solution does assume that you want to find just a permutation and not the most simple permutation (since sorting and unsorting through permutations will not be incredibly efficient).


Proof: Let S,T be our pair of arrays. We can assume S to be sorted without loss of generality, since all that matters is the mapping between the two sets of elements.

Let T be the permutation that minimizes the distance between the two arrays, and let d be that distance.

Suppose that T is not sorted. Then there exist elements i,j s.t. T_i > T_j

S_i + k1 = S_j
T_i = T_j + k2
where k1,k2 > 0

Let x be the total distance of all elements except i and j.

d = x + (S_i - T_i)^2 + ((S_i + k1) - (T_i - k2))^2

If we swap the order of T_i and T_j, then our new distance is:

d' = x + (S_i - (T_i - k2))^2 + ((S_i + k1) - T_i)^2

Thus: d - d' = 2 * k1 * k2, which contradicts our assumption that T is the permutation that minimizes the distance, so the permutation that does so must be sorted.

Sorting the two arrays can be done in O(n log n) using a variety of methods.


The problem you describe is equivalent to the Minimum Cost Perfect Matching Problem which can be solved efficiently (and exactly) using The Hungarian Algorithm. In the Minimum Cost Perfect Matching Problem you have an input weighted bipartite graph where the two sets have the same size n, and each edge has a non-negative cost. The goal is to find a perfect matching of minimum cost.

In your case, the bipartite graph is a biclique. That is, every vertex in one set is connected to every vertex in the other set, and the cost of edge (i,j) is (A[i] - B[i])^2 (where i corresponds to index i in array A and j corresponds to index j in array B).

EDIT: This is not the best solution for the problem. Ivo Merchiers came up with a better solution both in terms of efficiency and simplicity. The reason I'm not deleting my answer is because my suggested solution is valuable for distance measures to which Ivo's solution does not apply (as his approach works by exploiting a property of the Euclidean distance).


You can just sort A and B and match up the corresponding elements.

Imagine that there are two elements of A, Ai and Aj, corresponding to Bi and Bj.

The error contribution from these matches is:

(Ai-Bi)^2 + (Aj-Bj)^2

= Ai^2 + Bi^2 + Aj^2 + Bj^2 - 2(AiBi + AjBj)

Is it better to swap the matches, or to keep them the way they are?

Well, the difference in the error if we swap them is:

2(AiBi + AjBj) - 2(AiBj + AjBi)

~ AiBi - AiBj + AjBj - AjBi

= Ai(Bi - Bj) - Aj(Bi - Bj)

= (Ai - Aj)(Bi - Bj)

So, if the As and Bs are in the same order, then this product is positive and the error will go up if you swap them. If they are not in the same order, then this product is negative an the error will go down if you swap them.

If you repeatedly swap any pairs that are out of order until there are no such pairs, your error will keep going down, and you'll end up with with the nth largest A matched up with the nth largest B all the way through the array.

Just sorting them and matching them up is therefor optimal, and of course it's way faster than the Hungarian algorithm.

Tags:

Algorithm