中值算法

引言

一个数据集合的中值(Median)通常是很一个很有价值的统计指标,由于它对异常数据不敏感,所以一般会比平均值(Mean)更能体现数据集合数据的“平均水平”。然而,对于无序数据序列求中值在实现上却没有求平均值那样简单优美的O (N)复杂度的算法。最容易想到的做法是先对数据进行排序,然后取中点的值,然而这种做法的时间复杂度是O(NlogN)。有没有更快的算法呢?

本文介绍两种更快的算法:第一种是利用快速排序原理的准确的随机选择算法;第二种是一种近似算法,所获得的值虽然可能不是很精确,但一般会比第一种方法更快。

本报告的算法实现伪代码除注释部分外均引自参考文献,若只需理解实现思想,不需要钻研伪代码的细节,可先直接看正文与注释部分。本报告提供了这两种算法相对先排序后取中值算法的时间性能比较的实验结果。

随机选择算法

这一算法是一个通用的选择算法,它可以求一个可排序数据序列中第k个位置的值。其算法伪代码如下:

// 分割,即一般快排的分割方法,返回分割点

PARTITION(A, p, r)

x ß A[r]

i ß p-1

for j ß p to r-1

do if A[j] <= x

then i ß i+1

exchange A[i] <-> A[j]

exchange A[i+1] <-> A[r]

return i+1

// 随机分割,在选择分割点时引入随机性,使快排的最坏情况难以发生

RANDOMIZED-PARTITION(A, p, r)

i ß RANDOM(p, r)

exchange A[r] <-> A[i]

return PARTITION(A, p, r)

// 随机选择

RANDOMIZED-SELECT(A, p, r, i)

if p = r

then return A[p]

q ß RANDOMIZED-PARTITION(A, p, r)

k ß q – p +1

if  i = k

then return A[q]

elseif i < k

then return RANDOMIZED-PARTITION(A, p, q-1, i)

else return RANDOMIZED-PARTITION(A, q+1, r, i-k)

其基本思想是利用快速排序的原理,对数据进行分割,将分割点的位置与k做比较,若相等,返回k位置的值,否则在分割点左右两个集合的其中一个中继续查找(快速排序需要对前后两个集合都进一步进行排序,而选择算法只需要对其中一个集合再处理,这是它能比排序算法更快的关键)。本算法的“随机”是在选取分割点时进行了随机化,这样可以避免出现最坏状况。本算法的算法复杂度为O(N)。

近似中值选择算法

本算法是一个近似算法,先看一个数组元素个数是3r的算法版本,其算法伪代码如下:

// 三重调整,对三个数进行调整,将中位数移到中间位置

TRIPLET_ADJUST(A, i, Step)

if (A[i] < A[j])

then

