快速查找C ++中的所有本地最大值

时间:2014-06-30 16:19:12

标签: algorithm max

问题

我有一个计算一维多项式,关节函数的公式。我想在给定范围内找到该函数的所有局部最大值。

我的方法

我目前的解决方案是,我在范围内的一定数量的点上评估我的功能,然后我通过这些点并记住功能从上升到下降的点。因为我可以在间隔内更改样本数量,但我希望找到尽可能少的样本数量的所有最大值。

问题

你能为我推荐一些有效的算法吗?

2 个答案:

答案 0 :(得分:3)

查找未知函数的所有最大值很难。你永远无法确定你找到的最大值是否只是一个最大值,或者你没有忽略某个地方的最大值。

但是,如果对该功能有所了解,您可以尝试利用它。当然,最简单的是,如果已知函数是合理的并且在等级上有界限。达到五年级的合理函数,可以从封闭的公式中推导出所有四个极值,有关详细信息,请参阅http://en.wikipedia.org/wiki/Quartic_equation#General_formula_for_roots。最有可能的是,您不希望实现它,但对于线性,方形和立方根,闭合公式是可行的,可用于查找四次函数的最大值。

这只是可能知道的最简单的信息,其他有趣的信息是你是否可以给出二阶导数的约束。这样可以在发现强斜率时降低采样密度。

您也可以利用您打算如何使用所找到的最大值的信息。它可以为您提供有关您需要多少精度的线索。知道一个点接近最大值是否足够?或者说一点是平的?如果将鞍点归类为最大值,这真的是一个问题吗?或者如果忽略转折点旁边的最大值?允许的误差范围是多少?

如果你不能利用这样的信息,你会被抛回到小步骤中对你的功能进行采样,并希望你不要犯太多错误。


编辑:
您在评论中提到您的函数实际上是内核密度估计。这至少为您提供以下信息:

  • 除非内核不受扩展限制,否则您的估计函数将是一个分段函数:它上的任何点只会受到精确计算的测量点数的影响。

  • 如果内核基于有理函数,则得到的估计函数将是分段有理的。它将与内核具有相同的等级!

    • 如果内核是统一内核,那么您的估计函数将是一个阶梯函数 这种情况需要特殊处理,因为在数学意义上不会有任何最大值。但是,它也使你的工作变得非常简单。

    • 如果内核是三角形内核,则估计的函数将是分段线性函数。

    • 如果内核是Epanechnikov内核,你的估计函数将是一个分段二次函数。

    在所有这些情况下,生成分段函数并找到它们的最大值几乎是微不足道的。

  • 如果内核具有过高的等级或超越性,您仍然知道您的估计所依据的度量,并且您知道内核属性。这使您可以获得有关最大值可以达到的密度的启发式算法。

  • 至少,你知道内核的第一个和第二个派生。

    • 原则上,这允许您计算任意点估计函数的一阶和二阶导数。

    • 在本地内核的情况下,在任何时候计算一阶导数和估计函数的二阶导数的上限可能更为谨慎。

    根据这些信息,应该可以将搜索限制在有最大值的区域,并避免对斜坡进行过采样。

如您所见,您可以从您的功能知识中获得许多有用的信息,以及您可以利用哪些信息。

答案 1 :(得分:0)

局部最大值是一阶导数的根。要在工作区间中隔离这些根,您可以使用Sturm定理,然后进行二分法。理论上(使用精确算术)它可以为你提供真正的根源。

等效方法是在Bezier / Bernstein基础上表达多项式,并寻找系数符号的变化(船体属性)。通过Bezier的递归细分可以有效地实现二分法搜索。

有多种经典算法可用于多项式,例如Laguerre,它通常也会寻找复杂的根。