import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import minimize
# 1. ОПРЕДЕЛЯЕМ ФУНКЦИИ (без этого будут ошибки в Z = f(...) и GQ = grad_f(...))
def f(x):
# Ваша функция из задания №6
return x[0]**4 + 2*x[1]**2 - 1.1*x[0]*x[1]
def grad_f(x):
# Аналитические производные для градиентного метода
df_dx1 = 4 * x[0]**3 - 1.1 * x[1]
df_dx2 = 4 * x[1] - 1.1 * x[0]
return np.array([df_dx1, df_dx2])
# 2. РЕАЛИЗАЦИЯ МЕТОДОВ (чтобы получить переменные для графиков)
def simplex_method(f, x_start):
# Упрощенный поиск минимума (Нелдер-Мид)
res = minimize(f, x_start, method='Nelder-Mead')
return res.x, res.fun
def gradient_descent(f, grad, x_start, lr=0.01, eps=1e-7):
x = x_start.copy()
for i in range(1000):
g = grad(x)
if np.linalg.norm(g) < eps: break
x = x - lr * g
return x, f(x)
# Начальные данные
x_start = np.array([3.0, 3.0])
# Проводим расчеты (создаем те самые переменные, на которые ругается Spyder)
res_nm_custom, f_nm = simplex_method(f, x_start)
res_grad_custom, f_grad = gradient_descent(f, grad_f, x_start)
# 3. ВИЗУАЛИЗАЦИЯ (ваш код со скриншота, но теперь рабочий)
x_vals = np.linspace(-1.5, 3.5, 100)
y_vals = np.linspace(-1.5, 3.5, 100)
X, Y = np.meshgrid(x_vals, y_vals)
Z = f([X, Y])
fig = plt.figure(figsize=(14, 6))
# Левый график: Поверхность
ax1 = fig.add_subplot(121, projection='3d')
ax1.plot_surface(X, Y, Z, cmap='viridis', alpha=0.8)
ax1.set_title('Поверхность функции')
# Правый график: Линии уровня и градиенты
ax2 = fig.add_subplot(122)
cp = ax2.contour(X, Y, Z, levels=50)
plt.colorbar(cp)
# Стрелки градиентов
x_q = np.linspace(-1, 3, 15)
y_q = np.linspace(-1, 3, 15)
XQ, YQ = np.meshgrid(x_q, y_q)
GQ = grad_f([XQ, YQ])
ax2.quiver(XQ, YQ, -GQ[0], -GQ[1], color='red', alpha=0.5, scale=50, label='Антиградиент')
# Точки минимума
ax2.plot(res_nm_custom[0], res_nm_custom[1], 'm*', markersize=12, label='Min (Nelder-Mead)')
ax2.plot(res_grad_custom[0], res_grad_custom[1], 'cx', markersize=10, label='Min (Gradient)')
# Поиск второго минимума (он симметричен)
second_min = minimize(f, [-1, -1]).x
ax2.plot(second_min[0], second_min[1], 'ro', markersize=5, label='Второй минимум')
ax2.set_title('Линии уровня и градиенты')
ax2.legend()
plt.show()