问题
给定一个二维数组,用PYTHON设计实现一个高效的算法找到一个峰值。
思路
1、给二维数组添加全零边框
2、找出田字框的最大值
3、比较该值(图中数字7)与其上下左右四个数的大小,若该值最大,则为峰值;否则,选取比其大的一个值(如9)所处的象限(如第一象限),进行迭代。
代码
import numpy as np
import math
# 查找最大值
def findMaxValue(*list):
tmp = 0
result = 0
for i in range(len(list)):
if(list[i]>tmp):
tmp = list[i]
result = i
return result
# 查找二维数组中的峰值
def findingPeak2(startRow,endRow,startCol,endCol,matrix):
midRow = math.floor((startRow + endRow)/2)
midCol = math.floor((startCol + endCol)/2)
maxTmp = matrix[startRow,startCol]
maxTmpLocRow = startRow
maxTmpLocCol = startCol
#找田字框的最大值,以及最大值的坐标
for i in range(startCol,endCol+1):
if maxTmp < matrix[startRow,i]:
maxTmp = matrix[startRow,i]
maxTmpLocRow = startRow
maxTmpLocCol = i
if maxTmp < matrix[midRow,i]:
maxTmp = matrix[midRow,i]
maxTmpLocRow = midRow
maxTmpLocCol = i
if maxTmp < matrix[endRow,i]:
maxTmp = matrix[endRow,i]
maxTmpLocRow = endRow
maxTmpLocCol = i
for i in range(startRow,endRow+1):
if maxTmp < matrix[i,startCol]:
maxTmp = matrix[i,startCol]
maxTmpLocRow = i
maxTmpLocCol = startCol
if maxTmp < matrix[i,midCol]:
maxTmp = matrix[i,midCol]
maxTmpLocRow = i
maxTmpLocCol = midCol
if maxTmp < matrix[i,endCol]:
maxTmp = matrix[i,endCol]
maxTmpLocRow = i
maxTmpLocCol = endCol
#判断田字框的最大值是否是峰值
rowOffset = np.array([0,0,-1,1])
colOffset = np.array([-1,1,0,0])
result = findMaxValue(maxTmp,
matrix[maxTmpLocRow+rowOffset[0],maxTmpLocCol+colOffset[0]],
matrix[maxTmpLocRow+rowOffset[1],maxTmpLocCol+colOffset[1]],
matrix[maxTmpLocRow+rowOffset[2],maxTmpLocCol+colOffset[2]],
matrix[maxTmpLocRow+rowOffset[3],maxTmpLocCol+colOffset[3]])
if result == 0:
res = (maxTmpLocRow-1,maxTmpLocCol-1)
elif result == 1:
if maxTmpLocRow < midRow:
#第一象限
res = findingPeak2(startRow,midRow,startCol,midCol,matrix)
else:
#第三象限
res = findingPeak2(midRow,endRow,startCol,midCol,matrix)
elif result == 2:
if maxTmpLocRow < midRow:
#第二象限
res = findingPeak2(startRow,midRow,midCol,endCol,matrix)
else:
#第四象限
res = findingPeak2(midRow,endRow,midCol,endCol,matrix)
elif result == 3:
if maxTmpLocCol < midCol:
#第一象限
res = findingPeak2(startRow,midRow,startCol,midCol,matrix)
else:
#第二象限
res = findingPeak2(startRow,midRow,midCol,endCol,matrix)
else:
if maxTmpLocCol < midCol:
#第三象限
res = findingPeak2(midRow,endRow,startCol,midCol,matrix)
else:
#第四象限
res = findingPeak2(midRow,endRow,midCol,endCol,matrix)
return res
# 数组初始化,以及调用计算函数
def main():
matrix = np.array([[9, 3, 5, 2, 4, 9, 8],
[7, 2, 5, 1, 4, 0, 3],
[9, 8, 9, 3, 2, 4, 8],
[7, 6, 3, 1, 3, 2, 3],
[9, 0, 6, 0, 4, 6, 4],
[8, 9, 8, 0, 5, 3, 0],
[2, 1, 2, 1, 1, 1, 1]])
row = matrix.shape[0] #行数
col = matrix.shape[1] #列数
# 加最外层的田字框
a = np.row_stack((matrix, np.zeros(col)))
a = np.row_stack((np.zeros(col), a))
a = np.column_stack((np.zeros(row+2), a))
a = np.column_stack((a, np.zeros(row+2)))
#找峰值
result = findingPeak2(0,row+1,0,col+1,a)
print("峰值点位置:",result)
print("峰值点大小:",matrix[result[0],result[1]])
if __name__ == '__main__':
main()