在动态范围内查找局部最大值

JTo*_*and 17 c# algorithm

在C#中工作,我需要在双精度列表中找到所有本地峰值,并将它们作为另一个列表双精度返回.这看起来很简单,如果我在任何给定的"窗口"值中有一组我正在比较的值,但我需要能够将这个窗口大小实际传递给函数本身.这可能令人困惑,但基本上我需要这样的东西:

public List<double> FindPeaks(List<double> values, double rangeOfPeaks)
Run Code Online (Sandbox Code Playgroud)

如果'rangeOfPeaks'为5,则将'current'值与其每一侧的2个值进行比较,以确定它是否为峰值.如果'rangeOfPeaks'为11,则将当前值与每侧的5个值进行比较.我认为这是一个非常基本的算法,但是,我找不到像这样检测峰值的任何好方法都没有成功.有没有人曾经这样做过?任何帮助都将不胜感激.提前致谢!

小智 8

我建议对Levy的帖子进行一些修改......

1)当指定值IList几乎是直线时,Levy的代码抛出异常.

2)我认为数组中峰的索引是期望的结果.例如,考虑如果我们有两个具有相同双精度的峰值会发生什么?行动.更改为返回指定IList中峰值的索引.

    public static IList<int> FindPeaks(IList<double> values, int rangeOfPeaks)
    {
        List<int> peaks = new List<int>();
        double current;
        IEnumerable<double> range;

        int checksOnEachSide = rangeOfPeaks / 2;
        for (int i = 0; i < values.Count; i++)
        {
            current = values[i];
            range = values;

            if (i > checksOnEachSide)
            {
                range = range.Skip(i - checksOnEachSide);
            }

            range = range.Take(rangeOfPeaks);
            if ((range.Count() > 0) && (current == range.Max()))
            {
                peaks.Add(i);
            }
        }

        return peaks;
    }
Run Code Online (Sandbox Code Playgroud)


Rob*_*evy 7

可能有更有效的方法,但LINQ使这非常简单

    static IList<double> FindPeaks(IList<double> values, int rangeOfPeaks)
    {
        List<double> peaks = new List<double>();

        int checksOnEachSide = rangeOfPeaks / 2;
        for (int i = 0; i < values.Count; i++)
        {
            double current = values[i];
            IEnumerable<double> range = values;
            if( i > checksOnEachSide )
                range = range.Skip(i - checksOnEachSide);
            range = range.Take(rangeOfPeaks);
            if (current == range.Max())
                peaks.Add(current);
        }
        return peaks;
    }
Run Code Online (Sandbox Code Playgroud)