假设我在间隔[0,1]
上定义了一个函数f
,该函数是平滑的,并且在某些点开始减少之后增加到某个点a
。我在此间隔上有一个网格x[i]
,例如与步长为dx = 0.01
,我想通过在最坏的情况下做最小数量的评估f
,我想找到哪些点具有最高的价值。我认为我可以做得比穷举搜索更好,应用渐变式方法启发灵感。有任何想法吗?我正在考虑像二元搜索或抛物线方法。在最少的计算次数中查找全局最大值
这是一个二分样法我编码:
def optimize(f, a, b, fa, fb, dx):
if b - a <= dx:
return a if fa > fb else b
else:
m1 = 0.5*(a + b)
m1 = _round(m1, a, dx)
fm1 = fa if m1 == a else f(m1)
m2 = m1 + dx
fm2 = fb if m2 == b else f(m2)
if fm2 >= fm1:
return optimize(f, m2, b, fm2, fb, dx)
else:
return optimize(f, a, m1, fa, fm1, dx)
def _round(x, a, dx, right = False):
return a + dx*(floor((x - a)/dx) + right)
的理念是:找到区间的中间,计算m1
和m2
- 点到右侧和它的左侧。如果方向正在增加,请按照正确的时间间隔进行操作,否则继续向左。每当间隔太小时,只需比较两端的数字。然而,这个算法仍然不使用我计算的点处的导数的强度。
你可能想看看nelder蜂蜜酒或模拟退火 – iedoc
@iedoc:不,这将是一个可怕的矫枉过正,因为这个函数被认为是单峰的。 –
有多少个网格点? –