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


# Программа 2: Градиентный метод с аналитическими частными производными
# Вариант 16
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 grad(x):
    # Частные производные аналитически
    return np.array([2*x[0] + 1.1*x[1] + 1,
                     2*x[1] + 1.1*x[0] - 1])

def gradient_descent(f, grad, x0, alpha=0.2, eps=1e-6, max_iter=10000):
    x = x0.copy()
    f_prev = f(x)
    iterations = 0
    for _ in range(max_iter):
        g = grad(x)
        if np.linalg.norm(g) < eps:
            break
        # Адаптивный шаг: уменьшаем, пока функция не уменьшится
        step_ok = False
        for _ in range(10):
            x_new = x - alpha * g
            f_new = f(x_new)
            if f_new < f_prev:
                x = x_new
                f_prev = f_new
                step_ok = True
                break
            alpha *= 0.5
        if not step_ok:
            break
        iterations += 1
    return x, f(x), iterations

x0 = np.array([1.0, 0.0])
x_min, f_min, iters = gradient_descent(f, grad, x0, alpha=0.2, 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}")

# Проверка через BFGS (встроенный квазиньютоновский метод)
res = optim.minimize(f, x0, method='BFGS', jac=grad, options={'disp': False})
print("\nПроверка через scipy.optimize (method='BFGS'):")
print(f"x = {res.x}")
print(f"f = {res.fun:.10f}")
print("="*50)