选择元素对之间的最短距离

时间:2013-09-05 15:19:26

标签: c++ arrays algorithm sorting

我想在C ++中解决以下问题:

我有6个元素:A1,A2,A3,B1,B2,B3。我想将一个B恰好与一个A匹配,这样产生的匹配总和就是最小的。

以下是我编写一个简单的贪婪算法的想法(可能不是最优的,但对我来说似乎已经足够了):

  1. 测量所有A-B对之间的距离,将其保存在2D浮点阵列中。
  2. 将2D数组排序为单个值,类似于以下排序lambda:
  3. 设置A的最佳匹配,禁用搜索选定的B和A(禁用2D中的列和行)。
  4. 从仍然可用的阵列中选择最小的数字。
  5. 等。等等,直到完成所有比赛。
  6. 这里有两个有趣的问题:

    1. 你能告诉我这个问题是如何被调用的,并指出一些适当的解决方案,如果存在的话?

    2. 您能告诉我如何在C ++中实现上述贪婪算法?到目前为止,我想过使用这个函数来排序

    3. 以下是代码:

      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个元素的性能,但是当元素的数量要大得多时,我真的对这个问题的真正解决方案感兴趣。

1 个答案:

答案 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。