是否存在一种算法来查找二维数组中不相交值的最小和



我正在寻找一种快速算法来确定给定2D数组的特定最小属性-没有行或列共同的最小值的总和。我相信这一定有一个名字,但我不知道它叫什么。

我有一个字符串匹配系统,它将在空格上分割输入字符串,并将其与搜索值的语料库进行比较(也在空格中分割),并返回每个字符串中标记之间的距离矩阵,我想通过取距离的最小组合将其减少到单个聚合距离,而不重用任何输入/输出标记组合。

例子:

{ 1, 2 }   => 5 (either 1+4, or 3+2)
{ 3, 4 }
{ 0, 2 }   => 6 (because 2+4 < 0+8)
{ 4, 8 } 
{ 1, 0, 0 }
{ 0, 1, 0 } => 0
{ 0, 0, 1 }
{ 2, 3, 4 }
{ 3, 2, 4 } => 6 (2+2+2)
{ 4, 3, 2 } 
到目前为止,我一直在使用的朴素算法是这样的(c#):
public static int Minimux(this int[,] array) {
  var xUsed = new bool[array.GetLength(0)];
  var yUsed = new bool[array.GetLength(1)];
  var xMax = array.GetLength(0);
  var yMax = array.GetLength(1);
  var minima = new List<int>();
  var limit = Math.Min(xMax, yMax);
  int xMin = 0, yMin = 0;
  while (minima.Count < limit) {
    var vMin = Int32.MaxValue;
    for (var x = 0; x < xMax; x++) {
      for (var y = 0; y < yMax; y++) {
        if (xUsed[x] || yUsed[y] || array[x, y] >= vMin) continue;
        vMin = array[x, y];
        xMin = x;
        yMin = y;
      }
    }
    xUsed[xMin] = true;
    yUsed[yMin] = true;
    minima.Add(vMin);
  }
  return (minima.Sum());
}

它基本上做了一个数组扫描,当它找到每个最小值时,它将行/列组合标记为"使用",因此它不会再次被考虑-一旦列表中有尽可能多的最小值,因为在最短的数组维度中有元素,它返回这些最小值的总和。

问题是它在以下情况下会分解:

{ 0, 0, 0 }
{ 0, 0, 0 } => 3 (when it should be returning 1)
{ 1, 2, 3 } 

当扫描到最后一行时,它已经将第0列和第1列标记为"已使用",因此第2行中最小的未使用值是3,而实际上应该使用1

是否存在执行此操作的标准算法?

是的,存在一种标准算法可以精确地解决这个问题。它的名字是Hungarian algorithm

最新更新