本文使用梯度下降法和梯度上升法分别求解函数 f(x) = cos(x)/x 在 1≤x≤20 范围内的极小值和极大值点。

通过 10 次随机采样不同的初始化值 x0,观察算法是否收敛到同一个解,并通过一阶导数和二阶导数验证这些点是否为极值点。

import numpy as np
import matplotlib.pyplot as plt

def f(x):
    return np.cos(x) / x

def f_prime(x):
    return (x * np.sin(x) - np.cos(x)) / x**2

def f_double_prime(x):
    return (2 * np.sin(x) - x * np.cos(x) - 2 * np.sin(x) + 2 * np.cos(x)) / x**3

def gradient_descent(x0, learning_rate, iterations):
    x = x0
    x_vals = [x]
    for i in range(iterations):
        x -= learning_rate * f_prime(x)
        x_vals.append(x)
    return x, x_vals

def gradient_ascent(x0, learning_rate, iterations):
    x = x0
    x_vals = [x]
    for i in range(iterations):
        x += learning_rate * f_prime(x)
        x_vals.append(x)
    return x, x_vals

np.random.seed(0)

x = np.linspace(1, 20, 1000)
y = f(x)

x0_list = np.random.uniform(1, 20, 10)
converged_min_points = []
converged_max_points = []

plt.plot(x, y, label='f(x)')

for x0 in x0_list:
    x_min, x_vals_min = gradient_descent(x0, 0.1, 1000)
    converged_min_points.append(x_min)
    plt.scatter(x_vals_min, f(x_vals_min), color='red', alpha=0.3)

    x_max, x_vals_max = gradient_ascent(x0, 0.1, 1000)
    converged_max_points.append(x_max)
    plt.scatter(x_vals_max, f(x_vals_max), color='blue', alpha=0.3)

plt.scatter(converged_min_points, f(np.array(converged_min_points)), color='green', label='Converged Min Points')
plt.scatter(converged_max_points, f(np.array(converged_max_points)), color='purple', label='Converged Max Points')
plt.legend()
plt.xlabel('x')
plt.ylabel('f(x)')
plt.title('Function and Converged Points')
plt.show()

# 验证是否为极值点
for x in converged_min_points:
    if f_double_prime(x) > 0:
        print('The point', x, 'is not a local minimum.')
    else:
        print('The point', x, 'is a local minimum.')

for x in converged_max_points:
    if f_double_prime(x) < 0:
        print('The point', x, 'is not a local maximum.')
    else:
        print('The point', x, 'is a local maximum.')

运行上述代码,将得到一个图像,显示了函数 f(x) 的曲线以及梯度下降和梯度上升过程中收敛到的极小值点和极大值点。每个初始值都用红色和蓝色的点表示,并在图例中显示收敛的最小值点和最大值点。同时,代码会输出每个收敛点的验证结果,以验证它们是否为极小值点和极大值点。

请注意,在验证时,如果某个点的二阶导数大于 0,则该点不是局部极小值点;如果某个点的二阶导数小于 0,则该点不是局部极大值点。反之,则是。


原文地址: https://www.cveoy.top/t/topic/b0Xs 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录