如何在trust-constr求解器中仅使用线性不等式约束c(x)>0?
在trust-constr中配置
c(x) > 0的不等式约束 步骤1:封装约束计算逻辑
把你提供的插值计算逻辑封装成求解器可调用的函数,输入为优化变量x(对应你的input_val),输出为约束值cons = g(x, teta) - ymin:
def constraint_func(x, pressure_cons_val, interpolation_file): # x对应input_val = (BHP, GOR, WC, GLR, LR) interpol = interpolation_file.do_interpolation(0) res = interpol(x) # 计算g(x,teta) return res - pressure_cons_val # 返回c(x)
步骤2:定义trust-constr兼容的约束对象
trust-constr优先推荐使用NonlinearConstraint适配插值逻辑(绝大多数插值都是非线性的)。约束c(x) > 0在数值优化中通常用极小下界替代严格大于0,避免边界数值问题:
from scipy.optimize import NonlinearConstraint import numpy as np # 传入已知的ymin和插值文件对象 nonlinear_cons = NonlinearConstraint( fun=lambda x: constraint_func(x, pressure_cons_val, self.file), lb=1e-8, # 用极小值替代严格大于0 ub=np.inf )
如果你的插值是严格线性关系(比如线性插值且变量与结果呈线性映射),可以用LinearConstraint,但需提前推导线性系数矩阵A和常数项b0(满足g(x,teta) = A @ x + b0):
from scipy.optimize import LinearConstraint # 推导得到线性关系后,构造约束A@x + (b0 - pressure_cons_val) > 0 linear_cons = LinearConstraint( A=A, # 线性系数矩阵 lb=1e-8 - (b0 - pressure_cons_val), ub=np.inf )
步骤3:调用trust-constr求解器
将约束传入求解器,同时定义目标函数和初始猜测值:
from scipy.optimize import minimize # 定义你的目标函数(根据实际优化需求修改) def objective_func(x): # 示例:最小化变量的平方和 return sum(x**2) # 初始猜测值,对应input_val的初始参数 x0 = [初始BHP, 初始GOR, 初始WC, 初始GLR, 初始LR] # 执行优化 result = minimize( objective_func, x0, method='trust-constr', constraints=[nonlinear_cons] # 线性约束则传linear_cons ) # 输出结果 print("优化后参数:", result.x) print("约束满足值:", constraint_func(result.x, pressure_cons_val, self.file))
关键注意事项
- 严格大于0的约束不能直接设
lb=0,会导致求解器在边界处出现数值不稳定,用1e-8这类极小值替代更稳妥。 - 确保插值函数返回标量值,若需要多约束,需调整函数返回数组并对应设置
lb/ub数组。 - 如果仅优化
input_val中的部分参数,需在constraint_func中做好变量映射,保证插值输入正确。
内容的提问来源于stack exchange,提问作者Sogol27
相关产品推荐
相关产品推荐

