我想在C ++中解决以下问题:
我有6个元素:A1,A2,A3,B1,B2,B3。我想将一个B恰好与一个A匹配,这样产生的匹配总和就是最小的。
以下是我编写一个简单的贪婪算法的想法(可能不是最优的,但对我来说似乎已经足够了):
这里有两个有趣的问题:
你能告诉我这个问题是如何被调用的,并指出一些适当的解决方案,如果存在的话?
您能告诉我如何在C ++中实现上述贪婪算法?到目前为止,我想过使用这个函数来排序
以下是代码:
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];
});
而且我认为我会保留vector<bool> selectedA, selectedB;
来跟踪所选元素,但我不知道它有多好。
注意:好的,没有必要谈论3,3个元素的性能,但是当元素的数量要大得多时,我真的对这个问题的真正解决方案感兴趣。
答案 0 :(得分:5)
这称为最大成本二分匹配,最通用的算法是Bellman-Ford Algorithm(您可以将距离转换为负值以使算法直接适用)
您还可以使用Hungarian Algorithm,这实际上是分配问题,方法是将A顶点定义为工作线程,将B顶点定义为任务,并将距离放在成本矩阵中。
编辑:
对于简单方法(如3元素情况),您可以考虑完整搜索。这是因为我们可以将你的n x n距离矩阵视为一个板,我们需要选择n个正方形,这样每行和每列只有一个选定的正方形。
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)); }
复杂度为n ^ n,因此仅适用于n <= 8。