最小化功能

时间:2011-05-04 19:24:38

标签: algorithm math language-agnostic

假设您被赋予单个变量和参数a和b的函数,并被要求查找函数在区间[a,b]上采用的最小值。 (您可以假设参数是双精度的,但在我的应用程序中,我可能需要使用任意精度库。)

一般来说,这是一个难题,因为功能可能很奇怪。这个问题的简单版本是假设它是连续(没有间隙或跳跃)和单峰(有一个独特的最小值;对于左边的函数正在递减,而右边的函数正在递增)。有没有一种好方法可以解决这个问题(但也许并不容易!)?

假设该函数可能难以计算,但存储您计算的答案并不是特别昂贵。 (显然,如果你不必制作巨大的键/值对数组,那就更好了。)

关于在幸运案例中改进算法的好主意的好处(例如:导数存在,函数是平滑/解析,导数可以以封闭形式计算,导数可以在函数时免费计算)评估)。

6 个答案:

答案 0 :(得分:3)

您描述的版本只有一个最小值,很容易解决。

这个想法是这样的。假设我有a < b < cf(b) < f(a)以及f(b) < f(c)的3分。然后,真正的最小值介于ac之间。此外,如果我在区间中的某处选择另一个点d,那么我可以丢弃ad中的一个,并且仍然具有中间的真实最小值的间隔。随着我进行更多迭代,我的近似值将以指数方式快速提高。

我们并没有从这开始。我们从2分开始,ab,并且知道答案在中间某处。以中点为中心。如果f低于终点,我们将讨论上面讨论过的情况。否则它必须低于其中一个端点,并且高于另一个端点。我们可以扔掉更高端的点并重复。

答案 1 :(得分:2)

如果函数很好,即单峰和严格单调(即严格减小到最小值的左边并严格增加到右边),那么你可以通过二分搜索找到最小值:

  • 设置x = (b-a)/2
  • 测试x是否在最小值或左侧
  • 的右侧
  • 如果x剩下最小值:b = x
  • 如果x符合最低要求:a = x
  • 从开始重复直到你感到无聊
  • 最低值为x

要测试x是否为最小值的左/右,请创建一个小值epsilon并检查f(x - epsilon) < f(x + epsilon)是否为delta。如果是,则最小值在左侧,否则在右侧。 “直到你感到无聊”,我的意思是:发明另一个小值fabs(f(x - epsilon) - f(x + epsilon)) < delta并在{{1}}时停止。


请注意,在一般情况下,您对函数f的行为一无所知,因此无法确定f的非平凡属性。好吧,除非你愿意尝试所有可能的输入。有关详细信息,请参阅http://en.wikipedia.org/wiki/Rice%27s_theorem处的Rice定理(因此,我们不会将此识别为URL)。

答案 2 :(得分:1)

Boost项目的Brent's algorithm实现可能很有用。 它似乎假设函数是连续的,并且在输入间隔中没有最大值(仅最小值)。

答案 3 :(得分:1)

不是直接答案,而是指向更多阅读的指针:

对于函数可微分两次的特殊情况(并且可以轻松计算两个导数),可以使用Newton's method for optimization,即基本上找到一阶导数的根(这是一个必要条件)最小值)。

关于一般情况,请注意“怪异”的极端情况是continuous nowhere的函数,并且如果不是不可能找到最小值(在有限时间内)是非常困难的。所以我想你应该尝试至少对你试图最小化的函数做出一些假设。

答案 4 :(得分:1)

您想要的是优化Unimodal function。正确的算法类似于btilly,但你需要额外的点。

Take 4 points a < b < c < d.
We want to minimize f in [a,d].

If f(b) < f(c) we know the minimum is in [a, c]
If f(b) > f(c) "  "    "   "       is in [b, d]

这可以给出一个算法本身,但是有一个很好的trick涉及黄金比例,它允许你重用中间值(在某种程度上你只需要每次迭代计算一次f而不是两次)

答案 5 :(得分:0)

如果您有该函数的表达式,则存在基于区间分析的全局优化算法。