Here is to share a Python division of the two-dimensional array to find a local peak method, has a good reference value, we hope to help. Come and see it together.
The meaning of the topic is roughly in a two-dimensional array of n*m, where a local peak is found. The peak requirement is greater than the adjacent four elements (which are considered negative infinity outside the array boundary), such as last we find the peak a[j][i], then a[j][i] > A[j+1][i] && a[j][i] > a[j-1][i] && a[j ][i] > A[j][i+1] && a[j][i] > a[j][i-1]. Returns the coordinates and values for this peak.
Of course, the simplest and most straightforward method is to traverse all array elements to determine if it is a peak, and the time complexity is O (n^2).
The maximum value of each row (column) is optimized, then the peak value of the maximum column is found by the dichotomy method (the method can see the peak of one-dimensional array), and the time complexity of the algorithm is O (LOGN).
Here is a complex O (n) algorithm, the idea of the algorithm is divided into the following steps:
1, find "Tian" word. Includes four sides of the periphery and two edges in the middle and the other (the green part of the figure), comparing its size to find the position of the maximum value. (7 in the picture)
2, find the maximum value in the field, determine if it is not a local peak, if the coordinate is returned, if not, the record finds the nearest four points in the maximum coordinates. Reduce the range by the quadrant in which the coordinates are located, and continue to compare the next field word
3. When the range is reduced to 3*3, local spikes will be found (or they may have been found before).
As to why there must be a peak in the range we choose, you can think of it, first we have a circle and we know that there is at least one element in the circle that is larger than all of the elements in this loop, so is there a maximum value in this circle?
May be said a bit around, but think more should be able to understand, but also can be used to prove the mathematics of the contrary.
Algorithm we understand the next step is the code implementation, here I use the language is Python (beginner python, may be some usage is not concise please forgive me), first on the code:
Import NumPy as Npdef max_sit (*n): #返回最大元素的位置 temp = 0 sit = 0 for I in range (len (n)): if (n[i]>temp): temp = N[i ] sit = I return sitdef dp (S1,S2,E1,E2): m1 = Int ((E1-S1)/2) +s1 #row m2 = Int ((E2-S1)/2) +s2 #col nub = e1-s1 temp = 0 Sit_row = 0 sit_col = 0 for I in range (nub): t = max_sit (List[s1][s2+i], #第一排 list[m1][s2+i], #中间排 list [E1] [S2+i], #最后排 list[s1+i][s2], #第一列 list[s1+i][m2], #中间列 list[s1+i][e2], #最后列 temp) if (t==6 ): Pass Elif (t==0): temp = list[s1][s2+i] Sit_row = S1 Sit_col = s2+i elif (t==1): temp = List[m1][s2+i] Sit_ Row = M1 Sit_col = s2+i elif (t==2): temp = list[e1][s2+i] Sit_row = e1 Sit_col = s2+i elif (t==3): temp = list[ S1+I][S2] Sit_row = s1+i Sit_row = S2 elif (t==4): temp = list[s1+i][m2] Sit_row = s1+i Sit_col = M2 elif (t==5) : temp = list[s1+i][e2] Sit_row = s1+i Sit_col = m2 t = max_sit (List[sit_row][sit_col], #中 list[sit_row-1][sit_ Col], #上 list[siT_row+1][sit_col], #下 list[sit_row][sit_col-1], #左 list[sit_row][sit_col+1]) #右 if (t==0): return [Sit_row-1,sit_ COL-1] Elif (t==1): Sit_row-=1 elif (t==2): Sit_row+=1 elif (t==3): Sit_col-=1 elif (t==4): sit_col+=1 if (SIT_ROW<M1): E1 = M1 ELSE:S1 = M1 if (sit_col<m2): E2 = m2 Else:s2 = m2 return dp (s1,s2,e1,e2) F = open ("Demo.txt", "r") List = f. Read () List = List.split ("\ n") #对行进行切片list = ["0" *len (list)]+list+["0" *len (list)] #加上下的围墙for I in range (len (list)): #对列进行切片 List[i] = List[i].split () list[i] = ["0"]+list[i]+["0"] #加左右的围墙list = Np.array (list). Astype (Np.int32) row_ n = len (list) Col_n = Len (list[0]) Ans_sit = DP (0,0,row_n-1,col_n-1) print ("Find Peak point at:", ans_sit) print ("This peak point size is:", List[ans _SIT[0]+1,ANS_SIT[1]+1]) F.close ()
First of all, my input is written in txt text file, through the string conversion into a two-dimensional array, the specific conversion process can be seen in my previous blog-python string into a two-dimensional array . (It is important to note that if the list after split in the Windows environment does not have an empty tail, do not add List.pop ().) Some change is that I added a "0" fence around the two-dimensional array. The fence can be used to judge the peak time without considering the boundary problem.
The Max_sit (*n) function is used to find the position of the largest value in multiple values, returning its position, and the max function of the python's intrinsic can only return the maximum value, so it still needs to write itself, *n the indefinite length parameter, because I need to use this function in the comparison field and 10 (judging the peak)
def max_sit (*n): #返回最大元素的位置 temp = 0 sit = 0 for I in range (len (n)): if (n[i]>temp): temp = n[i] sit = i return sit
The four parameters in the DP (S1,S2,E1,E2) function can be seen as Startx,starty,endx,endy respectively. That is, we look for the coordinate values in the upper-left and lower-right corners of the range.
M1,M2 are the middle values of row and Col, which is the middle of the field.
def DP (S1,S2,E1,E2): m1 = Int ((E1-S1)/2) +s1 #row m2 = Int ((E2-S1)/2) +s2 #col
Compare the values in 3 rows and 3 columns to find the maximum value, note that the two-dimensional array is required to be square, and if the rectangle needs to be adjusted
For I in range (nub): t = max_sit (List[s1][s2+i], #第一排 list[m1][s2+i], #中间排 list[e1][s2+i], #最后排 List[s1+i][s2], #第一列 list[s1+i][m2], #中间列 list[s1+i][e2], #最后列 temp) if (t==6): pass elif (t==0): temp = list[s1][s2+i] sit_row = S1 sit_col = s2+i elif (t==1 ): temp = list[m1][s2+i] Sit_row = m1 sit_col = S2+i elif (t==2): temp = list[e1][s2+i] Sit_row = e1 sit_col = s2+i elif (t==3): temp = list[s1+i][s2] sit_row = s1+i sit_row = s2 Elif (t==4): temp = list[s1+i][m2] sit_row = s1+i sit_row = m2 elif (t==5): temp = list[s1+i][ E2] Sit_row = s1+i Sit_row = m2
Determine if the maximum value in the field is not the peak value, and cannot find the nearest neighbor maximum
t = max_sit (List[sit_row][sit_col], #中 List[sit_row-1][sit_col], #上 List[sit_row+1][sit_col], #下 list[sit_row][sit_col-1], #左 list[sit_row][sit_col+1]) #右 if (t==0): return [ SIT_ROW-1,SIT_COL-1] elif (t==1): sit_row-=1 elif (t==2): sit_row+=1 elif (t==3) : Sit_col-=1 elif (t==4): sit_col+=1
Narrow the range, recursive solution
if (SIT_ROW<M1): e1 = M1 else: S1 = M1 if (sit_col<m2): e2 = m2 else: s2 = m2< C26/>return DP (S1,S2,E1,E2)
Okay, here's the basic analysis of the code. If there is no clear place welcome the message below.
In addition to this algorithm, I also write a greedy algorithm to solve this problem, but unfortunately the worst case algorithm complexity or O (n^2), Qaq.
The general idea is to find the largest point of the adjacent 4 points from the middle position, continue to the point to find the adjacent maximum point, will eventually find a peak point, interested can look at the code:
#!/usr/bin/python3def DP (n): temp = (str[n],str[n-9],str[n-1],str[n+1],str[n+9]) #中 left and right sit = Temp.index (max (temp ) if (sit==0): Return Str[n] Elif (sit==1): Return DP (n-9) elif (sit==2): return DP (n-1) elif (sit==3): Return DP (n+1) ELSE: return DP (n+9) F = open ("/home/nancy/desktop/demo.txt", "r") List = F.read () List = List.replace ("", "") . Split () #转换为列表row = len (list) col = Len (list[0]) str= "0" * (col+3) for x in list: #加围墙 Two-dimensional change one-dimensional str+=x+ "xx" str+= "0" * ( col+1) mid = Int (len (str)/2) print (STR,MID) p = DP (mid) print (p) f.close ()