我一直在寻找为分类矩阵使用二进制搜索逻辑的最佳优化方法。
使用Stack Over flow中“ Michal Sznajder ”建议的逻辑。 Most efficient way to search a sorted matrix?
但难以计算时间复杂度与递归关系。 有人可以帮助我。
虽然我使用二进制搜索逻辑,但我认为它不是T(n)= log(m + n)。
是T(n)= log(log(log(m x n)))还是log(log(m x n))?
代码可能不是最佳标准或优化但我刚开始写作。
/*
1, 4, 7, 10, 13,
2, 5, 8, 11, 14,
3, 6, 9, 12, 15,
16, 17, 18, 19, 20,
21, 22, 23, 24, 25,
26, 27, 28, 29, 30
a ..... b ..... c
. . . . .
. 1 . 2 .
. . . . .
d ..... e ..... f
. . . . .
. 3 . 4 .
. . . . .
g ..... h ..... i
a, c, g < i --> if not there is no element
a, b, d < e
b, c, e < f
d, e, g < h
e, f, h < i
Left Top : Right Top
-----------Mid--------------
Left Bottom : Right Bottom
*/
public int SearchSortedMatrixInLogNByM(int[,] SortedMatix, int elementToSearch, int rowStPos, int colStPos, int rowEndPos, int colEndPos)
{
// Step 0. Check for basic validations.
if (SortedMatix == null)
{
throw new Exception("Matrix is empty");
}
// Step 1. Use divide and conquer and to get the middle element.
int resultNode = 0;
int rowMidPos = (rowStPos + rowEndPos) / 2;
int colMidPos = (colStPos + colEndPos) / 2;
// Step 2. Mid element in Recursive Sub Matrix. For e.g in above example if it is 'e', 'f','h','i' then found.
if (SortedMatix[rowMidPos, colMidPos] == elementToSearch || SortedMatix[rowMidPos, colEndPos] == elementToSearch ||
SortedMatix[rowEndPos, colMidPos] == elementToSearch || SortedMatix[rowEndPos, colEndPos] == elementToSearch)
{
return elementToSearch;
}
// Step 3. Terminate the sub matrix iteration when the element is not found in the 2 X 2 matrix.
if ((rowStPos == rowMidPos || colStPos == colMidPos) && SortedMatix[rowStPos, colStPos] != elementToSearch)
{
return 0;
}
// Step 4. Left Top Sub Matrix.
if (resultNode == 0 && elementToSearch < SortedMatix[rowMidPos, colMidPos])
{
resultNode = SearchSortedMatrixInLogNByM(SortedMatix, elementToSearch, rowStPos, colStPos, rowMidPos, colMidPos);
}
// Step 5. Right Top Sub Matrix.
if (resultNode == 0 && elementToSearch < SortedMatix[rowMidPos, colEndPos])
{
resultNode = SearchSortedMatrixInLogNByM(SortedMatix, elementToSearch, rowStPos, colMidPos, rowMidPos, colEndPos);
}
// Step 6. Left bottom Sub Matrix.
if (resultNode == 0 && elementToSearch < SortedMatix[rowEndPos, colMidPos])
{
resultNode = SearchSortedMatrixInLogNByM(SortedMatix, elementToSearch, rowMidPos, colStPos, rowEndPos, colMidPos);
}
// Step 7. Right bottom Sub Matrix.
if (resultNode == 0 && elementToSearch < SortedMatix[rowEndPos, colEndPos])
{
resultNode = SearchSortedMatrixInLogNByM(SortedMatix, elementToSearch, rowMidPos, colMidPos, rowEndPos, colEndPos);
}
return resultNode;
}
public void SearchSortedMatrixTest()
{
int[,] SortedMatix = {{ 1, 4, 7, 10, 13,},
{ 2, 5, 8, 11, 14,},
{ 3, 6, 9, 12, 15,},
{ 16, 17, 18, 19, 20,},
{ 21, 22, 23, 24, 25,},
{ 26, 27, 28, 29, 30}};
//SearchSortedMatrixInNLogN(AssendMatix, 21);
StringBuilder strBldr = new StringBuilder();
strBldr.Append("\n 1 : " + SearchSortedMatrixInLogNByM(SortedMatix, 1, 0, 0, SortedMatix.GetLength(0) - 1, SortedMatix.GetLength(1) - 1));
strBldr.Append("\n 2 : " + SearchSortedMatrixInLogNByM(SortedMatix, 2, 0, 0, SortedMatix.GetLength(0) - 1, SortedMatix.GetLength(1) - 1));
strBldr.Append("\n 3 : " + SearchSortedMatrixInLogNByM(SortedMatix, 3, 0, 0, SortedMatix.GetLength(0) - 1, SortedMatix.GetLength(1) - 1));
strBldr.Append("\n 4 : " + SearchSortedMatrixInLogNByM(SortedMatix, 4, 0, 0, SortedMatix.GetLength(0) - 1, SortedMatix.GetLength(1) - 1));
strBldr.Append("\n 5 : " + SearchSortedMatrixInLogNByM(SortedMatix, 5, 0, 0, SortedMatix.GetLength(0) - 1, SortedMatix.GetLength(1) - 1));
strBldr.Append("\n 6 : " + SearchSortedMatrixInLogNByM(SortedMatix, 6, 0, 0, SortedMatix.GetLength(0) - 1, SortedMatix.GetLength(1) - 1));
strBldr.Append("\n 7 : " + SearchSortedMatrixInLogNByM(SortedMatix, 7, 0, 0, SortedMatix.GetLength(0) - 1, SortedMatix.GetLength(1) - 1));
strBldr.Append("\n 8 : " + SearchSortedMatrixInLogNByM(SortedMatix, 8, 0, 0, SortedMatix.GetLength(0) - 1, SortedMatix.GetLength(1) - 1));
strBldr.Append("\n 9 : " + SearchSortedMatrixInLogNByM(SortedMatix, 9, 0, 0, SortedMatix.GetLength(0) - 1, SortedMatix.GetLength(1) - 1));
strBldr.Append("\n 10 : " + SearchSortedMatrixInLogNByM(SortedMatix, 10, 0, 0, SortedMatix.GetLength(0) - 1, SortedMatix.GetLength(1) - 1));
strBldr.Append("\n 11 : " + SearchSortedMatrixInLogNByM(SortedMatix, 11, 0, 0, SortedMatix.GetLength(0) - 1, SortedMatix.GetLength(1) - 1));
strBldr.Append("\n 12 : " + SearchSortedMatrixInLogNByM(SortedMatix, 12, 0, 0, SortedMatix.GetLength(0) - 1, SortedMatix.GetLength(1) - 1));
strBldr.Append("\n 13 : " + SearchSortedMatrixInLogNByM(SortedMatix, 13, 0, 0, SortedMatix.GetLength(0) - 1, SortedMatix.GetLength(1) - 1));
strBldr.Append("\n 14 : " + SearchSortedMatrixInLogNByM(SortedMatix, 14, 0, 0, SortedMatix.GetLength(0) - 1, SortedMatix.GetLength(1) - 1));
strBldr.Append("\n 15 : " + SearchSortedMatrixInLogNByM(SortedMatix, 15, 0, 0, SortedMatix.GetLength(0) - 1, SortedMatix.GetLength(1) - 1));
strBldr.Append("\n 16 : " + SearchSortedMatrixInLogNByM(SortedMatix, 16, 0, 0, SortedMatix.GetLength(0) - 1, SortedMatix.GetLength(1) - 1));
strBldr.Append("\n 17 : " + SearchSortedMatrixInLogNByM(SortedMatix, 17, 0, 0, SortedMatix.GetLength(0) - 1, SortedMatix.GetLength(1) - 1));
strBldr.Append("\n 18 : " + SearchSortedMatrixInLogNByM(SortedMatix, 18, 0, 0, SortedMatix.GetLength(0) - 1, SortedMatix.GetLength(1) - 1));
strBldr.Append("\n 19 : " + SearchSortedMatrixInLogNByM(SortedMatix, 19, 0, 0, SortedMatix.GetLength(0) - 1, SortedMatix.GetLength(1) - 1));
strBldr.Append("\n 20 : " + SearchSortedMatrixInLogNByM(SortedMatix, 20, 0, 0, SortedMatix.GetLength(0) - 1, SortedMatix.GetLength(1) - 1));
strBldr.Append("\n 21 : " + SearchSortedMatrixInLogNByM(SortedMatix, 21, 0, 0, SortedMatix.GetLength(0) - 1, SortedMatix.GetLength(1) - 1));
strBldr.Append("\n 22 : " + SearchSortedMatrixInLogNByM(SortedMatix, 22, 0, 0, SortedMatix.GetLength(0) - 1, SortedMatix.GetLength(1) - 1));
strBldr.Append("\n 23 : " + SearchSortedMatrixInLogNByM(SortedMatix, 23, 0, 0, SortedMatix.GetLength(0) - 1, SortedMatix.GetLength(1) - 1));
strBldr.Append("\n 24 : " + SearchSortedMatrixInLogNByM(SortedMatix, 24, 0, 0, SortedMatix.GetLength(0) - 1, SortedMatix.GetLength(1) - 1));
strBldr.Append("\n 25 : " + SearchSortedMatrixInLogNByM(SortedMatix, 25, 0, 0, SortedMatix.GetLength(0) - 1, SortedMatix.GetLength(1) - 1));
strBldr.Append("\n 26 : " + SearchSortedMatrixInLogNByM(SortedMatix, 26, 0, 0, SortedMatix.GetLength(0) - 1, SortedMatix.GetLength(1) - 1));
strBldr.Append("\n 27 : " + SearchSortedMatrixInLogNByM(SortedMatix, 27, 0, 0, SortedMatix.GetLength(0) - 1, SortedMatix.GetLength(1) - 1));
strBldr.Append("\n 28 : " + SearchSortedMatrixInLogNByM(SortedMatix, 28, 0, 0, SortedMatix.GetLength(0) - 1, SortedMatix.GetLength(1) - 1));
strBldr.Append("\n 29 : " + SearchSortedMatrixInLogNByM(SortedMatix, 29, 0, 0, SortedMatix.GetLength(0) - 1, SortedMatix.GetLength(1) - 1));
strBldr.Append("\n 30 : " + SearchSortedMatrixInLogNByM(SortedMatix, 30, 0, 0, SortedMatix.GetLength(0) - 1, SortedMatix.GetLength(1) - 1));
strBldr.Append("\n\n Example 2:\n");
SortedMatix = new int[,] {{ 1, 4, 7,},
{ 2, 5, 8,},
{ 3, 6, 9}};
strBldr.Append("\n 1 : " + SearchSortedMatrixInLogNByM(SortedMatix, 1, 0, 0, SortedMatix.GetLength(0) - 1, SortedMatix.GetLength(1) - 1));
strBldr.Append("\n 2 : " + SearchSortedMatrixInLogNByM(SortedMatix, 2, 0, 0, SortedMatix.GetLength(0) - 1, SortedMatix.GetLength(1) - 1));
strBldr.Append("\n 3 : " + SearchSortedMatrixInLogNByM(SortedMatix, 3, 0, 0, SortedMatix.GetLength(0) - 1, SortedMatix.GetLength(1) - 1));
strBldr.Append("\n 4 : " + SearchSortedMatrixInLogNByM(SortedMatix, 4, 0, 0, SortedMatix.GetLength(0) - 1, SortedMatix.GetLength(1) - 1));
strBldr.Append("\n 5 : " + SearchSortedMatrixInLogNByM(SortedMatix, 5, 0, 0, SortedMatix.GetLength(0) - 1, SortedMatix.GetLength(1) - 1));
strBldr.Append("\n 6 : " + SearchSortedMatrixInLogNByM(SortedMatix, 6, 0, 0, SortedMatix.GetLength(0) - 1, SortedMatix.GetLength(1) - 1));
strBldr.Append("\n 7 : " + SearchSortedMatrixInLogNByM(SortedMatix, 7, 0, 0, SortedMatix.GetLength(0) - 1, SortedMatix.GetLength(1) - 1));
strBldr.Append("\n 8 : " + SearchSortedMatrixInLogNByM(SortedMatix, 8, 0, 0, SortedMatix.GetLength(0) - 1, SortedMatix.GetLength(1) - 1));
strBldr.Append("\n 9 : " + SearchSortedMatrixInLogNByM(SortedMatix, 9, 0, 0, SortedMatix.GetLength(0) - 1, SortedMatix.GetLength(1) - 1));
MessageBox.Show("Element(s) Search in Sorted Matrix and the result(s) are " + strBldr.ToString());
}
答案 0 :(得分:1)
如果我正确理解算法,你可以使用Z模式将矩阵划分为四个象限,然后通过递归检查象限的中心并知道接下来要查看其四个子象限中的哪一个来查询。
在这种情况下,您可以将其视为与每个节点有四个子节点的树结构类似。每次评估当前节点时,您将进入四个子节点之一。在这样的树结构(以及该数据结构)中查询节点位置的时间将是O(log base 4(n)),其中n是矩阵中元素的总数。
原因是因为这是树的高度,我们必须在树的每个级别停止一次,才能找到最有可能位于底部的元素,因为树的那个级别约占75%整个树中的节点。
当然这是一个方阵。随着矩阵变得更加矩形,您的搜索变得效率更低,最坏的情况是n x 1矩阵,这只是一条长线。在这种情况下,您会看到O(log base 2(n)),因为您实际上每次只在两个子节点之间进行分割。
答案 1 :(得分:1)
更新:在网上提供一些帮助后,我能够稍微提高我的上一个答案。
事实证明,像许多问题一样,通过良好的Google搜索,这个问题很容易解决(只要可以解决)。我尝试了“按行和列排序的搜索矩阵”。其中一个结果就是这个页面:
Find number in sorted matrix (Rows n Columns) in O(log n)
坏消息是,在最糟糕的情况下,你不能比一个天真的一行一次算法做得更好,这个算法是O(min(m,n)* log(max(m)中,n)))。另一方面,朴素算法很容易实现,并且(我认为)在最优的恒定因子内。
对该问题的解决方案的评论链接到一个页面,其中包含一些其他有用的材料http://twistedoakstudios.com/blog/Post5365_searching-a-sorted-matrix-faster,它似乎概述了一种有用的,不太天真的算法。我认为我不能做得更好;当然不容易。
对于它的价值,这是我之前的回答:
算法需要工作。考虑这个4x4矩阵:
1, 2, 4, 10
3, 6, 7, 12
5, 8, 9, 14
11, 13, 15, 16
考虑在此矩阵中搜索包含值9,10或11的单元格。所有这三个值都将“test”传递到子矩阵2(右上角),但它们都将测试传递给子矩阵3(左下)。实际上,其中一个在子矩阵2中,一个在子矩阵3中,一个在这两个子矩阵中。根据包含值4,12,13和16的单元格的观察值,这三个数字中唯一可以说的是这些数字都不在子矩阵1中。所以你消除了1/4的那一步的矩阵。
值4和5应该根据算法出现在子矩阵1中(因为每个小于6,位于该子矩阵的右下角),但实际上一个在子矩阵2中,另一个在子矩阵中子标记3.当您要查找的值小于子矩阵1的右下角元素时,这四个比较通常不允许您消除任何子矩阵。