Advertisement
evgeniya_polyntseva

gradient descent

May 20th, 2020
133
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 3.01 KB | None | 0 0
  1. #!/usr/bin/python
  2. # -*- coding: utf-8 -*-
  3. import math
  4. from sympy import *
  5. import sympy as sym
  6.  
  7. x, y, t = sym.symbols('x y t')
  8.  
  9.  
  10.  
  11. def f(x, y):
  12.     #1 функция из учебника РАБОТАЕТ
  13.     return 2 * x ** 2 + x * y + y ** 2
  14.     # 2 функция по варианту
  15.     # return  -(2 / (1 + ((x - 1) / 2) ** 2 + (y - 1) ** 2)) - (3 / (1 + ((x - 2) / 3) ** 2 + ((y - 3) / 2) ** 2))
  16.     # 3 функция из методы min(1,1) РАБОТАЕТ
  17.     # return 100*(y - x) ** 2 + (1 - x) ** 2
  18.     # 4 функция Розенброка min(1,1) НЕ РАБОТАЕТ
  19.     #return 100 * (y - x ** 2) ** 2 + (1 - x) ** 2
  20.  
  21.  
  22. def golden_ratio(func):
  23.     eps = 10 ** (-10)
  24.     a=-1
  25.     b=0
  26.     coef1 = (3 - math.sqrt(5)) / 2
  27.     coef2 = (math.sqrt(5) - 1) / 2
  28.     i = 1
  29.     x1 = a + coef1 * (b - a)
  30.     x2 = a + coef2 * (b - a)
  31.     f1 = func.subs(t, x1)
  32.     f2 = func.subs(t, x2)
  33.     while True:
  34.         if f1 <= f2:
  35.             b = x2
  36.             x2 = x1
  37.             f2=f1
  38.             k = 1
  39.         else:
  40.             a = x1
  41.             x1 = x2
  42.             f1=f2
  43.             k = 2
  44.         if abs(a - b) < eps:
  45.             return (a + b) / 2
  46.         if k == 1:
  47.             x1 = a + coef1 * (b - a)
  48.             f1 = func.subs(t, x1)
  49.         else:
  50.             x2 = a + coef2 * (b - a)
  51.             f2 = func.subs(t, x2)
  52.         i += 1
  53.  
  54.  
  55. def gradient_descent():
  56.     # v-начальная точка
  57.     v = (0, 1)
  58.     eps1 = 10 ** (-10)
  59.     eps2 = 10 ** (-10)
  60.     i = 0
  61.     # нахождение градиента и подстановка v (шаги 4-5)
  62.     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]}))
  63.     norma_grad = (gradient[0] ** 2 + gradient[1] ** 2) ** 0.5
  64.     print("Итерация\tЗначение функции в точке\t\tКоордината x\t\tКоордината y\n")
  65.     while norma_grad > eps1:
  66.         # expand раскрывает скобки
  67.         phi = expand(f(v[0] - gradient[0] * t, v[1] - gradient[1] * t))
  68.         phigrad = (diff(phi, t))
  69.         # условие безусловного экстремума, нахождение t(шаг 6)
  70.         t_res = golden_ratio(phigrad)
  71.         # находим следующее приближение (шаг 7)
  72.         x_next = v[0] - gradient[0] * t_res
  73.         y_next = v[1] - gradient[1]* t_res
  74.         v_next = (x_next, y_next)
  75.         n1 = ((v_next[0] - v[0]) ** 2 + (v_next[1] - v[1]) ** 2) ** 0.5
  76.         n2 = abs(f(v_next[0], v_next[1]) - f(v[0], v[1]))
  77.         if n1 > eps2 and n2 > eps2:
  78.             v=v_next
  79.             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]}))
  80.             norma_grad = (gradient[0] ** 2 + gradient[1] ** 2) ** 0.5
  81.             i = i + 1
  82.             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])
  83.         else:
  84.             print("test")
  85.             break
  86.  
  87.  
  88. gradient_descent()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement