Javascript 增长阵列的内存高效下采样(图表)

Javascript 增长阵列的内存高效下采样(图表),javascript,algorithm,memory,charts,sampling,Javascript,Algorithm,Memory,Charts,Sampling,我的一个节点进程每半秒接收一个样本点,我想更新我接收的所有样本点的历史图表。 图表应该是一个数组,其中包含从0到当前点的所有点的下采样历史。 换句话说,数组的最大长度应该是l。如果我收到的采样点比l多,我希望图表数组是整个历史的一个降采样到-l版本 要用代码表示它,请执行以下操作: const CHART_LENGTH = 2048 createChart(CHART_LENGTH) onReceivePoint = function(p) { // p can be considere

我的一个节点进程每半秒接收一个样本点,我想更新我接收的所有样本点的历史图表。 图表应该是一个数组,其中包含从0到当前点的所有点的下采样历史。 换句话说,数组的最大长度应该是
l
。如果我收到的采样点比
l
多,我希望图表数组是整个历史的一个降采样到-
l
版本

要用代码表示它,请执行以下操作:

const CHART_LENGTH = 2048
createChart(CHART_LENGTH)
onReceivePoint = function(p) {
    // p can be considered a number
    const chart = addPointToChart(p)
    // chart is an array representing all the samples received, from 0 to now
    console.assert(chart.length <= CHART_LENGTH)
}
const图表长度=2048
createChart(图表长度)
onReceivePoint=函数(p){
//p可以看作是一个数字
常量图表=添加点到图表(p)
//图表是一个数组,表示从0到现在接收的所有样本

console.assert(chart.length唯一不会扭曲数据并且可以多次使用的操作是对整数个相邻样本的聚合。您可能需要2

更具体地说:如果您发现添加新样本将超过数组边界,请执行以下操作:从数组的开始处开始,并平均两个后续样本。这将使数组大小减少2,并且您有空间添加新样本。这样,您应该跟踪当前的群集大小
c
(构成数组中一个条目的样本量)。从一开始。每次缩减都会将集群大小乘以两

现在的问题是,您不能再直接将新样本添加到数组中,因为它们具有完全不同的比例。相反,您应该将下一个
c
样本平均到一个新条目中。结果表明,在当前集群中存储样本数
n
就足够了。因此,如果您添加一个新的sample
s
,您将执行以下操作

n++
if n = 1
    append s to array
else        
    //update the average
    last array element += (s - last array element) / n
if n = c
    n = 0 //start a new cluster
因此,您实际需要的内存如下:

  • 具有预定义长度的历史记录数组
  • 历史记录数组中的元素数
  • 当前群集大小
    c
  • 当前群集中的元素数
    n

额外内存的大小不取决于样本总数,因此
O(1)

我不确定我是否理解“从数组的开始处开始,然后对两个后续样本进行平均”。我是否应该直接取[0]和[1],对它们进行平均,并将它们放在[0]的位置,将数组向后移动一个位置?或者我应该平均a[0]和a[1]、a[2]和a[3]等直到数组结束,并得到一个长度为一半的数组?这就是我的意思:
a0:=0.5(a0+a1);a1:=0.5(a2+a3);a2:=0.5(a4+a5);…
n++
if n = 1
    append s to array
else        
    //update the average
    last array element += (s - last array element) / n
if n = c
    n = 0 //start a new cluster