我有一个对cobyla
的函数调用,它不会终止。
我想在给定的orthant中找到一些(多元)多项式的局部最小值。
我可以重现的最小示例如下。
import numpy as np
import scipy.optimize
A = np.array([[ 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 6, 12, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 2, 3, 3, 3, 1, 2],
[ 0, 0, 2, 2, 2, 4, 10, 0, 4, 4, 12, 4, 0, 2, 4, 0, 3, 4, 3, 3, 2, 3, 3, 4, 3, 2, 3, 3, 4, 3],
[ 0, 4, 0, 6, 10, 10, 4, 4, 4, 8, 2, 0, 4, 2, 4, 2, 4, 4, 3, 4, 3, 5, 3, 4, 4, 4, 3, 4, 4, 4],
[ 0, 0, 6, 0, 0, 6, 2, 12, 10, 0, 2, 8, 0, 8, 4, 2, 5, 3, 5, 3, 3, 4, 4, 4, 2, 3, 4, 4, 3, 4]])
b = np.array([ 3.81330727e+00, 1.30927853e+00, 1.89829563e+00, 1.55301205e+00, 2.05509780e+00, 4.72913144e+00, 8.64125139e+00, 6.78452109e+00, 1.97505381e+01, 8.10184002e+00, 8.56817472e+00, 1.76581791e+00, 6.90448362e+00, 8.44460914e-02, 1.52023325e+00, -1.97710183e+00, -1.66933212e-01, -2.71655065e-01, -2.03262146e+00, -6.74143747e-01, -1.53382538e+00, -9.94362458e-01, 1.86147837e-01, -6.23838626e-01, 1.04835921e+00, 3.49272629e-01, -6.47927068e-01, -4.69780766e-01, 1.48099164e-02, 3.61251102e-01])
x0 = np.array([ 3.75422451, -4.13253284, -46.27451838, -29.48396097])
def f(x):
return np.dot(np.prod(np.power(x,A.T),axis = 1),b)
res = scipy.optimize.fmin_cobyla(f, x0, lambda x: x*np.array([1,-1,-1,-1]), disp = 3)
然后,代码的最后一行不会终止。
即使达到最大显示级别,我也不会获得一行输出。
更糟糕的是,Ctrl+C
不会终止IPython
中的计算(我假设代码停留在Fortran
中)。
如何避免这个问题?
答案 0 :(得分:0)
我相信您描述约束的方式存在问题。
我尝试了以下两种形式的代码,并且可以使用:
import numpy as np
import scipy.optimize
A = np.array([[ 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 6, 12, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 2, 3, 3, 3, 1, 2],
[ 0, 0, 2, 2, 2, 4, 10, 0, 4, 4, 12, 4, 0, 2, 4, 0, 3, 4, 3, 3, 2, 3, 3, 4, 3, 2, 3, 3, 4, 3],
[ 0, 4, 0, 6, 10, 10, 4, 4, 4, 8, 2, 0, 4, 2, 4, 2, 4, 4, 3, 4, 3, 5, 3, 4, 4, 4, 3, 4, 4, 4],
[ 0, 0, 6, 0, 0, 6, 2, 12, 10, 0, 2, 8, 0, 8, 4, 2, 5, 3, 5, 3, 3, 4, 4, 4, 2, 3, 4, 4, 3, 4]])
b = np.array([ 3.81330727e+00, 1.30927853e+00, 1.89829563e+00, 1.55301205e+00, 2.05509780e+00, 4.72913144e+00, 8.64125139e+00, \
6.78452109e+00, 1.97505381e+01, 8.10184002e+00, 8.56817472e+00, 1.76581791e+00, 6.90448362e+00, 8.44460914e-02, 1.52023325e+00, \
-1.97710183e+00, -1.66933212e-01, -2.71655065e-01, -2.03262146e+00, -6.74143747e-01, -1.53382538e+00, -9.94362458e-01, 1.86147837e-01, \
-6.23838626e-01, 1.04835921e+00, 3.49272629e-01, -6.47927068e-01, -4.69780766e-01, 1.48099164e-02, 3.61251102e-01])
x0 = np.array([ 3.75422451, -4.13253284, -46.27451838, -29.48396097])
def fun(x):
return np.dot(np.prod(np.power(x,A.T),axis = 1),b)
def constraint_func(x_in):
factor = np.array([1,-1,-1,-1])
constraints_list = []
for i in range(len(x_in)):
constraints_list.append({lambda x: x[i]*factor[i]})
res = scipy.optimize.fmin_cobyla(fun, x0, constraint_func, disp = 3)
使用Scipy库的另一个功能的另一种方法:
import numpy as np
import scipy.optimize
A = np.array([[ 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 6, 12, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 2, 3, 3, 3, 1, 2],
[ 0, 0, 2, 2, 2, 4, 10, 0, 4, 4, 12, 4, 0, 2, 4, 0, 3, 4, 3, 3, 2, 3, 3, 4, 3, 2, 3, 3, 4, 3],
[ 0, 4, 0, 6, 10, 10, 4, 4, 4, 8, 2, 0, 4, 2, 4, 2, 4, 4, 3, 4, 3, 5, 3, 4, 4, 4, 3, 4, 4, 4],
[ 0, 0, 6, 0, 0, 6, 2, 12, 10, 0, 2, 8, 0, 8, 4, 2, 5, 3, 5, 3, 3, 4, 4, 4, 2, 3, 4, 4, 3, 4]])
b = np.array([ 3.81330727e+00, 1.30927853e+00, 1.89829563e+00, 1.55301205e+00, 2.05509780e+00, 4.72913144e+00, 8.64125139e+00, \
6.78452109e+00, 1.97505381e+01, 8.10184002e+00, 8.56817472e+00, 1.76581791e+00, 6.90448362e+00, 8.44460914e-02, 1.52023325e+00, \
-1.97710183e+00, -1.66933212e-01, -2.71655065e-01, -2.03262146e+00, -6.74143747e-01, -1.53382538e+00, -9.94362458e-01, 1.86147837e-01, \
-6.23838626e-01, 1.04835921e+00, 3.49272629e-01, -6.47927068e-01, -4.69780766e-01, 1.48099164e-02, 3.61251102e-01])
x0 = np.array([ 3.75422451, -4.13253284, -46.27451838, -29.48396097])
def fun(x):
return np.dot(np.prod(np.power(x,A.T),axis = 1),b)
def constraint_func(x_in):
factor = np.array([1,-1,-1,-1])
constraints_list = []
for i in range(len(x_in)):
constraints_list.append({'type': 'ineq', 'fun': lambda x: x[i]*factor[i]})
return constraints_list
constraints = constraint_func(x0)
res = scipy.optimize.minimize(fun, x0, method='COBYLA', constraints= constraints)
print(res)