#sliding-window #control

sliding_window_alt

一个结构,用于保存推送到它中的最后 N 个项

3 个版本

0.1.2 2022年7月8日
0.1.1 2022年4月12日
0.1.0 2022年4月2日

#769 in 数据结构

无许可证

17KB
307

是什么

这是一个滑动窗口数据结构。在其内部,有一个向量,其中位置 0 存储最新元素,位置 capacity 存储最旧元素。每次推入一个项时,该元素被存储在位置 0,所有其他元素都会移动,最后位置会被遗忘。

为了提高速度,它内部的工作方式并非如此。内部有一个移动的索引,始终指向集合中的最旧元素。这样插入操作是 O(1)。

您可以通过三种方式获取信息,通过获取迭代器,通过获取 Vec<T>,或者通过直接索引

为什么

以下包相当相似

队列 有类型 CircularBuffer。它有几个问题。第一个问题是它有 O(n) 的插入。不那么令人担忧的是,它只能返回最新项。另一方面,它将抽象队列的操作表示为 trait,这是好的。它没有测试。这很可能不是你在搜索滑动窗口时想要的。

circular_queue 几乎与这个包完全相同,除了这个包没有提供多种可能的顺序。另一方面,这个包提供了更多创建和推送项的方式,更多的比较,以及向量返回。它不允许索引,这正是这个包所拥有的,主要受到...

sliding_windowcircular_queue 有类似的功能,但它是 no_std,并且有一些不安全代码。它允许索引,其中 0 是最旧项。这可能是在速度和可移植性方面需要考虑的包。

然而,我发布了这个包。我的原因如下

  1. 它始终从创建时开始填充,始终返回相同大小的迭代器和向量。这对于某些数学操作特别有用。这将是对其他包的重大更改,也是创建新包而不是向那些包贡献的原因。

  2. 它在 circular_queue 索引的基础上增加了,向量返回,以及大量 PartialEqs 实现。

  3. 它是100%安全的。

  4. 没有依赖项,构建速度快,(它是一个小目标,实际行数约为130)。

如何

examples文件夹中有几个示例。以下是了解这个库的一些代码。

use sliding_window_alt::SlidingWindow;

fn main() {
    // Stores the useful information for a model of a system. In this case the
    // latest 5 outputs of the system
    let mut sys = SlidingWindow::new(5, 0.0);

    // caracteristical polynomial of the system, it's stable
    let carac_pol = [0.5, -0.4, 0.2, -0.3, 0.05];

    for _ in 0..=100 {
        sys.push(
            sys.iter()
                .zip(carac_pol)
                .map(|(item, coef)| coef * *item)
                .sum::<f64>() // Multiplies the polinomial
                + 1.0, // the action input, in this case a step
        );
        println!("{}", sys[0]);
    }
}

声明

创建滑动窗口有三种方法。一种是使用new,另外两种是从数组或切片创建。

转换

&SlidingWindowSlidingWindowinto_iter方法允许在for循环中使用,然而,这两个方法都是O(n)。

推送

push方法推送一个项目,而push_slice推送一个项目数组,其中位置0的项目是“最年轻的”。

迭代

iteriter_mut方法提供了从最新项目开始的迭代器。

索引

您可以通过索引访问滑动窗口的内容,它。索引0是最新的元素,而capacity是最旧的。

向量

如果您需要为您的应用程序执行某些分析,您可以从to_vec方法获取一个向量。此操作是O(n),在您真正需要向量时使用它。

基准测试

有一些针对代码的基准测试以及与之前提出的替代crates的比较。

标准 胜利 失败
创建 队列/滑动窗口 (?[^1]) 这个crate
插入 这个crate 队列[^2]
迭代 这个crate/circular_queue sliding_window
完整工作流程(无需初始化) sliding_window circular_queue
完整工作流程(需要初始化) 这个crate sliding_window

我的建议是,如果您不需要固定长度,请使用sliding_window,否则,使用这个。Queues crate中的CircularBuffer可能无法最佳地解决您的问题。

[^1]: 未知,因为我无法黑盒创建时的项目数量。[^2]: Queues不提供迭代器,也不提供访问队列中所有数据的方法,因此无法在其他类别中竞争。

没有运行时依赖项