Algorithm 在1小时运行中找到最佳8分钟窗口的算法

Algorithm 在1小时运行中找到最佳8分钟窗口的算法,algorithm,Algorithm,一个活动运行一个多小时。我需要得到最好的8分钟窗口,其中一些参数是最大的 例如,每秒测量一个值x。如果我的活动运行一小时,我会得到x的3600个值。我需要找到最佳的连续8分钟时间间隔,其中x值在所有其他时间间隔中最高 如果我捕捉到,比如说,从第0分钟到第8分钟,可能还有另一个时间范围,比如0.4到8.4,在这个时间范围内,它是最大的。粒度为1秒。我们需要考虑每一秒。 请帮我设计一下。是什么阻止了你尝试各种可能性?3600个值并不多。您可以在O(n*m)时间内运行它们,其中n表示数据点数,m表示窗

一个活动运行一个多小时。我需要得到最好的8分钟窗口,其中一些参数是最大的

例如,每秒测量一个值x。如果我的活动运行一小时,我会得到x的3600个值。我需要找到最佳的连续8分钟时间间隔,其中x值在所有其他时间间隔中最高

如果我捕捉到,比如说,从第0分钟到第8分钟,可能还有另一个时间范围,比如0.4到8.4,在这个时间范围内,它是最大的。粒度为1秒。我们需要考虑每一秒。


请帮我设计一下。

是什么阻止了你尝试各种可能性?3600个值并不多。您可以在O(n*m)时间内运行它们,其中n表示数据点数,m表示窗口中的点数

如果你想进行优化,你可以使用滑动窗口在O(n)中进行。将前8分钟内x的所有值以及这8分钟的总数保持在一个队列中。每次你前进一秒钟,你就可以把最早的x值从你的跑步总数中减去。然后将新值x添加到队列中,并将其添加到总数中


但是,这种优化对于问题的规模来说几乎是不必要的。我建议保持简单,除非需要额外的性能。

有许多窗口可以捕获x的峰值——您需要更好地定义您想要的。窗口的最大平均值为x?在所有包含峰值的窗口中,平均值最高的窗口?最低信噪比?包含峰值的第一个窗口?

如下所示:

int[] xs = { 1, 9, 5, 6, 14, 9, 6, 1, 5, 4, 7, 16, 8, 3, 2 };

int bestEndPos = 0;
int bestSum = 0;

int currentSum = 0;
for (int i = 0; i < xs.length; i++) {

    // Add the current number to the sum.
    currentSum += xs[i];

    // Subtract the number falling out behind us.
    if (i >= 8)
        currentSum -= xs[i - 8];

    // Record our new "best-last-index" if we beat our previous record!
    if (currentSum > bestSum) {
        bestEndPos = i;
        bestSum = currentSum;
    }
}

System.out.println("Best interval: " + (bestEndPos - 8 + 1) + "-" + bestEndPos);
System.out.println("Has interval-sum of: " + bestSum);
int[]xs={1,9,5,6,14,9,6,1,5,4,7,16,8,3,2};
int-bestEndPos=0;
int-bestSum=0;
int currentSum=0;
for(int i=0;i=8)
currentSum-=xs[i-8];
//如果我们打破了以前的记录,就记录下我们新的“最新指数”!
如果(当前和>最佳和){
bestEndPos=i;
最佳和=当前和;
}
}
System.out.println(“最佳间隔:”+(bestEndPos-8+1)+“-”+bestEndPos);
System.out.println(“区间和:“+bestSum”);
在哈斯克尔

module BestWindow where

import Data.List (tails, maximumBy, genericTake)
import Data.Ord (comparing)
import System.Random (mkStdGen, random)

type Value = Integer
type Seconds = Integer
type Window = [Seconds]

getVal :: Seconds -> Value
getVal = fst . random . mkStdGen . fromIntegral

winVal :: Window -> Value
winVal = sum . map getVal

bestWindow :: Seconds -> Seconds -> (Value, Window)
bestWindow winTime totTime = maximumBy (comparing fst) valWins
  where
    secs = [0 .. totTime]
    wins = map (genericTake winTime) (tails secs)
    vals = map winVal wins
    valWins = zip vals wins
用法:

bestWindow (8 * 60) (60 * 60) -- gives value of window and list of window seconds

这是最大子序列问题,可以在O(N)中完成。以谷歌为例。

你是说8分钟内所有x的总和应该最大化吗?嗨,非常感谢你的回复。我需要最大平均值为x?的窗口,但窗口重叠。我认为动态编程是一种更好的方法。@user177883-这里不需要动态编程。滑动窗口就足够了,它解决了
O(n)
中的问题。比AraK的代码长一点,但效率更高一点,因为您不需要不断对片段求和,而是保持8分钟片段的总和最新。+1表示教育性;)你能解释一下复杂性吗?它与列表的长度是线性的吗?它与列表的长度是线性的。