如何在Python中定位局部最小点?

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

我有一个代码来绘制一组数据的热图,表示为 (x, y, f(x, y)),我想找到局部最小点。 Heatmap example with minimum points circled

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

data = np.genfromtxt('dados.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('dados.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
1个回答
0
投票

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

# 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

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