# Algorithm to minimize distance variance between 2D coordinates

I've been looking around for an algorithm that would optimize the distance between 2 list of coordinates and choose which coordinate should go together.

Say I have List 1:

205|200
220|210
200|220
200|180


List 2:

210|200
207|190
230|200
234|190


Calculated Distance between Coords:

205|200 to 210|200 == 5.00
205|200 to 207|190 == 10.20
205|200 to 230|200 == 25.00
205|200 to 234|190 == 30.68

220|210 to 210|200 == 14.14
220|210 to 207|190 == 23.85
220|210 to 230|200 == 14.14
220|210 to 234|190 == 24.41

200|220 to 210|200 == 22.36
200|220 to 207|190 == 30.81
200|220 to 230|200 == 36.06
200|220 to 234|190 == 45.34

200|180 to 210|200 == 22.36
200|180 to 207|190 == 12.21
200|180 to 230|200 == 36.06
200|180 to 234|190 == 35.44


This Algorithm would pick:

205|200 to 230|200 == 25.00
220|210 to 207|190 == 23.85
200|220 to 210|200 == 22.36
200|180 to 234|190 == 35.44


The Algorithm would pick these numbers as they would be the group that would have the littlest variance between the distance. Conditions:

1. A Coordinate may only be used ones from each list
2. If List 1 or List2 is larger than it still only uses each coordinate once, but it tries to get the smallest distance variance and does nothing with the unused coordinates.

P.S. I've looked at the Hungarian algorithm and it seems like it will sort of do the job, but not exactly how I was expecting. The Hungarian algorithm will only try and make the least distance from all the coordinates, which can mean the smallest variance, but not every time as variance is more important here then least distance optimization.

I will have an array of List1, List2, and then the distances:

Distance[List1_item_0][List2_item_0] = 5;
Distance[List1_item_0][List2_item_1] = 10.20;
Distance[List1_item_0][List2_item_2] = 25.00;
Distance[List1_item_0][List2_item_3] = 30.68;

Distance[List1_item_1][List2_item_0] = 14.14;
Distance[List1_item_1][List2_item_1] = 23.85;
Distance[List1_item_1][List2_item_2] = 14.14;
Distance[List1_item_1][List2_item_3] = 24.41;

Distance[List1_item_2][List2_item_0] = 22.36;
Distance[List1_item_2][List2_item_1] = 30.81;
Distance[List1_item_2][List2_item_2] = 36.06;
Distance[List1_item_2][List2_item_3] = 45.34;

Distance[List1_item_3][List2_item_0] = 22.36;
Distance[List1_item_3][List2_item_1] = 12.21;
Distance[List1_item_3][List2_item_2] = 36.06;
Distance[List1_item_3][List2_item_3] = 35.44;


From the Distance['List1_item_#] I would need to pick a distance. Once that distance is picked the [List2_item_#] CANNOT be picked by a different [List1_item_#]. The distances picked for each [List1_item_#] element would need to be picked in a way that the variance between them all is minimal. So distance for each [List1_item_#] should be as close as possible to each other without reusing a [List2_item_#] more than once.

• Any algorithm? There's a relatively simple brute force $O(N!)$ algorithm. ;) – edA-qa mort-ora-y May 26 '12 at 7:30
• Please specify formally what exactly the desired result is. It looks like you want a) a pairing of two coordinate lists that b) has minimal sample variance among all pairings. Is that correct? – Raphael May 26 '12 at 9:36
• I would have a function that takes List1 and List2 and finds the distance between them and stores in an array similar to the "Calculated Distance between Coords:" List and then the Algorithm would have to go through and select the best fit option from each section without re-using a coordinate from List 2. I've added more code to the bottom to hopefully clarify – Steven10172 May 26 '12 at 9:48
• To rephrase: please define your notion of "distance" rigorously (in a general way, not by example). I don't understand the second part of your comment. – Raphael May 26 '12 at 12:13
• The distance is just the distance formula for a 2D plain(a graph). The square Root of((x1-x2)^2 + (y1-y2)^2) – Steven10172 May 26 '12 at 16:35

So here is a rather simple approach to solve this problem. You know that there are $O(n^2)$ different distances that matter. You can characterize the solution of your problem by the smallest and the largest distance ($d_\min$,$d_\max$) between your matched points. This gives you a set of $O(n^4)$ candidates.
So suppose you want to test, if there exists a matching where all distances are between $d_\min$ and $d_\max$. In other words, you want to solve the decision problem. This can be modeled as a perfect matching in a bipartite graph. Let $(u_1,\ldots,u_n)$ be the points in the first list and $(v_1,\ldots,v_n)$ be the points in the second list. Consider the bipartite graph that has an edge $(u_i,v_j)$ if and only if the distance between $u_i$ and $v_j$ is contained inside $[d_\min,d_\max]$. If this graph has a perfect matching, then there is an point-to-point assignment for the given distance constraints. Such a test can be done by the Hopcroft-Kahn algorithm, which needs $O(n^{2.5})$. A slightly faster solution can be achieved with fast matrix multiplication.
So you are left with trying out the candidates. This gives a $O(n^{6.5})$ algorithm. You can save a bit of running time by trying out all $d_\min$ values but then do a binary search for each $d_\max$ value. Now you have to solve only $O(n^2 \log n)$ decision problems (you also have to sort all distances, which is dominated by the overall running time) and hence the running time is only $O(n^{4.5}\log n)$.