Python多变量优化:调整数组值使两数组乘积和匹配指定目标值
问题原因排查及修复方案
核心问题
- 第一个问题:目标函数定义错误。
fmin是求传入函数的最小值,你当前返回的是res - tar,这个值可以无限变小(比如三个参数全部取负数且绝对值不断增大,差值就会无限小),完全无法收敛到让乘积和接近目标值的最优解。正确的做法是返回误差的平方或者绝对值,保证函数的最小值恰好出现在误差为0的位置。 - 第二个问题:问题欠定无唯一解。你只有一个约束条件
150a + 200b + 230c = 2,3个变量对应1个方程,存在无限多组合法解。你期望的解是更接近初始猜测值的结果,所以需要在目标函数里加入参数偏离初始值的惩罚项,才能约束解的范围匹配你的预期。
基础修复版(仅保证乘积和匹配目标)
import numpy as np from scipy.optimize import fmin def func2(params): arr2 = [150, 200, 230] res = sum(np.multiply(params, arr2)) tar = 2 # 返回误差平方,最小值为0时刚好匹配目标值 return (res - tar) ** 2 initial_guess = [0.0025, 0.0030, 0.0035] finarr = fmin(func2, initial_guess) print(finarr)
该版本运行后可保证两数组乘积和接近2,但输出的参数可能和你预期的结果存在差异,因为未约束参数的取值范围。
匹配预期结果的修复版
import numpy as np from scipy.optimize import fmin initial_guess = np.array([0.0025, 0.0030, 0.0035]) def func2(params): arr2 = [150, 200, 230] res = sum(np.multiply(params, arr2)) tar = 2 # 目标包含两部分误差:乘积和偏离目标的误差 + 参数偏离初始猜测的误差,权重可根据需求调整 product_error = (res - tar) ** 2 param_error = np.sum((params - initial_guess) ** 2) return product_error + 0.1 * param_error finarr = fmin(func2, initial_guess) print(finarr) # 可运行下方代码验证乘积和是否符合要求 # print(sum(finarr * [150,200,230]))
该版本运行后输出的参数会非常接近你期望的[0.0027, 0.0033, 0.0040],同时两数组乘积和也接近目标值2。
内容的提问来源于stack exchange,提问作者nicktrent
相关产品推荐
相关产品推荐

