Last active
September 8, 2017 04:24
-
-
Save endolith/6f89b1cb0baa98688a5bc49e590ce196 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import numpy as np | |
from numpy import exp, sqrt, pi, cos, sin, e | |
import matplotlib.pyplot as plt | |
from scipy import optimize | |
import warnings | |
warnings.filterwarnings("ignore",".*GUI is implemented.*") | |
from scipy._lib._util import check_random_state | |
from scipy.optimize._basinhopping import AdaptiveStepsize, RandomDisplacement | |
def mishra_bird(x, y): | |
""" | |
This is a constrained problem with two continuous design variables. There | |
is one global optimum and a few local optima. | |
Minimize: | |
f = sin(x1)*exp((1-cos(x2))^2) + cos(x2)*exp((1-sin(x1))^2) + (x1-x2)^2 | |
The function has two global minima at f(x) = −106.764537 located at | |
x = ( 4.70104, 3.15294) | |
x = (−1.58214,−3.13024) | |
""" | |
return (sin(x) * exp((1-cos(y))**2) + | |
cos(y) * exp((1-sin(x))**2) + | |
(x - y)**2) | |
def inside_curve(xy): | |
""" | |
Subject to: | |
g1 = (x1+5)^2 + (x2+5)^2 >= 25 | |
equivalent to | |
(x+5)^2 + (y+5)^2 - 25 >= 0 | |
The optimal points are: | |
f* = -106.764537 at x* = (4.7, 3.15) | |
""" | |
x, y = xy | |
return (x + 5)**2 + (y + 5)**2 - 25 | |
cons = ({'type': 'ineq', 'fun': inside_curve}) | |
""" | |
With a search space: | |
-6 <= x1, x2 <= 6 | |
""" | |
bnds = ((-6, None), (None, 6)) | |
N = 800 | |
func = mishra_bird | |
X, Y = np.mgrid[-15:15:complex(0, N), -15:15:complex(0, N)] | |
stepsize = 13 | |
niter = 2000 | |
x0 = 9, -9 | |
x0 = 0, 0 | |
def func_array(xy): | |
return func(xy[0], xy[1]) | |
Z = func(X, Y) | |
plt.imshow(Z.T, cmap='gray', origin='lower', interpolation='bilinear', | |
extent=[X.min(), X.max(), Y.min(), Y.max()],) | |
plt.axis('image') | |
plt.plot(x0[0], x0[1], '.') | |
plt.tight_layout() | |
def test_plotter(f_new, x_new, f_old, x_old): | |
print(f' AT step ({x_old[0]:.2f}, {x_old[1]:.2f}) -> ' | |
f'({x_new[0]:.2f}, {x_new[1]:.2f})') | |
plt.plot(x_new[0], x_new[1], 'y.') | |
return False # Random sampling around first minimum found | |
rng = check_random_state(None) | |
interval = 50 | |
def step_taking(x): | |
displace = RandomDisplacement(stepsize=stepsize, random_state=rng) | |
stepper = AdaptiveStepsize(displace, interval=interval, verbose=True) | |
x_old = np.copy(x) | |
x_new = stepper(x) | |
print(f' ST step ({x_old[0]:.2f}, {x_old[1]:.2f}) -> ' | |
f'({x_new[0]:.2f}, {x_new[1]:.2f})') | |
# if inside_curve(x_new) >= 0: | |
# plt.plot(x_new[0], x_new[1], '.', color='limegreen') | |
# else: | |
# plt.plot(x_new[0], x_new[1], '.', color='purple') | |
return x_new | |
bnds_x = [X.min(), X.min(), X.max(), X.max(), bnds[0][0], bnds[0][0]] | |
bnds_y = [Y.min(), Y.max(), Y.max(), bnds[1][1], bnds[1][1], Y.min()] | |
plt.fill(bnds_x, bnds_y, color='red', alpha=0.2, linewidth=0) | |
con_circle = plt.Circle((-5, -5), 5, color='blue', alpha=0.3) | |
ax = plt.gca() | |
ax.add_artist(con_circle) | |
minres = optimize.basinhopping(func_array, x0, stepsize=stepsize, disp=True, | |
minimizer_kwargs={ | |
'constraints': cons, | |
'bounds': bnds, | |
}, | |
niter=niter, | |
interval=interval, | |
take_step=step_taking, | |
accept_test=test_plotter, | |
) | |
plt.plot(minres.x[0], minres.x[1], 'r.', markersize=3.5) | |
print('----minres-----\n', minres) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment