如何通过Scipy的minimize函数获取约束条件的取值
解决Scipy minimize获取约束条件取值的问题
我明白你的困扰——想拿到约束条件的最终取值,却不想靠每次迭代打印这种笨办法对吧?这里有两个更优雅的方案,帮你轻松获取constraint2的最终值:
方案1:优化完成后手动计算(推荐)
既然minimize返回的optimizeResult.x就是最优解,我们可以直接用这个最优解代入约束函数计算取值,完全不需要修改迭代过程。
修改后的代码如下:
import numpy as np from scipy.optimize import minimize def f(r,d): # 把约束2的逻辑单独抽成函数,方便复用 def constraint2_fun(e, d): return 1 - np.inner(e, d) constraint1 = { 'type': 'ineq', 'args': (r,), 'fun': lambda e, r: r - calculate_risk(e) } constraint2 = { 'type': 'ineq', 'args': (d,), 'fun': constraint2_fun } optimizeResult = minimize( calculate_excess_profit, (1/portfolio_parameters.shape[0],)*portfolio_parameters.shape[0], method="SLSQP", constraints=(constraint1, constraint2), bounds=get_bounds() ) # 用最优解计算约束2的最终取值 constraint2_final_val = constraint2_fun(optimizeResult.x, d) # 把值附加到结果对象上,方便后续调用 optimizeResult.constraint2_value = constraint2_final_val return optimizeResult
这个方法的优势是简单高效,不会对迭代性能产生任何影响,只在优化结束后做一次计算。
方案2:用可变对象记录迭代过程中的约束值
如果你不仅需要最终值,还想观察迭代过程中约束值的变化,可以用一个可变对象(比如列表)在约束函数里存储每次的计算结果:
import numpy as np from scipy.optimize import minimize def f(r,d): # 用列表存储约束2的所有迭代取值(列表是可变对象,可在函数内部修改) constraint2_values = [] def constraint2_fun(e, d): val = 1 - np.inner(e, d) constraint2_values.append(val) return val constraint1 = { 'type': 'ineq', 'args': (r,), 'fun': lambda e, r: r - calculate_risk(e) } constraint2 = { 'type': 'ineq', 'args': (d,), 'fun': constraint2_fun } optimizeResult = minimize( calculate_excess_profit, (1/portfolio_parameters.shape[0],)*portfolio_parameters.shape[0], method="SLSQP", constraints=(constraint1, constraint2), bounds=get_bounds() ) # 最后一次迭代的取值就是列表的最后一个元素 constraint2_final_val = constraint2_values[-1] optimizeResult.constraint2_value = constraint2_final_val # 可选:把所有迭代值也附加到结果上 optimizeResult.constraint2_history = constraint2_values return optimizeResult
这个方法适合需要调试迭代过程的场景,但如果只需要最终值,方案1会更轻量。
补充说明
Scipy的minimize函数默认不会保存约束函数的计算结果,所以我们需要通过以上两种方式手动获取。两种方案都避免了每次迭代打印的繁琐,而且更符合代码规范。
内容的提问来源于stack exchange,提问作者thijs818
相关产品推荐
相关产品推荐