if (A[k] < A[i] then swap (A[i], A[j]);

else if (A[k] < A[j] then swap(A[j], A[k])

else

if (A[i] < A[k]) then swap(A[i], A[j]);

else if (A[k] > A[j]) then swap(A[j], A[k]);

// 中值近似,求一个数组A[0, 3r-1]的中值

APPROXIMATE_MEDIAN(A, r)

Step=1; Size=3^r;

Repeat r times

i = (Step-1)/2;

while ( i < Size) do

TRIPLET_ADJUST(A, I, Step);

i = i +(3*Step)

end while

Step = 3*Step

end repeat

return A[(Size-1)/2]

这一算法的基本思想是连续进行三重调整,即对每三个数取其中值,将取出的小区域中值组成一个新的数组再取其中值,直到最后。

以上算法只对n=3r时适用,对于一般情况如何扩展使用呢?以下是其基本思想:

(1)       对于任意的n, n = 3*t + k  = 3*(t-1) + (3 + k)  k∈{0, 1, 2} 对于前面的(t-1)个三重组使用以上三重调整算法,获取其中值序列,对于剩下的(3+k)个数,使用选择排序算法,获取其中值,与前面中值序列合并作为下一轮中值候选数组。

(2)       为了防止某些数每一轮被剩下,在选择三重组时从左到右、从右到左轮流进行。

其具体算法伪代码如下:

// 选择排序,就是一般的选择排序算法,没什么特别

SELECTION_SORT(A, Left, Size, Step)

for (i=Left; i < Left+(Size-1)*Step; i=i+Step)

min = i;

for (j=i+Step; j<Left+Size*Step; j=j+Step)

if (A[j].Key < A[min].Key) then min = j;

end for;

swap(A[i], A[min]);

end for

// 任何大小数组中值近似,利用三重调整与选择排序算法实现,获取A[0, Size-1]的中值

APPROXIMATE_MEDIAN_ANYN(A, Size)

LeftToRight = False;  Left=0;  Step=1;

while (Size > Threshod) do

LeftToRight = Not(LeftToRight);

Rem = (Size mod 3);

// 根据是从左至右还是从右至左设置调整初始位置

if (LeftToRight) then i = Left;

else i = Left + (3 + Rem)*Step;

// 对于t-1个三重组进行三重调整

repeat (Size/3-1) times

TRIPLET_ADJUST (A, i, Step);

i = i+3*Step;

end repeat;

if (LeftToRight) then Left = Left+Step;

else i=Left;

Left=Left+(1+Rem)*Step;

// 对剩下的3+Rem值进行选择排序

SELECTION_SORT(A, i, 3+Rem, Step);

if (Rem=2) then

if (LeftToRight) then swap(A[i+Step], A[i+2*Step])

else swap(A[i+2*Step], A[i+3Step]);

Step=3*Step; Size=Size/3;

end while

SELECTION_SORT(A, Left, Size, Step);

return A[Left+Step*Floor((Size-1)/2)];

可以证明,对于n=3r的情形,以上算法平均进行少于4n/3次比较和n/3次交换,最坏情形是进行小于3n/2次比较和n/2次交换。

实验结果

为了比较以上算法与先进行排序再取中值的实际性能差别,我们将以上算法用C++实现并与使用STL的sort排序后再取中值进行比较,N分别取值106, 107, 108,数组值初始化为0-N的随机值。结果如下:

不同算法运行时间比较(单位s):


N值


求平均值


std::sort后求中值


随机选择算法


近似中值选择算法


1,000,000


0.01


0.23


0.07


0.03


10,000,000


0.09


2.79


0.6


0.26


100,000,000


0.92


32.79


4.68


2.51

从以上实验结果可知,近似中值选择算法一般比先排序的算法快10倍左右,随机选择算法比先排序的算法快5倍左右。近似中值选择算法所用时间为求平均值算法的时间的3倍左右。

小结

对于大数据集合,本文所介绍的随机选择算法和近似中值选择算法比快速排序分别快5倍与10倍左右;而且随机选择算法是一个通用的选择算法,可以用来方便地求k位置值。在恰当时侯值得一用。

时间: 2024-08-01 00:13:46

中值算法的相关文章

数字图像处理之快速中值滤波算法

快速中值滤波算法 中值滤波算法: 在图像处理中,在进行如边缘检测这样的进一步处理之前,通常需要首先进行一定程度的降噪.中值滤波是一种非线性数字滤波器技术,经常用于去除图像或者其它信号中的噪声.这个设计思想就是检查输入信号中的采样并判断它是否代表了信号,使用奇数个采样组成的观察窗实现这项功能.观察窗口中的数值进行排序,位于观察窗中间的中值作为输出.然后,丢弃最早的值,取得新的采样,重复上面的计算过程.中值滤波是图像处理中的一个常用步骤,它对于斑点噪声和椒盐噪声来说尤其有用.保存边缘的特性使它在不希

笔试算法题(54):快速排序实现之三路划分, 三元中值法和插入排序处理小子文件

议题:快速排序算法实现之三(三路划分遍历,解决与划分元素相等元素的问题) 分析: 算法原理:使用三路划分策略对数组进行划分(也就是荷兰国旗问题,dutch national flag problem).这个实现是对实现二的改进,它添加处理等于划分元素的值的逻辑,将所有等于划分元素的值集中在一起,并且以后都不会再对他们进行划分. 本算法中使用四个标示值进行操作.使用left和right同时向中间遍历时,当left遇见等于划分元素时,就与iflag指向的值进行交换 (iflag指向的当前值到最左端表

关于中值滤波算法,以及C语言实现(转)

源:关于中值滤波算法,以及C语言实现 1.什么是中值滤波? 中值滤波是对一个滑动窗口内的诸像素灰度值排序,用其中值代替窗口中心象素的原来灰度值,它是一种非线性的图像平滑法,它对脉冲干扰级椒盐噪声的抑制效果好,在抑制随机噪声的同时能有效保护边缘少受模糊. 中值滤波可以过滤尖峰脉冲.目的在于我们对于滤波后的数据更感兴趣.滤波后的数据保留的原图像的变化趋势,同时去除了尖峰脉冲对分析造成的影响. 以一维信号的中值滤波举例.对灰度序列80.120.90.200.100.110.70,如果按大小顺序排列,其

关于中值滤波算法,以及C语言实现

1.什么是中值滤波? 中值滤波是对一个滑动窗口内的诸像素灰度值排序,用其中值代替窗口中心象素的原来灰度值,它是一种非线性的图像平滑法,它对脉冲干扰级椒盐噪声的抑制效果好,在抑制随机噪声的同时能有效保护边缘少受模糊. 中值滤波可以过滤尖峰脉冲.目的在于我们对于滤波后的数据更感兴趣.滤波后的数据保留的原图像的变化趋势,同时去除了尖峰脉冲对分析造成的影响. 以一维信号的中值滤波举例.对灰度序列80.120.90.200.100.110.70,如果按大小顺序排列,其结果为70.80.90.10O.110

中值滤波的快速算法

我想学过图像处理的人没有人会不知道中值滤波的,最早的时候我是在冈萨雷斯的图像处理课本[1]中学到的,后来在看Sonka的书[2]的时候又看到了中值滤波的介绍,下面我试着结合课本所学和网上的资料自己整理一篇中值滤波的介绍. Jeremy Lin 中值滤波器是一种统计排序滤波器,由Tukey于1971年在文献[3]中提出.所谓的统计排序滤波器是一种非线性的空间滤波器,它的响应基于图像滤波器包围的图像区域中像素的排序,然后用统计排序结果决定的值代替中心像素的值.除了中值滤波器外,最大值滤波器和最小值滤

实时高速实现改进型中值滤波算法_爱学术_免费下载

[摘要]在图像采集和处理过程中会引入噪声,必须先对图像进行预处理.本文介绍一种快速中值滤波算法,该算法在硬件平台上实现实时处理功能.综合考虑,选择现场可编程门阵列(FPGA)作为硬件平台,采用硬件描述语言Verilog实现改进型中值滤波算法.经Modelsim仿真结果表明:基于FPGA硬件平台实现改进型中值滤波算法不仅速度快,而且实时处理效果佳,提高了图像处理的效率. [作者] 杨晶  王元庆 转载至爱学术:https://www.ixueshu.com/document/29bcda14996

基于记忆性的中值滤波O(r)与O(1)复杂度的算法实现

本文参考博客:https://www.cnblogs.com/Imageshop/archive/2013/04/26/3045672.html 原生的中值滤波是基于排序算法的,这样的算法复杂度基本在O(r2)左右,当滤波半径较大时,排序算法就显得很慢.对此有多种改进算法,这里介绍经典 的Huang算法与O(1)算法,两者都是基于记忆性的算法,只是后者记性更强. 排序算法明显的一个不足之处就是无记忆性.当核向右移动一列后,只是核的最左和最右列数据发生了变化,中间不变的数据应当被存储起来,而排序算

数据挖掘中分类算法小结

数据挖掘中分类算法小结 数据仓库,数据库或者其它信息库中隐藏着许多可以为商业.科研等活动的决策提供所需要的知识.分类与预测是两种数据分析形式,它们可以用来抽取能够描述重要数据集合或预测未来数据趋势的模型.分类方法(Classification)用于预测数据对象的离散类别(Categorical Label);预测方法(Prediction )用于预测数据对象的连续取值. 分类技术在很多领域都有应用,例如可以通过客户分类构造一个分类模型来对银行贷款进行风险评估;当前的市场营销中很重要的一个特点是强

复杂网络中聚类算法总结

网络,数学上称为图,最早研究始于1736年欧拉的哥尼斯堡七桥问题,但是之后关于图的研究发展缓慢,直到1936年,才有了第一本关于图论研究的著作.20世纪60年代,两位匈牙利数学家Erdos和Renyi建立了随机图理论,被公认为是在数学上开创了复杂网络理论的系统性研究.之后的40年里,人们一直讲随机图理论作为复杂网络研究的基本理论.然而,绝大多数的实际网络并不是完全随机的.1998年,Watts及其导师Strogatz在Nature上的文章<Collective Dynamics of Small