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):
There are two interesting questions here:
Can you tell me how is this problem called, and point me to some proper solutions to it, in case they exists?
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.
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 .
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With