我正在使用scipy的curvefit模块来拟合函数,并想知道是否有办法告诉它唯一可能的条目是整数而不是实数?关于这样做的另一种方式的任何想法? 最佳答案 在一般形式中,整数规划问题是NP难的(见
here).有一些有效的启发式算法或近似算法来解决这个问题,但没有一个能保证一个精确的最优解.
在scipy中,您可以对整数系数实现网格搜索,并使用,例如,curve_fit对给定整数系数的实参数.至于网格搜索. scipy有brute
功能.
例如,如果y = a * x b * x ^ 2 some-noise,其中a必须是整数,这可能有效:
>生成一些a = 5且b = -1.5的测试数据:
coef, n = [5, - 1.5], 50
xs = np.linspace(0, 10, n)[:,np.newaxis]
xs = np.hstack([xs, xs**2])
noise = 2 * np.random.randn(n)
ys = np.dot(xs, coef) + noise
>给定整数系数的函数使用curve_fit方法拟合实系数:
def optfloat(intcoef, xs, ys):
from scipy.optimize import curve_fit
def poly(xs, floatcoef):
return np.dot(xs, [intcoef, floatcoef])
popt, pcov = curve_fit(poly, xs, ys)
errsqr = np.linalg.norm(poly(xs, popt) - ys)
return dict(errsqr=errsqr, floatcoef=popt)
>给定整数系数的函数,使用上述函数优化浮点系数并返回错误:
def errfun(intcoef, *args):
xs, ys = args
return optfloat(intcoef, xs, ys)['errsqr']
>使用scipy.optimize.brute最小化errfun以找到最佳整数系数,并使用优化的整数系数调用optfloat以找到最佳实际系数:
from scipy.optimize import brute
grid = [slice(1, 10, 1)] # grid search over 1, 2, ..., 9
# it is important to specify finish=None in below
intcoef = brute(errfun, grid, args=(xs, ys,), finish=None)
floatcoef = optfloat(intcoef, xs, ys)['floatcoef'][0]
使用这种方法,我得到[5.0,-1.50577]最优系数,这对于整数系数是精确的,并且对于实系数足够接近.