zoukankan      html  css  js  c++  java
  • 算法随笔(一):动态维护分位数(第N大数,The N-th element)

    查找分位数的典型算法是分治法$T(n)=O(n)$。但是对于动态数组来说,依然有优化空间。

    问题描述:交易员在策略中要维护一个定长价格序列(N=3000),交易所每推过来一个新的价格,需要从头部插入它,同时从尾部移走最早的价格。之后,获取它的10%分位数和90%分位数。根据分位数来获得交易信号。

    最原始的做法是:每次更新价格后,排序,然后取10%,90%分位数。在实盘运行时自然没有问题,但是回测速度特别慢。因为它的时间复杂度是$T(n)=O(nlog n)$

    使用分治法代替排序过程后,时间复杂度为$T(n)=O(n)$。依然不够快:

    最终做法:

     1、建立一个Queue(内部实现:循环数组),来按时间顺序存放价格。

    2、建立三个SortedSet(内部实现:排序二叉树): LeftSet,MiddleSet和RightSet。分别保存序列中最小的10%,中间的80%和最大的10%和价格。

    每来一个价格p:

    1、从Queue头部插入p,从尾部弹出最老的数据q。时间复杂度:$T(n)=O(1)$

    2、从LeftSet, MiddleSet,RightSet三个集合中找到q,删除。若q在LeftSet中,删除后LeftSet的元素将少于10%。这时将MiddleSet中最小值移动到LeftSet中,再将RightSet的最小值移入MiddleSet。其他情况以此类推。时间复杂度:$T(n)=O(log n)$

    3、p插入LeftSet,这时候LeftSet中元素个数超过10%。所以将LeftSet最大值移入MiddleSet,在把MiddleSet最大值移入RightSet。最后删除RightSet中的最大值。时间复杂度:$T(n)=O(log n)$

    4、获取10%分位数=LeftSet.Max,90%分位数=RightSet.Min。时间复杂度:$T(n)=O(log n)$

    这样,整个操作时间复杂度降为$T(n)=O(log n)$

    当然,排序二叉树也可以用堆来代替。实现略有不同,这里省略。

  • 相关阅读:
    setTimeout中0毫秒延时
    javascript中call和apply方法
    javascript闭包
    apns 服务
    新的开始,新的起点
    心情笔记
    如何解决控件附件上传时超大附件无法上传的问题
    BPM实例分享——日期自动计算
    BPM实例分享——金额规则大写
    分享一个程序猿在流程数据查看权限问题的总结
  • 原文地址:https://www.cnblogs.com/milaohu/p/6085064.html
Copyright © 2011-2022 走看看