如何定位局部最小点?

问题描述 投票:0回答:2

我有一个代码来绘制一组数据的热图,表示为

(x, y, f(x, y))
,我想找到局部最小点。

import numpy as np
import math
import matplotlib.pyplot as plt
import matplotlib as mpl
from scipy.interpolate import griddata

data = np.genfromtxt('data.dat',
                     skip_header=1,
                     delimiter='        ')


x, y, z = data[:, 1], data[::, 0], data[:, 2]
x, y, z = x*180/math.pi, y*180/math.pi, z - min(z)

xi, yi = np.linspace(max(x), min(x), 1000), np.linspace(max(y), min(y), 1000)

xi, yi = np.meshgrid(xi, yi)


zi = griddata((x, y), z, (xi, yi), method='linear')


plt.figure(figsize=(10,5))
plt.pcolormesh(xi, yi, zi, shading='auto', cmap='jet')

plt.colorbar(label='Heatmap')

plt.gca().invert_yaxis()


plt.show()

这是生成一些假数据的代码:

import math

with open('data.dat', 'w') as arquivo:

    for x in range(20):
        for y in range(20):
            z = -math.exp(math.sin(x*y)- math.cos(y))
            arquivo.write(f"{x}\t\t{y}\t\t{z}\n")

最小点圈出的热图示例:

我尝试使用

np.gradient
,认为也许通过取两个导数我就能够确定局部最小点(一阶导数为零,二阶导数为负),但我无法使其发挥作用.

python matplotlib heatmap derivative calculus
2个回答
1
投票

为了找到局部最小值,我们通常使用一些基于梯度的优化,例如梯度下降。然而,找到所有局部最小值并不容易,除非进行大量“重新启动”(通常人们对一个局部最小值感到满意)。解决问题的一种直接方法是使用网格搜索:如果当前点小于其周围的邻居,则它是一个局部最小值。代码片段如下

# Function to get the neighbors of a given point (i,j)
def get_neighbors(i, j, shape):
    neighbors = []

    for x in [-1, 0, 1]:
        for y in [-1, 0, 1]:
            ni, nj = i + x, j + y

            if (0 <= ni < shape[0]) and (0 <= nj < shape[1]) and (x, y) != (0, 0):
                neighbors.append((ni, nj))

    return neighbors

local_minima = []

# Iterate over the 2D grid
for i in range(zi.shape[0]):
    for j in range(zi.shape[1]):
        current_value = zi[i, j]
        neighbors = get_neighbors(i, j, zi.shape)

        # Check if the current point is less than all its neighbors
        if all(current_value < zi[n[0], n[1]] for n in neighbors):
            local_minima.append((xi[i, j], yi[i, j], current_value))
# Print the local minima
for loc in local_minima:
    print(f"Local minimum value {loc[2]} at location ({loc[0]}, {loc[1]}).")

然后绘制局部最小值

# Marking all the local minima on the plot
for loc in local_minima:
    plt.scatter(loc[0], loc[1], color='red', s=100, marker='x')

Sample output


-1
投票

有几种方法可以做到这一点,但我的方法是使用 scipy 过滤器(如 uniform 过滤器)创建地图背景的模型,其尺寸足够大以包含地图上的几个主要特征地图(例如图像大小的一半)。然后使用 标准差过滤器创建地图标准差的另一个模型。

局部最小值出现在

(original_map - background) / standard_deviation < threshold_value
处。

您可以尝试使用

threshold_value
(也许负 2-3 就可以了)以及过滤窗口的大小。

Python 代码留作练习。 :)

© www.soinside.com 2019 - 2024. All rights reserved.