如何在SciPy的least_squares函数中约束系数为整数?
解决SciPy least_squares整数约束问题的方案
1. 你的约束函数无法直接融入least_squares流程
least_squares是针对连续参数的非线性最小二乘优化器,仅支持连续边界约束,不接受返回布尔值的整数校验约束。它的优化过程中参数始终是连续浮点数,不会主动满足整数要求,因此你写的constraint函数无法被该函数识别或应用。
2. 可行解决方案
方案一:暴力枚举(适合整数范围小的场景)
如果你的整数系数范围有限(比如你例子中的1-4),直接枚举所有可能的整数值,对每个整数固定后调用least_squares优化剩余参数,最后选择目标函数值最小的结果即可。
示例代码:
from scipy.optimize import least_squares def objective_function(params, target): # 你的残差计算逻辑,返回残差数组 coeff = params[0] other_params = params[1:] # ... 计算残差并返回 ... # 目标数据 target = ... # 枚举所有可能的整数系数 coeff_candidates = range(1, 5) # 对应1-4的整数 best_cost = float('inf') best_params = None for coeff in coeff_candidates: # 固定整数系数,设置初始猜测(示例包含2个其他参数) initial_guess = [coeff, 1.0, 0.5] # 设置边界:固定coeff的上下界为自身,其他参数按需设置 bounds = ([coeff, -10, -10], [coeff, 10, 10]) # 执行优化 result = least_squares(objective_function, initial_guess, bounds=bounds, args=(target,)) # 比较残差平方和(result.cost是残差平方和的一半) if result.cost < best_cost: best_cost = result.cost best_params = result.x print("最优参数:", best_params) print("最小残差平方和:", best_cost * 2)
方案二:使用支持整数约束的SciPy优化器(适合整数范围大的场景)
如果整数系数范围较大,枚举效率太低,可以使用scipy.optimize.differential_evolution——它支持通过integers参数指定哪些参数必须为整数,且能处理非线性目标函数。
注意:differential_evolution要求目标函数返回标量值(而非残差数组),因此需要对原目标函数做简单包装。
示例代码:
from scipy.optimize import differential_evolution def objective_function(params, target): # 原残差计算逻辑,返回残差数组 coeff = params[0] other_params = params[1:] # ... 计算残差并返回 ... # 包装目标函数,返回残差平方和(标量) def scalar_obj_func(params, target): residuals = objective_function(params, target) return sum(residuals ** 2) # 目标数据 target = ... # 参数边界:coeff在1-4之间,其他参数示例为-10到10 bounds = [(1, 4), (-10, 10), (-10, 10)] # 指定第0个参数为整数 result = differential_evolution(scalar_obj_func, bounds, args=(target,), integers=[0]) print("最优参数:", result.x) print("最小残差平方和:", result.fun)
方案三:混合整数线性规划(仅适用于线性场景)
如果你的目标函数和约束都是线性的,可以使用scipy.optimize.milp(混合整数线性规划器),但该工具对非线性问题不适用,需根据你的实际场景判断。
内容的提问来源于stack exchange,提问作者IssacJay
相关产品推荐
相关产品推荐

