use*_*925 7 python optimization mathematical-optimization scipy
我试图使用Python的scipy.optimize最大化以下功能.然而,经过大量的尝试,它似乎没有用.该函数和我的代码粘贴在下面.谢谢你的帮助!
问题
Maximize [sum (x_i / y_i)**gamma]**(1/gamma)
subject to the constraint sum x_i = 1; x_i is in the interval (0,1).
Run Code Online (Sandbox Code Playgroud)
x是一个选择变量的向量; y是参数的矢量; gamma是一个参数.在x小号必须总和为1.每个x必须在区间(0,1).
码
def objective_function(x, y):
sum_contributions = 0
gamma = 0.2
for count in xrange(len(x)):
sum_contributions += (x[count] / y[count]) ** gamma
value = math.pow(sum_contributions, 1 / gamma)
return -value
cons = ({'type': 'eq', 'fun': lambda x: np.array([sum(x) - 1])})
y = [0.5, 0.3, 0.2]
initial_x = [0.2, 0.3, 0.5]
opt = minimize(objective_function, initial_x, args=(y,), method='SLSQP',
constraints=cons,bounds=[(0, 1)] * len(x))
Run Code Online (Sandbox Code Playgroud)
有时,数值优化器由于某种原因不起作用。我们可以稍微不同地参数化问题,它就会起作用。(并且可能工作得更快)
例如,对于 的边界(0,1),我们可以有一个变换函数,使得 中的值在(-inf, +inf)变换后最终会变为(0,1)
我们可以用等式约束做类似的技巧。例如,我们可以将维度从 3 减少到 2,因为 中的最后一个元素x必须是1-sum(x)。
如果它仍然不起作用,我们可以切换到不需要导数信息的优化器,例如Nelder Mead.
还有拉格朗日乘子。
In [111]:
def trans_x(x):
x1 = x**2/(1+x**2)
z = np.hstack((x1, 1-sum(x1)))
return z
def F(x, y, gamma = 0.2):
z = trans_x(x)
return -(((z/y)**gamma).sum())**(1./gamma)
In [112]:
opt = minimize(F, np.array([0., 1.]), args=(np.array(y),),
method='Nelder-Mead')
opt
Out[112]:
status: 0
nfev: 96
success: True
fun: -265.27701747828007
x: array([ 0.6463264, 0.7094782])
message: 'Optimization terminated successfully.'
nit: 52
Run Code Online (Sandbox Code Playgroud)
结果是:
In [113]:
trans_x(opt.x)
Out[113]:
array([ 0.29465097, 0.33482303, 0.37052601])
Run Code Online (Sandbox Code Playgroud)
我们可以通过以下方式将其可视化:
In [114]:
x1 = np.linspace(0,1)
y1 = np.linspace(0,1)
X,Y = np.meshgrid(x1,y1)
Z = np.array([F(item, y) for item
in np.vstack((X.ravel(), Y.ravel())).T]).reshape((len(x1), -1), order='F')
Z = np.fliplr(Z)
Z = np.flipud(Z)
plt.contourf(X, Y, Z, 50)
plt.colorbar()
Run Code Online (Sandbox Code Playgroud)