我正在尝试用minimize_scalar来计算一维多项式的最小值和最大值。
多项式为x^{6}-2x^{5}-26x^{4}+28x^{3}+145x^{2}-26x-80
代码如下所示
import numpy as np
from scipy.optimize import *
ppar = np.array([1, -2, -26, 28, 145, -26, -80])
p = np.poly1d(ppar)
print p
maximum = minimize_scalar(-p, bounds=(-3.978, 3.068), method = 'bounded')
print "(-3.978, 3.068)", -maximum.fun
print maximum
minimum = minimize_scalar(p, bounds=(-3.978, 3.068), method = 'bounded')
print "(-3.978, 3.068)", minimum.fun
print minimum结果是
6 5 4 3 2
1 x - 2 x - 26 x + 28 x + 145 x - 26 x - 80
(-3.978, 3.068) 86.0883584933
status: 0
nfev: 12
success: True
fun: -86.0883584932823
x: -1.5444720061831096
message: 'Solution found.'
(-3.978, 3.068) -81.1476243092
status: 0
nfev: 11
success: True
fun: -81.147624309245643
x: 0.08767224353999728
message: 'Solution found.'但是,一维多项式的实际解应该是最大值: x=2.176时为264.155,x= -436.947时为最小值-3.391
有没有人知道我的代码出了什么问题,或者我漏掉了什么?
感谢您的帮助和意见。
发布于 2019-11-26 05:13:53
多项式是振荡的,并且有几个极值。你得到的是完全不同的。请注意,局部最小化程序找到一个最小值,如果有多个最小值,它会报告其中一个。
对于多项式,最好使用专门的最小化函数。例如,使用伴生矩阵方法微分并找到导数的根:
In [53]: coef = [-26, 2*145, 3*28, -4*26, -5*2] # coefficients for the derivative
In [54]: coef = np.asarray(coef, dtype=float)
In [55]: coef /= 6 # make it monic
In [56]: coef
Out[56]: array([ -4.33333333, 48.33333333, 14. , -17.33333333, -1.66666667])
In [57]: a = np.diag(np.ones(4), -1) # build the companion matrix
In [58]: a[:, -1] = -coef伴随矩阵的特征值是导数的根(反之亦然),因此原始多项式的极值:
In [61]: np.linalg.eigvals(a)
Out[61]: array([-3.39056572, -1.54447197, 0.08767236, 2.17555358, 4.33847842])
In [62]: pp = np.poly1d([1, -2, -26, 28, 145, -26, -80]) # sanity check
In [63]: pp(np.linalg.eigvals(a))
Out[63]:
array([-436.94699498, 86.08835849, -81.14762431, 264.15457395,
-794.0522912 ])必须注意的一点是,最好避免高次多项式,因为它们是不稳定的。
发布于 2019-11-26 06:46:06
简单的答案是使用scipy.optimize.minimize_scalar,您可以找到局部最小值。详细信息在@ev-br answer中。但是,您可以使用global optimization方法在给定的范围内查找函数的全局最小值。即使在这种情况下,您也应该准备好这些方法也可能失败,因为在幕后使用了局部最小化程序。在下一个示例中,您可以看到shgo优化器无法找到全局最小值:
import numpy as np
from scipy import optimize
p = np.poly1d([1, -2, -26, 28, 145, -26, -80])
bounds = [(-3.978, 3.068)]
results = {}
results['shgo'] = optimize.shgo(p, bounds)
results['DA'] = optimize.dual_annealing(p, bounds)
results['DE'] = optimize.differential_evolution(p, bounds)
print(results['shgo']['x'], results['DA']['x'], results['DE']['x'])
[0.08767235] [-3.39056566] [-3.39056573]https://stackoverflow.com/questions/59037169
复制相似问题