Rolling median algorithm in C

前端 未结 13 1761
臣服心动
臣服心动 2020-11-27 09:24

I am currently working on an algorithm to implement a rolling median filter (analogous to a rolling mean filter) in C. From my search of the literature, there appear to be t

13条回答
  •  旧时难觅i
    2020-11-27 10:08

    I couldn't find a modern implementation of a c++ data structure with order-statistic so ended up implementing both ideas in top coders link suggested by MAK ( Match Editorial: scroll down to FloatingMedian).

    Two multisets

    The first idea partitions the data into two data structures (heaps, multisets etc) with O(ln N) per insert/delete does not allow the quantile to be changed dynamically without a large cost. I.e. we can have a rolling median, or a rolling 75% but not both at the same time.

    Segment tree

    The second idea uses a segment tree which is O(ln N) for insert/deletions/queries but is more flexible. Best of all the "N" is the size of your data range. So if your rolling median has a window of a million items, but your data varies from 1..65536, then only 16 operations are required per movement of the rolling window of 1 million!!

    The c++ code is similar to what Denis posted above ("Here's a simple algorithm for quantized data")

    GNU Order Statistic Trees

    Just before giving up, I found that stdlibc++ contains order statistic trees!!!

    These have two critical operations:

    iter = tree.find_by_order(value)
    order = tree.order_of_key(value)
    

    See libstdc++ manual policy_based_data_structures_test (search for "split and join").

    I have wrapped the tree for use in a convenience header for compilers supporting c++0x/c++11 style partial typedefs:

    #if !defined(GNU_ORDER_STATISTIC_SET_H)
    #define GNU_ORDER_STATISTIC_SET_H
    #include 
    #include 
    
    // A red-black tree table storing ints and their order
    // statistics. Note that since the tree uses
    // tree_order_statistics_node_update as its update policy, then it
    // includes its methods by_order and order_of_key.
    template 
    using t_order_statistic_set = __gnu_pbds::tree<
                                      T,
                                      __gnu_pbds::null_type,
                                      std::less,
                                      __gnu_pbds::rb_tree_tag,
                                      // This policy updates nodes'  metadata for order statistics.
                                      __gnu_pbds::tree_order_statistics_node_update>;
    
    #endif //GNU_ORDER_STATISTIC_SET_H
    

提交回复
热议问题