Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Selecting shortest distance between pairs of elements

I would like to solve the following problem in C++:

I have 6 elements: A1, A2, A3, B1, B2, B3. I would like to match exactly one B to exactly one A, in such a way that the sum of the resulting matches is the smallest.

Here is how I thought about writing a simple greedy algorithm (might not be optimal, but seems good enough for me):

  1. Measure the distance between all A-B pairs, save it in an 2D array of floats.
  2. Sort the 2D array as individual values, something like the sort lambda below:
  3. Set the best match for that A, disable searching for the selected B and A (disable a column and a row in 2D).
  4. Select the smallest number from the still available array.
  5. etc. etc, till all matches are made.

There are two interesting questions here:

  1. Can you tell me how is this problem called, and point me to some proper solutions to it, in case they exists?

  2. Can you tell me how would you implement the above greedy algorithm in C++? So far I thought about using this function to sort

Here is the code:

float centerDistances[3][3]; // .. random distances

vector<int> idx(9);

for (size_t i = 0; i != idx.size(); ++i) idx[i] = i;
sort(idx.begin(), idx.end(), [](int i1, int i2) 
{
    return centerDistances[0][i1] < centerDistances[0][i2];
});

And I think I'd keep a vector<bool> selectedA, selectedB; to keep track of selected elements, but I don't know how well it'd be.

Note: OK, there is no point talking about performance for 3,3 elements, but I'd be really interested in the real solution to this problem, when the number of elements is much larger.

like image 754
hyperknot Avatar asked Sep 05 '13 15:09

hyperknot


People also ask

What is the formula for finding the shortest distance?

The Distance Formula. The shortest distance between two points is a straight line. This distance can be calculated by using the distance formula. The distance between two points ( x 1 , y 1 ) and ( x 2 , y 2 ) can be defined as d = ( x 2 − x 1 ) 2 + ( y 2 − y 1 ) 2 .

Which method should be applied to find the shortest distance?

We wish to find its shortest distance from the line L : y = mx + c. Let B(bx,by) be the point on line L such that PB ⊥ L. It can be shown, using the Pythagoras theorem, that the perpendicular distance d = l(PB) (see the Figure) is the shortest distance between point P and line L.

How do you find the minimum distance between elements in an array?

Suppose we have one unsorted array A, and two numbers x and y. We have to find the minimum distance between x and y in A. The array can also contain duplicate elements. So if the array is A = [2, 5, 3, 5, 4, 4, 2, 3], x = 3 and y = 2, then the minimum distance between 3 and 2 is just 1.


1 Answers

This is called Maximum Cost Bipartite Matching, and the most general algorithm for it is Bellman-Ford Algorithm (you can convert your distance to negative to make the algorithm directly applicable)

You can also use Hungarian Algorithm, which is actually assignment problem, by defining the A vertices as workers and B vertices as tasks, and putting the distance in the cost matrix.

EDIT:

For simple method (like your 3-element case), you can consider complete search. This is because we can consider your n x n distance matrix as a board, and we need to select n squares, such that each row and each column has exactly one selected square.

float cost[n][n];
bool[n] used;

float solve(int row){
    float min = 999999; // Put a very large number here
    for(int i=0; i < n; i++){
        if(!used[i]){
            used[i] = 1;
            if(i==n-1){
                return cost[row][i];
            } else {
                float total = cost[row][i]+solve(row+1);
                if(total<min) min=total;
            }
            used[i] = 0;
        }
    }
    return min;
}

int main(){
    printf("%.2f\n",solve(0));
}

The complexity is n^n, so this only works for n <= 8.

like image 109
justhalf Avatar answered Oct 11 '22 13:10

justhalf