我正在寻找一个优化解决方案,它是一个代表 4 个复数元素的 8d 向量,其中每个元素都在最大半径为 1.2 的复数圆内。
目标函数为:
我正在使用该scipy.optimize.basinhopping模块。
import numpy as np
from scipy import optimize
class MyBounds(object):
def __init__(self, xmax=[360, 360, 360, 360, 1.2, 1.2, 1.2, 1.2], xmin=[0, 0, 0, 0, 0, 0, 0, 0] ):
self.xmax = np.array(xmax)
self.xmin = np.array(xmin)
def __call__(self, **kwargs):
x = kwargs["x_new"]
tmax = bool(np.all(x <= self.xmax))
tmin = bool(np.all(x >= self.xmin))
return tmax and tmin
class MyTakeStep(object):
def __init__(self, stepsize=45):
self.stepsize = stepsize
def __call__(self, x):
s = self.stepsize
x[0] += np.random.uniform(0, 1*s)
x[1] += np.random.uniform(0, 2*s)
x[2] += np.random.uniform(0, 3*s)
x[3] += np.random.uniform(0, 4*s)
s = 1
x[4] += np.random.uniform(0, 1*s)
x[5] += np.random.uniform(0, 1*s)
x[6] += np.random.uniform(0, 1*s)
x[7] += np.random.uniform(0, 1*s)
return x
def f(input_list):
polar_form = [rphi for rphi in zip(input_list[4:], input_list[:4])]
x = np.array([z(e[0], e[1]) for e in polar_form])
# objective function componenets
result = abs(2 - np.linalg.norm(x, 2)) + np.linalg.norm(cref-x, 2)
return result
def hopping_solver(min_f, min_x):
minimizer_kwargs = {"method":'Nelder-Mead'}
comb = np.array([0, 0, 0, 0, 0, 0, 0, 0])
# define bounds
mybounds = MyBounds()
mytakestep = MyTakeStep()
optimal_c = optimize.basinhopping(f, x0 = comb, niter=50000, T=45, stepsize=1, minimizer_kwargs=minimizer_kwargs, take_step=None, accept_test=mybounds, callback=None, interval=5000, disp=False, niter_success=None)
min_x, min_f = optimal_c['x'], optimal_c['fun']
print(optimal_c)
return min_x, min_f
min_f = 10**10
min_x = []
min_x, min_f = hopping_solver(min_f, min_x)
我的问题基本上与步骤有关:我的第一个元素是 [0, 360] 中的角度,其他元素在 [0, 1.2] 中。在这里定义一个好的步骤以平衡精度和快速处理之间的合适方法是什么?
我知道此代码不会返回全局最小值。
同样在这里我选择了我的解决方案空间的中心作为,是否有关于如何选择起点的建议?