import math
# =========================
# ЦЕЛЕВАЯ ФУНКЦИЯ
# =========================
def f(x1, x2):
return 2 * (x1 - 4) ** 2 + (x2 - 6) ** 2
# =========================
# ГРАДИЕНТ ФУНКЦИИ
# =========================
def grad(x1, x2):
df_dx1 = 4 * (x1 - 4)
df_dx2 = 2 * (x2 - 6)
return df_dx1, df_dx2
# =========================
# МЕТОД С ПОСТОЯННЫМ ШАГОМ
# =========================
def gradient_const_alpha():
print("\n==============================")
print("ГРАДИЕНТНЫЙ СПУСК (alpha = const)")
print("==============================\n")
# Начальная точка
x1 = 7
x2 = 7
# Постоянный шаг
alpha = 0.1
# Точность
eps = 0.01
# Максимум итераций
max_iter = 100
for k in range(max_iter):
g1, g2 = grad(x1, x2)
grad_norm = math.sqrt(g1**2 + g2**2)
print(f"Итерация {k}")
print(f"x = ({x1:.6f}, {x2:.6f})")
print(f"grad = ({g1:.6f}, {g2:.6f})")
print(f"|grad| = {grad_norm:.6f}")
print(f"f(x) = {f(x1, x2):.6f}")
print()
# Критерий остановки
if grad_norm < eps:
break
# Формула метода
x1 = x1 - alpha * g1
x2 = x2 - alpha * g2
print("Минимум найден:")
print(f"x* = ({x1:.6f}, {x2:.6f})")
print(f"f(x*) = {f(x1, x2):.6f}")
# =========================
# МЕТОД АРМИХО
# =========================
def gradient_armijo():
print("\n==============================")
print("ГРАДИЕНТНЫЙ СПУСК (Армихо)")
print("==============================\n")
# Начальная точка
x1 = 7
x2 = 7
# Параметры Армихо
alpha_max = 1.0
rho = 0.5
c = 0.5
# Точность
eps = 0.01
# Максимум итераций
max_iter = 100
for k in range(max_iter):
g1, g2 = grad(x1, x2)
grad_norm = math.sqrt(g1**2 + g2**2)
print(f"Итерация {k}")
print(f"x = ({x1:.6f}, {x2:.6f})")
print(f"grad = ({g1:.6f}, {g2:.6f})")
print(f"|grad| = {grad_norm:.6f}")
print(f"f(x) = {f(x1, x2):.6f}")
# Критерий остановки
if grad_norm < eps:
break
# Начальное значение alpha
alpha = alpha_max
# Подбор alpha по правилу Армихо
while True:
new_x1 = x1 - alpha * g1
new_x2 = x2 - alpha * g2
left = f(new_x1, new_x2)
right = f(x1, x2) - c * alpha * (g1**2 + g2**2)
# Проверка условия Армихо
if left <= right:
break
alpha = alpha * rho
print(f"Подобранный alpha = {alpha:.6f}\n")
# Переход к новой точке
x1 = new_x1
x2 = new_x2
print("Минимум найден:")
print(f"x* = ({x1:.6f}, {x2:.6f})")
print(f"f(x*) = {f(x1, x2):.6f}")
# =========================
# ЗАПУСК ОБОИХ МЕТОДОВ
# =========================
gradient_const_alpha()
gradient_armijo()