Загрузка данных


import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import minimize

def f(x):
    x1, x2 = x
    return (x1 - 1.1)**2 + (1.2 * x2 - 1.1)**2 - 1.2 * x1 * x2

def grad(x):
    x1, x2 = x
    df_dx1 = 2 * (x1 - 1.1) - 1.2 * x2
    df_dx2 = 2 * 1.2 * (1.2 * x2 - 1.1) - 1.2 * x1
    return np.array([df_dx1, df_dx2])

x0 = np.array([0.0, 3.0])

res_nm = minimize(f, x0, method='Nelder-Mead')
res_bfgs = minimize(f, x0, jac=grad, method='BFGS')

min_nm = res_nm.x
min_bfgs = res_bfgs.x

print("Точки минимумов:")
print(f"Nelder-Mead: ({min_nm[0]:.8f}, {min_nm[1]:.8f}), f = {res_nm.fun:.8f}")
print(f"BFGS:        ({min_bfgs[0]:.8f}, {min_bfgs[1]:.8f}), f = {res_bfgs.fun:.8f}")
print(f"Разница между точками: ({abs(min_nm[0]-min_bfgs[0]):.2e}, {abs(min_nm[1]-min_bfgs[1]):.2e})")

# Сетка для графиков
x1_vals = np.linspace(-1, 4, 40)
x2_vals = np.linspace(-1, 4, 40)
X1, X2 = np.meshgrid(x1_vals, x2_vals)
Z = (X1 - 1.1)**2 + (1.2 * X2 - 1.1)**2 - 1.2 * X1 * X2

# Численный градиент для поля направлений
py, px = np.gradient(Z)

fig = plt.figure(figsize=(10, 12))

# 3D поверхность
ax1 = fig.add_subplot(2, 1, 1, projection='3d')
surf = ax1.plot_surface(X1, X2, Z, cmap='viridis', alpha=0.8, edgecolor='none')
ax1.scatter(min_nm[0], min_nm[1], f(min_nm), color='red', s=80, label='Nelder-Mead', zorder=5)
ax1.scatter(min_bfgs[0], min_bfgs[1], f(min_bfgs), color='blue', s=80, label='BFGS', zorder=5)
ax1.set_xlabel('x₁')
ax1.set_ylabel('x₂')
ax1.set_zlabel('f(x₁, x₂)')
ax1.set_title('3D поверхность функции')
ax1.legend()
fig.colorbar(surf, ax=ax1, shrink=0.6, aspect=20)

# Контуры + градиент
ax2 = fig.add_subplot(2, 1, 2)
contour = ax2.contour(X1, X2, Z, levels=25, cmap='viridis', linewidths=0.8)
ax2.clabel(contour, inline=True, fontsize=8, fmt='%0.2f')

# Векторное поле градиента (разреженное)
stride = 3
ax2.quiver(X1[::stride, ::stride], X2[::stride, ::stride],
           px[::stride, ::stride], py[::stride, ::stride],
           color='black', alpha=0.4, scale=25, width=0.005)

ax2.scatter(min_nm[0], min_nm[1], color='red', s=120, zorder=5,
            label=f'Nelder-Mead ({min_nm[0]:.4f}, {min_nm[1]:.4f})', edgecolors='black')
ax2.scatter(min_bfgs[0], min_bfgs[1], color='blue', s=120, zorder=5,
            label=f'BFGS ({min_bfgs[0]:.4f}, {min_bfgs[1]:.4f})', edgecolors='black', marker='s')

ax2.annotate('NM', (min_nm[0], min_nm[1]),
             xytext=(5, 5), textcoords='offset points', fontsize=9, color='red')
ax2.annotate('BFGS', (min_bfgs[0], min_bfgs[1]),
             xytext=(5, -8), textcoords='offset points', fontsize=9, color='blue')

ax2.set_xlabel('x₁')
ax2.set_ylabel('x₂')
ax2.set_title('Линии равного уровня и поле градиента')
ax2.legend(loc='upper right')
ax2.grid(True, alpha=0.3)
ax2.axis('equal')

plt.tight_layout()
plt.show()