Algorithm C++;

Algorithm C++;,algorithm,max,Algorithm,Max,问题 我有一个计算一维多项式,联合函数的公式。我想找到给定范围内该函数的所有局部极大值 我的方法 我目前的解决方案是,我在范围内的一定数量的点上评估我的函数,然后我通过这些点,记住函数从上升到下降的点。当然,我可以在间隔内更改样本数,但我希望找到样本数尽可能少的所有最大值 问题 你能给我推荐一些有效的算法吗 找到未知函数的所有最大值是困难的。你永远无法确定你找到的最大值实际上只是一个最大值,或者你没有忽略某个最大值 但是,如果对该函数有所了解,您可以尝试利用它。当然,最简单的一个问题是,如果已知

问题

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

我的方法

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

问题


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

找到未知函数的所有最大值是困难的。你永远无法确定你找到的最大值实际上只是一个最大值,或者你没有忽略某个最大值

但是,如果对该函数有所了解,您可以尝试利用它。当然,最简单的一个问题是,如果已知函数是有理的且在等级上有界的。对于五级有理函数,可以从闭合公式推导出所有四个极值,详情见。很可能,您不想实现这一点,但对于线性、平方和立方根,闭合公式是可行的,可以用于找到四次函数的最大值

这只是可能知道的最简单的信息,其他有趣的信息是你是否能给出二阶导数的界。这将允许您在发现强坡度时降低采样密度

您还可以利用您打算如何使用您发现的最大值的信息。它可以为你提供你需要多高精度的线索。知道一个点接近最大值就足够了吗?还是说一个点是平的?如果鞍点被归类为最大值,这真的是个问题吗?或者,如果一个最大的权利旁边的转折点被忽略?允许的误差是多少

如果您不能利用这样的信息,那么您将返回到对函数进行小步采样的过程中,并希望您不要犯太多错误


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

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

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

    • 如果核是统一核,则估计函数将是阶跃函数。
      这种情况需要特殊处理,因为在数学意义上不会有任何极大值。然而,这也让你的工作变得非常简单

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

    • 如果核是Epanechnikov核,则估计函数将是分段二次函数

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

  • 如果内核的级别太高或超越,那么您仍然知道估计所基于的度量,并且您知道内核属性。这允许您推导出一个关于最大值密度的启发式方法

  • 至少,你知道内核的一阶导数和二阶导数

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

    • 在局部核的情况下,在任何点计算估计函数的一阶导数和二阶导数的上界可能更为谨慎

    有了这些信息,应该可以将搜索限制在存在最大值的区域,并避免斜率过采样


如您所见,从函数的知识中可以获得许多有用的信息,您可以利用这些信息发挥自己的优势。

局部极大值位于一阶导数的根中。为了在你的工作时间间隔中分离出这些根,你可以使用Sturm定理,然后进行二分法。理论上(使用精确的算术),它给出了所有的实根

一种等效的方法是用Bezier/Bernstein基表示多项式,并寻找系数符号的变化(赫尔特性)。通过对贝塞尔函数的递归细分,可以有效地实现二分搜索


对于多项式,有几种经典算法可用,例如拉盖尔算法,它们通常也会寻找复数根。

不知道效率,但这很简单:值得注意的是,均匀采样可能会失败,因为极值可以任意接近。谢谢,但有一点问题,我的“公式”来自“核密度估计”,因此它不是典型的分析多项式,而是由原始数据点和给定采样的“函数点”求和而成的。@Michal添加了一些可以从这些知识中获得的信息。我想应该会有帮助。谢谢,我用的是普通(高斯)内核。关于“你知道核的一阶导数和二阶导数”=>“这允许你在任意点计算估计函数的一阶导数和二阶导数”你有高斯核的一阶导数和二阶导数的公式,不是吗?我假设你知道如果
f(x)=a*g(x)+b*h(x)
,那么导数就是
f'(x)=a*g'(x)+b*h'(x)
。因为你的函数是一个加权和,它的导数就是这样计算的。二阶导数也是一样。