最小化约束的不可迭代错误来自 scipy.optimize
Not iterable Error with constraints in minimize from scipy.optimize
我刚开始研究 Python 的优化,我遇到了一个问题。
我有一个问题,我想使用从 scipy.optimize 最小化来最小化我的 objective 函数 (obj_fun)。
我将分享一个例子:
import numpy as np
def analysis(A):
N = []
for i in A:
N.append(i*3)
return N
def cons(A):
N = analysis(A)
C = []
for i in len(N):
if N[i] < 2:
C.append({'type': 'ineq', 'fun': lambda x: x[0]*N[i]})
else:
C.append({'type': 'ineq', 'fun': lambda x: x[0]-N[i]})
return C
def obj_fun(A):
"""Objective function returns the weight of the structure"""
w= 0.5*[1*A[0]+2*A[1]+3*A[2]]
return w
# Initial values
A0 = np.array([0.001 for i in range(0, 3)])
N = analysis(A0)
## Optimization
bnds = [(1e-6, None) for i in range(len(A0))]
from scipy.optimize import minimize
sol = minimize(obj_fun, x0=A0, method='trust-constr', bounds=bnds,
constraints=cons)
print(sol)
我得到的整个错误是:
运行文件('C:/Users/Myc/Documents/Python Scripts/example stack.py',wdir='C:/Users/Myc/Documents/Python Scripts')
回溯(最近调用最后):
文件“C:\Users\Myc\Documents\PythonScripts\examplestack.py”,第 40 行,在
溶胶=最小化(obj_fun,x0=A0,方法='trust-constr',边界=bnds,约束=cons)
文件“C:\Users\Myc\anaconda3\lib\site-packages\scipy\optimize_minimize.py”,第 605 行,最小化
constraints = standardize_constraints(constraints, x0, meth)
文件“C:\Users\Myc\anaconda3\lib\site-packages\scipy\optimize_minimize.py”,第 825 行,在 standardize_constraints
constraints = list(constraints) # 确保它是一个可变序列
类型错误:'function'对象不可迭代
我知道主要问题是我如何定义约束,如果我在优化之前定义 Cons1 = rest(A0),我可以将 constraints=cons 替换为 constraints = Cons1。
然而,这对我没有帮助,因为我需要在优化的每次迭代中执行函数 trus_analysis 以更新限制的参数 N。
如何定义约束?
原剧本:
def obj_fun(A):
return 7*A[0]+ 3*A[1]+ 7*A[2]
def analysis(A):
N = []
for i in A:
N.append(i*3)
return N
def cons(A):
n = analysis(A)
C = []
for i in range(len(A)):
if n[i] < 4:
C.append({'type': 'ineq', 'fun': lambda x: x[i]**2 / n[i]})
else:
C.append({'type': 'ineq', 'fun': lambda x: x[i] - n[i]})
return C
A0 = [1,2,3]
C = cons(A0)
bnds = [(1e-6, None) for i in range(len(A0))]
from scipy.optimize import minimize
sol = minimize(obj_fun, x0=A0, method='trust-constr', bounds=bnds, constraints=C)
print(sol)
运行:
/usr/local/lib/python3.8/dist-packages/scipy/optimize/_hessian_update_strategy.py:182: UserWarning: delta_grad == 0.0. Check if the approximated function is linear. If the function is linear better results can be obtained by defining the Hessian as zero instead of using quasi-Newton approximations.
warn('delta_grad == 0.0. Check if the approximated '
barrier_parameter: 0.00016000000000000007
barrier_tolerance: 0.00016000000000000007
cg_niter: 15
cg_stop_cond: 1
constr: [array([9.00009143]), array([4.57149698e-05]), array([4.57149698e-05]), array([2.38571416e-05, 5.43334162e-05, 9.00004571e+00])]
constr_nfev: [40, 40, 40, 0]
constr_nhev: [0, 0, 0, 0]
constr_njev: [0, 0, 0, 0]
constr_penalty: 1.0
constr_violation: 0.0
execution_time: 0.0873115062713623
fun: 63.00065000502843
grad: array([7. , 3. , 6.99999999])
jac: [array([[0. , 0. , 2.00001017]]), array([[0., 0., 1.]]), array([[0., 0., 1.]]), array([[1., 0., 0.],
[0., 1., 0.],
[0., 0., 1.]])]
lagrangian_grad: array([1.77635684e-15, 1.55431223e-14, 5.67948534e-14])
message: '`gtol` termination condition is satisfied.'
method: 'tr_interior_point'
nfev: 40
nhev: 0
nit: 14
niter: 14
njev: 10
optimality: 5.679485337974424e-14
status: 1
success: True
tr_radius: 18734.614693588483
v: [array([-1.77775972e-05]), array([-3.49997333]), array([-3.49997333]), array([-7.00000000e+00, -3.00000000e+00, -1.77776895e-05])]
x: array([2.38571416e-05, 5.43334162e-05, 9.00004571e+00])
这里
In [36]: C
Out[36]:
[{'type': 'ineq', 'fun': <function __main__.cons.<locals>.<lambda>(x)>},
{'type': 'ineq', 'fun': <function __main__.cons.<locals>.<lambda>(x)>},
{'type': 'ineq', 'fun': <function __main__.cons.<locals>.<lambda>(x)>}]
A0
用于创建 3 个约束函数。
analysis
函数只是将 A
乘以 3。
In [38]: analysis(A0)
Out[38]: [3, 6, 9]
In [39]: A0
Out[39]: [1, 2, 3]
In [40]: analysis(A0)
Out[40]: [3, 6, 9]
In [41]: np.array(A0)*3
Out[41]: array([3, 6, 9])
在最新的 cons
中,您删除了 range
,直接使用 cons
而不是 cons(A0)
。 constraints
参数应该是 dict
的 list,如 C
.
所示
我刚开始研究 Python 的优化,我遇到了一个问题。 我有一个问题,我想使用从 scipy.optimize 最小化来最小化我的 objective 函数 (obj_fun)。 我将分享一个例子:
import numpy as np
def analysis(A):
N = []
for i in A:
N.append(i*3)
return N
def cons(A):
N = analysis(A)
C = []
for i in len(N):
if N[i] < 2:
C.append({'type': 'ineq', 'fun': lambda x: x[0]*N[i]})
else:
C.append({'type': 'ineq', 'fun': lambda x: x[0]-N[i]})
return C
def obj_fun(A):
"""Objective function returns the weight of the structure"""
w= 0.5*[1*A[0]+2*A[1]+3*A[2]]
return w
# Initial values
A0 = np.array([0.001 for i in range(0, 3)])
N = analysis(A0)
## Optimization
bnds = [(1e-6, None) for i in range(len(A0))]
from scipy.optimize import minimize
sol = minimize(obj_fun, x0=A0, method='trust-constr', bounds=bnds,
constraints=cons)
print(sol)
我得到的整个错误是: 运行文件('C:/Users/Myc/Documents/Python Scripts/example stack.py',wdir='C:/Users/Myc/Documents/Python Scripts') 回溯(最近调用最后):
文件“C:\Users\Myc\Documents\PythonScripts\examplestack.py”,第 40 行,在 溶胶=最小化(obj_fun,x0=A0,方法='trust-constr',边界=bnds,约束=cons)
文件“C:\Users\Myc\anaconda3\lib\site-packages\scipy\optimize_minimize.py”,第 605 行,最小化 constraints = standardize_constraints(constraints, x0, meth)
文件“C:\Users\Myc\anaconda3\lib\site-packages\scipy\optimize_minimize.py”,第 825 行,在 standardize_constraints constraints = list(constraints) # 确保它是一个可变序列
类型错误:'function'对象不可迭代
我知道主要问题是我如何定义约束,如果我在优化之前定义 Cons1 = rest(A0),我可以将 constraints=cons 替换为 constraints = Cons1。 然而,这对我没有帮助,因为我需要在优化的每次迭代中执行函数 trus_analysis 以更新限制的参数 N。 如何定义约束?
原剧本:
def obj_fun(A):
return 7*A[0]+ 3*A[1]+ 7*A[2]
def analysis(A):
N = []
for i in A:
N.append(i*3)
return N
def cons(A):
n = analysis(A)
C = []
for i in range(len(A)):
if n[i] < 4:
C.append({'type': 'ineq', 'fun': lambda x: x[i]**2 / n[i]})
else:
C.append({'type': 'ineq', 'fun': lambda x: x[i] - n[i]})
return C
A0 = [1,2,3]
C = cons(A0)
bnds = [(1e-6, None) for i in range(len(A0))]
from scipy.optimize import minimize
sol = minimize(obj_fun, x0=A0, method='trust-constr', bounds=bnds, constraints=C)
print(sol)
运行:
/usr/local/lib/python3.8/dist-packages/scipy/optimize/_hessian_update_strategy.py:182: UserWarning: delta_grad == 0.0. Check if the approximated function is linear. If the function is linear better results can be obtained by defining the Hessian as zero instead of using quasi-Newton approximations.
warn('delta_grad == 0.0. Check if the approximated '
barrier_parameter: 0.00016000000000000007
barrier_tolerance: 0.00016000000000000007
cg_niter: 15
cg_stop_cond: 1
constr: [array([9.00009143]), array([4.57149698e-05]), array([4.57149698e-05]), array([2.38571416e-05, 5.43334162e-05, 9.00004571e+00])]
constr_nfev: [40, 40, 40, 0]
constr_nhev: [0, 0, 0, 0]
constr_njev: [0, 0, 0, 0]
constr_penalty: 1.0
constr_violation: 0.0
execution_time: 0.0873115062713623
fun: 63.00065000502843
grad: array([7. , 3. , 6.99999999])
jac: [array([[0. , 0. , 2.00001017]]), array([[0., 0., 1.]]), array([[0., 0., 1.]]), array([[1., 0., 0.],
[0., 1., 0.],
[0., 0., 1.]])]
lagrangian_grad: array([1.77635684e-15, 1.55431223e-14, 5.67948534e-14])
message: '`gtol` termination condition is satisfied.'
method: 'tr_interior_point'
nfev: 40
nhev: 0
nit: 14
niter: 14
njev: 10
optimality: 5.679485337974424e-14
status: 1
success: True
tr_radius: 18734.614693588483
v: [array([-1.77775972e-05]), array([-3.49997333]), array([-3.49997333]), array([-7.00000000e+00, -3.00000000e+00, -1.77776895e-05])]
x: array([2.38571416e-05, 5.43334162e-05, 9.00004571e+00])
这里
In [36]: C
Out[36]:
[{'type': 'ineq', 'fun': <function __main__.cons.<locals>.<lambda>(x)>},
{'type': 'ineq', 'fun': <function __main__.cons.<locals>.<lambda>(x)>},
{'type': 'ineq', 'fun': <function __main__.cons.<locals>.<lambda>(x)>}]
A0
用于创建 3 个约束函数。
analysis
函数只是将 A
乘以 3。
In [38]: analysis(A0)
Out[38]: [3, 6, 9]
In [39]: A0
Out[39]: [1, 2, 3]
In [40]: analysis(A0)
Out[40]: [3, 6, 9]
In [41]: np.array(A0)*3
Out[41]: array([3, 6, 9])
在最新的 cons
中,您删除了 range
,直接使用 cons
而不是 cons(A0)
。 constraints
参数应该是 dict
的 list,如 C
.