import numpy as np
from scipy.optimize import minimize
def f(x):
"""Целевая функция из второго задания"""
x1, x2 = x
return 1.2 * (2 * x2 - x1**2)**2 + 10 * (1.1 - x1)**2
def nelder_mead(f, x0, eps=1e-6, alpha=1.0, beta=0.5, gamma=2.0, sigma=0.5):
n = len(x0)
simplex = np.zeros((n, n + 1))
simplex[:, 0] = x0
for i in range(1, n + 1):
simplex[:, i] = x0.copy()
simplex[i - 1, i] += 1.0
f_vals = np.array([f(simplex[:, i]) for i in range(n + 1)])
it = 0
while np.std(f_vals) > eps and it < 1000:
order = np.argsort(f_vals)
simplex = simplex[:, order]
f_vals = f_vals[order]
xc = np.mean(simplex[:, :-1], axis=1)
xr = xc + alpha * (xc - simplex[:, -1])
fxr = f(xr)
if f_vals[0] <= fxr < f_vals[-2]:
simplex[:, -1] = xr
f_vals[-1] = fxr
elif fxr < f_vals[0]:
xe = xc + gamma * (xr - xc)
if f(xe) < fxr:
simplex[:, -1] = xe
f_vals[-1] = f(xe)
else:
simplex[:, -1] = xr
f_vals[-1] = fxr
else:
xc_outer = xc + beta * (simplex[:, -1] - xc)
if f(xc_outer) < f_vals[-1]:
simplex[:, -1] = xc_outer
f_vals[-1] = f(xc_outer)
else:
for i in range(1, n + 1):
simplex[:, i] = simplex[:, 0] + sigma * (simplex[:, i] - simplex[:, 0])
f_vals = np.array([f(simplex[:, i]) for i in range(n + 1)])
it += 1
best_idx = np.argmin(f_vals)
return simplex[:, best_idx], f_vals[best_idx], it
# Начальное приближение
x0 = np.array([2.0, 1.0])
# Собственная реализация
x_min, f_min, it = nelder_mead(f, x0)
print("Метод Нелдера-Мида (собственная реализация)")
print(f"Точка минимума: ({x_min[0]:.8f}, {x_min[1]:.8f})")
print(f"Значение функции: {f_min:.8f}")
print(f"Число итераций: {it}")
# Проверка через scipy
res = minimize(f, x0, method='Nelder-Mead')
print("\nПроверка (scipy.optimize.minimize):")
print(f"x = ({res.x[0]:.8f}, {res.x[1]:.8f})")
print(f"f = {res.fun:.8f}")