Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/python
- # -*- coding: utf-8 -*-
- import math
- from sympy import *
- import sympy as sym
- x, y, t = sym.symbols('x y t')
- def f(x, y):
- #1 функция из учебника РАБОТАЕТ
- return 2 * x ** 2 + x * y + y ** 2
- # 2 функция по варианту
- # return -(2 / (1 + ((x - 1) / 2) ** 2 + (y - 1) ** 2)) - (3 / (1 + ((x - 2) / 3) ** 2 + ((y - 3) / 2) ** 2))
- # 3 функция из методы min(1,1) РАБОТАЕТ
- # return 100*(y - x) ** 2 + (1 - x) ** 2
- # 4 функция Розенброка min(1,1) НЕ РАБОТАЕТ
- #return 100 * (y - x ** 2) ** 2 + (1 - x) ** 2
- def golden_ratio(func):
- eps = 10 ** (-10)
- a=-1
- b=0
- coef1 = (3 - math.sqrt(5)) / 2
- coef2 = (math.sqrt(5) - 1) / 2
- i = 1
- x1 = a + coef1 * (b - a)
- x2 = a + coef2 * (b - a)
- f1 = func.subs(t, x1)
- f2 = func.subs(t, x2)
- while True:
- if f1 <= f2:
- b = x2
- x2 = x1
- f2=f1
- k = 1
- else:
- a = x1
- x1 = x2
- f1=f2
- k = 2
- if abs(a - b) < eps:
- return (a + b) / 2
- if k == 1:
- x1 = a + coef1 * (b - a)
- f1 = func.subs(t, x1)
- else:
- x2 = a + coef2 * (b - a)
- f2 = func.subs(t, x2)
- i += 1
- def gradient_descent():
- # v-начальная точка
- v = (0, 1)
- eps1 = 10 ** (-10)
- eps2 = 10 ** (-10)
- i = 0
- # нахождение градиента и подстановка v (шаги 4-5)
- gradient = ((diff(f(x, y), x)).subs({x: v[0], y: v[1]}), (diff(f(x, y), y)).subs({x: v[0], y: v[1]}))
- norma_grad = (gradient[0] ** 2 + gradient[1] ** 2) ** 0.5
- print("Итерация\tЗначение функции в точке\t\tКоордината x\t\tКоордината y\n")
- while norma_grad > eps1:
- # expand раскрывает скобки
- phi = expand(f(v[0] - gradient[0] * t, v[1] - gradient[1] * t))
- phigrad = (diff(phi, t))
- # условие безусловного экстремума, нахождение t(шаг 6)
- t_res = golden_ratio(phigrad)
- # находим следующее приближение (шаг 7)
- x_next = v[0] - gradient[0] * t_res
- y_next = v[1] - gradient[1]* t_res
- v_next = (x_next, y_next)
- n1 = ((v_next[0] - v[0]) ** 2 + (v_next[1] - v[1]) ** 2) ** 0.5
- n2 = abs(f(v_next[0], v_next[1]) - f(v[0], v[1]))
- if n1 > eps2 and n2 > eps2:
- v=v_next
- gradient = ((diff(f(x, y), x)).subs({x: v[0], y: v[1]}), (diff(f(x, y), y)).subs({x: v[0], y: v[1]}))
- norma_grad = (gradient[0] ** 2 + gradient[1] ** 2) ** 0.5
- i = i + 1
- print(i, '\t\t\t', "%.12f" % f(v_next[0], v_next[1]), '\t\t\t\t', "%.12f" % v_next[0], '\t' "%.12f" % v_next[1])
- else:
- print("test")
- break
- gradient_descent()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement