# Программа 1: Метод Нелдера-Мита (симплекс)
# Вариант 16: f = x1^2 + x2^2 + 1.1*x1*x2 + x1 - x2 + 1.1
import numpy as np
import scipy.optimize as optim
def f(x):
return x[0]**2 + x[1]**2 + 1.1*x[0]*x[1] + x[0] - x[1] + 1.1
def simplex(f, x, eps=1e-6, alpha=1, beta=0.5, gamma=2, sigma=0.5):
# Построение начального симплекса (как на листе, но исправлено)
n = len(x)
simplex = np.zeros((n, n+1))
simplex[:, 0] = x
for i in range(n):
step = np.zeros(n)
step[i] = 0.5
simplex[:, i+1] = x + step
fx = np.array([f(simplex[:, i]) for i in range(n+1)])
it = 0
while np.var(fx) > eps and it < 10000:
ix = np.argsort(fx)
fx = fx[ix]
simplex = simplex[:, ix]
xo = np.mean(simplex[:, :-1], axis=1)
# Отражение
xr = xo + alpha * (xo - simplex[:, -1])
fxr = f(xr)
if fx[0] <= fxr < fx[-2]:
simplex[:, -1] = xr
fx[-1] = fxr
elif fxr < fx[0]:
xe = xo + gamma * (xr - xo)
if f(xe) < fxr:
simplex[:, -1] = xe
fx[-1] = f(xe)
else:
simplex[:, -1] = xr
fx[-1] = fxr
elif fxr >= fx[-2]:
xc = xo + beta * (simplex[:, -1] - xo)
if f(xc) < fx[-1]:
simplex[:, -1] = xc
fx[-1] = f(xc)
else:
# Редукция
for i in range(1, n+1):
simplex[:, i] = simplex[:, 0] + sigma * (simplex[:, i] - simplex[:, 0])
fx = np.array([f(simplex[:, i]) for i in range(n+1)])
it += 1
ix = np.argmin(fx)
return simplex[:, ix], fx[ix], it
# Начальная точка
x0 = np.array([1.0, 0.0])
# Запуск собственного метода Нелдера-Мида
x_min, f_min, iters = simplex(f, x0, eps=1e-6)
print("="*50)
print("Метод Нелдера-Мида (самостоятельная реализация)")
print(f"Минимум: x = [{x_min[0]:.8f}, {x_min[1]:.8f}]")
print(f"f(x) = {f_min:.10f}")
print(f"Количество итераций: {iters}")
# Проверка через встроенный решатель
res = optim.minimize(f, x0, method='Nelder-Mead', options={'disp': False})
print("\nПроверка через scipy.optimize (method='Nelder-Mead'):")
print(f"x = {res.x}")
print(f"f = {res.fun:.10f}")
print("="*50)