如果你有2个尺寸为N * M的矩阵。 获得差异的最佳方法是什么?
示例:
2 3 2 3 2 3 2 3 2 3 2 3 2 3 2 3
2 3 2 3 2 3 2 3 2 3 2 3 2 3 2 3
2 3 4 5 4 3 2 3 <---> 2 3 2 3 2 3 2 3
2 3 4 5 2 3 2 3 2 3 2 3 2 3 2 3
2 3 2 3 2 3 2 3 2 3 2 3 2 3 2 3
|
|
\ /
Rect([2,2] , [3,4])
4 5 4
4 5 2-> A (2 x 3 Matrix)
我能想到的最好的是从左上角扫描到有差异的点。 然后从右下角扫描并找到存在差异的点。
但在最坏的情况下,这是O(N * M)。有更好的有效算法吗?或者我可以用我如何表示它们,以便您可以应用更有效的算法?请注意,这个Matrix可能非常大。
答案 0 :(得分:3)
不,没有更高效的算法。对于相同的矩阵,您必须扫描所有元素,因此算法必须是O(n*m)
。
答案 1 :(得分:3)
“但在最坏的情况下,这是O(N M)。是否有更好的算法?”可能不是由于数据的维度为O(N M)。像这样的许多矩阵运算都是M N的阶数,因为在最坏的情况下,存在M N个元素,在矩阵相等的情况下都需要检查它们。
观察平均情况更有意思,如果差异框必须是整个矩阵中的单个矩形,那么我怀疑你可以平均扫描少于所有元素。
虽然我有一个快速: 跟踪当前元素,调用此XY
从左上角开始,因此XY现在是顶角
检查两者中的元素XY是否相等,如果不相等则转到3否则转到4
如果元素不是那么你有一个差异矩阵的元素。记录此元素,然后搜索其他元素的行和列(可能是二进制搜索最快)。搜索行/列后,您将获得边的坐标。如果元素不相等,请移至4.
下一步将XY对角线向下移动一个元素,向右移动一个元素,然后再转到2
一旦对角线被覆盖,那么你将需要沿着下一个对角线进行测试(我怀疑选择距离当前对角线最远的新对角线将是最好的,尽管我没有证据证明这一点是最好的选择),直到涵盖所有元素。最糟糕的情况是,这仍然是O(N * M),但在一般情况下可能更快。
基本上你是在尽可能快地尝试一个不同的元素,所以目的是选择第一个元素,以最小化搜索次数的预期值,以找到第一个不同的元素。
答案 2 :(得分:2)
正如其他人所指出的那样,O(N * M)是最佳的。
我想补充一点,在扫描矩阵时,你应该记住它的内存布局。如果矩阵按行布局,最好水平扫描。如果它按列布局,则可以更好地垂直扫描。这将导致非常优化的缓存行为。
当然,这假设问题的差异确实是矩形的形式。如果它是其他形状,并且你想要边界矩形,你将不得不扫描行和列,无论如何。
答案 3 :(得分:0)
我认为提出的算法是最优的算法。但是我建议你试试BLAS库非常有效,并比较性能。还有Boost uBlas库提供C ++接口和methods for Matrix expressions。