Sep-02-2019, 07:39 PM
Hello. I want to solve some optimization problem with Nelder-Mead algorithm. After that I want to port it into VBA.
So I use this code
The right result should be {-5.27607, {Subscript[p, 0] -> 0.937948,
Subscript[p, 1] -> 0.00888233}}
I also used some python chackup which gives right result but with a warning.
So I use this code
class Vector(object): def __init__(self, x, y): """ Create a vector, example: v = Vector(1,2) """ self.x = x self.y = y def __repr__(self): return "({0}, {1})".format(self.x, self.y) def __add__(self, other): x = self.x + other.x y = self.y + other.y return Vector(x, y) def __sub__(self, other): x = self.x - other.x y = self.y - other.y return Vector(x, y) def __rmul__(self, other): x = self.x * other y = self.y * other return Vector(x, y) def __truediv__(self, other): x = self.x / other y = self.y / other return Vector(x, y) def c(self): return (self.x, self.y) # objective function def f(point): p0, p1 = point n=56 d1=10 d2=15 bb=1/0.05 return 1/(2*bb*n*(p0+(n-1)*p1))*p0**-n*(-2*(-100+d2)*p0**2+2*bb*(d2+100*(-1+n))*p0**(2+n)-bb*(-1+n)*n*p0**n*p1* \ (200+(-100+2*d1-d2)*p1)+2*bb*n*p0**(1+n)*(-100+(-d1+d2+100*(-1+n))*p1)) def nelder_mead(alpha=1, beta=0.5, gamma=2, maxiter=50): # initialization v1 = Vector(0.5, 0.5) v2 = Vector(0.99999, 0.00001) v3 = Vector(0.00001, 0.99999) for i in range(maxiter): adict = {v1:f(v1.c()), v2:f(v2.c()), v3:f(v3.c())} points = sorted(adict.items(), key=lambda x: x[1]) b = points[0][0] g = points[1][0] w = points[2][0] mid = (g + b)/2 # reflection xr = mid + alpha * (mid - w) if f(xr.c()) < f(g.c()): w = xr else: if f(xr.c()) < f(w.c()): w = xr c = (w + mid)/2 if f(c.c()) < f(w.c()): w = c if f(xr.c()) < f(b.c()): # expansion xe = mid + gamma * (xr - mid) if f(xe.c()) < f(xr.c()): w = xe else: w = xr if f(xr.c()) > f(g.c()): # contraction xc = mid + beta * (w - mid) if f(xc.c()) < f(w.c()): w = xc # update points v1 = w v2 = g v3 = b return b print("Result of Nelder-Mead algorithm: ") xk = nelder_mead() print("Best poits is: %s"%(xk))and see no mistakes here. but it gives wrong result as (0.9242635409630066, 0.07573645903699333)
The right result should be {-5.27607, {Subscript[p, 0] -> 0.937948,
Subscript[p, 1] -> 0.00888233}}
I also used some python chackup which gives right result but with a warning.
import scipy.optimize as optimize def f2(point): p0, p1 = point n=56 d1=10 d2=15 bb=1/0.05 return 1/(2*bb*n*(p0+(n-1)*p1))*p0**-n*(-2*(-100+d2)*p0**2+2*bb*(d2+100*(-1+n))*p0**(2+n)-bb*(-1+n)*n*p0**n*p1* \ (200+(-100+2*d1-d2)*p1)+2*bb*n*p0**(1+n)*(-100+(-d1+d2+100*(-1+n))*p1)) print(f2((1,1))) initial_guess = [1, 1] bounds = [(0,1),(0,1)] result = optimize.minimize(f2, initial_guess, method='SLSQP', bounds=bounds) if result.success: fitted_params = result.x print(fitted_params) else: raise ValueError(result.message) -------------------------------------------------------------------- Warning (from warnings module): File "C:/Users/Alex/Downloads/1.py", line 8 return 1/(2*bb*n*(p0+(n-1)*p1))*p0**-n*(-2*(-100+d2)*p0**2+2*bb*(d2+100*(-1+n))*p0**(2+n)-bb*(-1+n)*n*p0**n*p1* \ RuntimeWarning: overflow encountered in double_scalars [0.93794678 0.0088846 ]What's wrong with Nelder-Mead code?