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


# Программа 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)