Advertisement
evgeniya_polyntseva

nelder

May 25th, 2020
139
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 2.07 KB | None | 0 0
  1. import math
  2. from sympy import *
  3. import sympy as sym
  4. from sympy.abc import *
  5.  
  6. x, y, r = sym.symbols('x y r')
  7.  
  8.  
  9. def nelder_mead(func):
  10.     alpha = 1
  11.     beta = 0.5
  12.     gamma = 2
  13.     i = 3000
  14.     v1 = (0, 1)
  15.     v2 = (1, 0)
  16.     v3 = (1, 1)
  17.  
  18.     for i in range(i):
  19.         a = func.subs({x: v1[0], y: v1[1]})
  20.         b = func.subs({x: v2[0], y: v2[1]})
  21.         c = func.subs({x: v3[0], y: v3[1]})
  22.         adict = {v1: a, v2: b, v3: c}
  23.         points = sorted(adict.items(), key=lambda p: p[0])
  24.         b = points[0][0]
  25.         g = points[1][0]
  26.         w = points[2][0]
  27.         mid = ((g[0] + b[0]) / 2, (g[1] + b[1]) / 2)
  28.  
  29.         # отражение
  30.         xr = (mid[0] + alpha * (mid[0] - w[0]), mid[1] + alpha * (mid[1] - w[1]))
  31.         if func.subs({x: xr[0], y: xr[1]}) < func.subs({x: g[0], y: g[1]}):
  32.             w = xr
  33.         else:
  34.             if func.subs({x: xr[0], y: xr[1]}) < func.subs({x: w[0], y: w[1]}):
  35.                 w = xr
  36.             c = ((w[0] + mid[0]) / 2, (w[1] + mid[1]) / 2)
  37.             if func.subs({x: b[0], y: b[1]}) < func.subs({x: w[0], y: w[1]}):
  38.                 w = c
  39.         if func.subs({x: xr[0], y: xr[1]}) < func.subs({x: b[0], y: b[1]}):
  40.  
  41.             # растяжение
  42.             xe = (mid[0] + gamma * (xr[0] - mid[0]), mid[1] + gamma * (xr[1] - mid[1]))
  43.             if func.subs({x: xe[0], y: xe[1]}) < func.subs({x: xr[0], y: xr[1]}):
  44.                 w = xe
  45.             else:
  46.                 w = xr
  47.         if func.subs({x: xr[0], y: xr[1]}) > func.subs({x: g[0], y: g[1]}):
  48.  
  49.             # сжатие
  50.             xc = (mid[0] + beta * (w[0] - mid[0]), mid[1] + beta * (w[1] - mid[1]))
  51.             if func.subs({x: xc[0], y: xc[1]}) < func.subs({x: w[0], y: w[1]}):
  52.                 w = xc
  53.  
  54.         # переобозначим точки: b = best, g = good, w = worst — соответственно.
  55.         v1 = w
  56.         v2 = g
  57.         v3 = b
  58.         if math.sqrt((((func.subs({x: g[0], y: g[1]}) - func.subs({x: mid[0], y: mid[1]})) ** 2) / 3)) > 10 ** (-10):
  59.             continue
  60.         return b
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement