【问题标题】:Peak finding algorithm寻峰算法
【发布时间】:2013-09-26 13:40:59
【问题描述】:

我最近开始看 MIT 的 6.006 课,在第一课中,讲师介绍了寻峰算法。

http://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-006-introduction-to-algorithms-fall-2011/lecture-videos/MIT6_006F11_lec01.pdf

根据他的定义:

给定一个数组 [a,b,c,d,e,f,g] 其中 a-g 是数字,b 是峰值 当且仅当 a = c.

他给出了递归的方法:

if a[n/2] < a[n/2 -1] then look for a peak from a[1] ... a[n/2 -1]
else if a[n/2] < a[n/2+1] then look for a peak from a[n/2+1] ... a[n]
else a[n/2] is a peak

他说算法是T(n) = T(n/2) + o(1) = o(lgn)

在他的pdf中他还给出了一个完整的例子:[6,7,4,3,2,1,4,5]

7 和 5 都是峰值。但是上面的算法不是仅仅因为中间元素恰好满足第一个分支而发现 7 作为峰值吗?

  1. 那么,如果我们要找到所有的峰,我们还会遍历整个阵列吗?这是否意味着最坏的情况N?

  2. 他的定义是否意味着我们只需要找到一个峰值?

我相信这个问题可以看作是在 Riverst 的算法介绍一书中找到最大和最小元素。

【问题讨论】:

    标签: algorithm language-agnostic


    【解决方案1】:

    是的,这个算法只找到一个峰值。

    如果你想找到所有峰,你必须检查所有元素,所以它将是 O(n)。

    注意:峰值不一定是全局最大值。

    【讨论】:

    • 如果我想要一个全局最大值怎么办?
    【解决方案2】:

    这个算法看起来很像binary search algorithm。二进制搜索仅适用于已排序的数组,并且这种峰值搜索算法看起来应该适用于另一个定义:x[p] 是一个峰值,如果 0 &lt;= i &lt; p x[i] &lt;= x[i + 1]p &lt;= i &lt; x.size x[i] &gt;= x[i + 1]。如果我们确定问题中的定义是错误的,而这个定义是正确的:一切都很好。看起来它是错误的,因为它在第二种情况下给出了几个峰值,你是对的。

    【讨论】:

    • 不,原来的定义完全没问题。 peak 是局部最大值
    【解决方案3】:

    我昨天刚开始这个课程,问题陈述是:

    问题:找到一个峰值(如果它存在)(它总是存在吗?)

    因此,算法所做的只是试图在尽可能短的时间内找到一个峰值,即第一个可用的峰值。

    这就是为什么这个算法只能找到一个峰值。

    【讨论】:

      【解决方案4】:

      我不太相信这种算法是否是找到有趣峰的最佳方法。它倾向于在中间元素进行比较,这可能会将搜索推向次优方向,最终算法总是会在边缘而不是中间找到峰值。 简单的例子

      [1,2,3,4,5,6,7,8] => 峰值为 8

      [6,21,7,8,9,10,11,13] => 峰值为 13,而峰值为 21 更有趣

      当然,算法可以保证找到一个峰值,因为它向更高的方向移动,但正如我在示例中显示的那样,这个峰值可能不是有趣的!

      【讨论】:

      • 定义“有趣”
      • 我认为作者的意思是,最有趣的峰是与其邻居有最大差异(可能是平均差异)的峰,即max( a[i] - (a[i-1] - a[i+1]) / 2 )
      【解决方案5】:

      我最近也开始研究这个,这就是我发现的: 如果一维数组元素不小于其相邻元素,则它是一个峰值,对于排序数组,最后一个元素始终是峰值,并且课程中提供的解决方案与使用分治法的二进制搜索的工作原理非常相似,并且问题还说找到一个峰,我们可以有多个峰,但我们需要第一个峰元素,我们就完成了。

      例如我们有长度为 n 的一维数组:

          DO:
          m = n/2
          neigborLeft = m-1
          neigborRight = m+1
          if neigborLeft >= 0 && a[neigborLeft] > a[m] 
             //recursion with left elements
          else if neigborRight <= n-1 && a[neigborRight] > a[m] 
              //recursion with right elements
           else
             // peak value is a[m]
      
      

      阅读更多: geeksforgeeks.org/find-a-peak-in-a-given-array/

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-12-15
        • 1970-01-01
        • 1970-01-01
        • 2020-04-27
        • 2017-02-09
        • 2015-02-10
        • 2018-11-12
        • 1970-01-01
        相关资源
        最近更新 更多