当前位置: 首页 > 知识库问答 >
问题:

高效计算运行中值[副本]

阳昊
2023-03-14

读过我之前问题的人都知道我在理解和实现快速排序和快速选择以及其他一些基本算法方面的工作。

Quickselect用于计算未排序列表中的第k个最小元素,这个概念也可以用于寻找未排序列表中的中值。

这一次,我需要帮助来设计一种有效的技术来计算运行中位数,因为快速选择不是一个好的选择,因为它需要在每次列表更改时重新计算。因为快速选择每次都必须重新启动,所以它不能利用之前完成的计算,所以我正在寻找一种不同的算法,它可能类似(可能),但在运行中位数方面更有效。

共有3个答案

尤夕
2023-03-14

一种解决方案是维护一个顺序统计树,依次插入序列的每个元素,然后计算树中元素的中位数。

这将花费每次插入O(lg n)时间和每个中值O(lg n)时间,总共O(n lg n)时间,加上O(n)空间。

濮阳宁
2023-03-14

杰夫·麦克林托克(Jeff McClintock)运行中位数估计。只需要保留两个值。此示例循环访问采样值数组(CPU 消耗)。似乎相对较快地收敛(约100个样本)到中位数的估计值。这个想法是在每次迭代中,中位数英寸以恒定速率朝向输入信号。该比率取决于您估计中位数的量级。我使用平均值作为中位数大小的估计值,以确定中位数的每个增量的大小。如果您需要中位数精确到约1%,请使用0.01 *平均值的步长。

float median = 0.0f;
float average = 0.0f;

// for each sample
{
    average += ( sample - average ) * 0.1f; // rough running average.
    median += _copysign( average * 0.01, sample - median );
}
农雅畅
2023-03-14

使用两个堆来计算流中值。所有小于或等于当前中值的数字都在左堆中,其排列方式使得最大数位于堆的根。所有大于或等于当前中值的数字都在右堆中,其排列方式使得最小的数字位于堆的根。请注意,等于当前中值的数字可以在任一堆中。两个堆中的数字计数相差不会超过1。

当进程开始时,两个堆最初是空的。输入序列中的第一个数字被添加到其中一个堆中,不管是哪个,并作为第一个流中位数返回。然后将输入序列中的第二个数字添加到另一个堆中,如果右堆的根小于左堆的根,则交换两个堆,并将两个数字的平均值作为第二个流中位数返回

然后主算法开始。将输入序列中的每个后续数字与当前中值进行比较,如果小于当前中值,则添加到左侧堆中,如果大于当前中值,则添加到右侧堆中;如果输入数等于当前中值,则将其添加到计数较小的堆中,或者添加到计数相同的任意堆中。如果这导致两个堆的计数相差超过1,则较大堆的根将被移除并插入较小堆中。然后,如果两个堆的数量不同,则将当前中值计算为较大堆的根;如果两个堆的大小相同,则将当前中值计算为两个堆的根的平均值。

Scheme和Python中的代码可以在我的博客上找到。

 类似资料:
  • 我正在用Apache POI 3.13编写一个Excel(xls)表。我手动设置列宽。如果单元格的内容太长,我希望对其进行包装,并调整列高度。 如果我将单元格样式的wrapText属性设置为true,则文本不再“流出”单元格,但如何将行的高度设置为合适的值? 我见过的所有方法都计算字符串中的换行符。这对我不起作用,因为我的文本不包含手动换行符。

  • 问题内容: 我有这个MySQL查询: 返回如下内容: 我真正想要的是末尾的另一列显示运行总计: 这可能吗? 问题答案: 也许这对您来说是一个更简单的解决方案,并且可以防止数据库不得不执行大量查询。这仅执行一个查询,然后在一次通过中对结果进行一点数学运算。 这将为您提供一个额外的RT(运行总计)列。不要错过顶部的SET语句来首先初始化运行的total变量,否则您将只获得一列NULL值。

  • 问题内容: 我有这个MySQL查询: 返回如下内容: 我真正想要的是末尾的另一列以显示运行总计: 这可能吗? 问题答案: 也许对您来说是一个更简单的解决方案,并且可以防止数据库不得不执行大量查询。这仅执行一个查询,然后在一次通过中对结果进行一些数学运算。 这将为您提供一个额外的RT(运行总计)列。不要错过顶部的SET语句来首先初始化运行中的total变量,否则您将只获得一列NULL值。

  • 我有一个家庭作业,我的老师给我们留下了以下指示:创建一个新的方法,带有字符串输入和字符串返回。检查字符串是否有大写字母,将所有大写字母放在一起并返回该字符串:您的方法头和for-loop提供:没有强大的工具,使用ASCII表您的示例输出应该如下所示:getUpper("Hello,World ")returns " HW " get upper(" No way ")returns " " 这是提

  • 问题内容: 想象一下下表(称为): 我想要一个按日期顺序返回运行总计的查询,例如: 我知道在SQL Server 2000/2005/2008中可以通过多种方式进行此操作。 我对使用aggregating-set-statement技巧的这种方法特别感兴趣: …这是非常有效的,但是我听说周围存在一些问题,因为您不一定能保证该语句将以正确的顺序处理行。也许我们可以获得有关该问题的明确答案。 但是,人

  • 我创建了一个应用程序,在我的计算机中,这个jar运行没有任何问题。我试着在另一台电脑上运行它,它什么都做不到。然后,我在另一台pc上尝试了同样的jar(如果你想这样看的话,是第三台),在那里,jar运行没有问题。所以我回到第二个,试着从命令行运行它,它给了我这个错误: “main”java.lang.UnsatisfiedLinkError头出现异常:无法加载库:C:\users\hectlr\l