我有一个结构向量,用于存储以不同间隔到达的值流。该结构由两个元素组成,一个用于值,另一个用于记录值到达时的时间。
struct Data {
Time timeOfArrival;
Time value;
}cd;
让我们说在另一个线程中,我想计算在过去10(比如)秒内到达的值的移动平均值。所以在一个线程中正在填充向量,而在另一个线程中我想要计算移动平均值。
答案 0 :(得分:1)
我将如何做到这一点。为简单起见,我重新定义了数据如下:
struct Data
{
int timeOfArrival;
int value;
};
您要求的一种方法是使用循环缓冲区,只存储移动平均线所需的数据量。
enum { MOVING_AVG_SIZE = 64, }; // number of elements that you use for your moving average
std::vector<Data> buffer(MOVING_AVG_SIZE);
std::vector<Data>::iterator insertIt = buffer.begin();
// saving to circular buffer
Data newData;
++insertIt
if (insertIt == buffer.end()) insertIt = buffer.begin();
*insertIt = newData;
// average
int sum = 0;
for (std::vector<Data>::const_iterator it = buffer.begin(); it != buffer.end(); ++it)
{
sum += it->value;
}
float avg = sum / (float)buffer.size();
如果你没有循环缓冲区并且只是不断向向量添加值,那么你可以获得计算移动平均线所需的最后一个元素数。
// saving to circular buffer
Data newData;
buffer.push_back(newData);
// average
// this algorithm calculates the moving average even if there is not enough samples in the buffer for the "10 s"
std::vector<Data>::const_reverse_iterator it = buffer.rbegin();
int i;
int sum = 0;
for (i = 0; i < MOVING_AVG_SIZE || it == buffer.rend(); ++i)
{
sum += it->value;
}
float avg = sum / (float)i;
答案 1 :(得分:0)
由于您已经确定一个线程将始终填充,另一个线程将执行移动平均线。然后你可以这样做:
保持一个结构包含两个元素RunningSum,而不包含向量中的项目。
编写一个循环,删除超过10秒的元素,并从RunningSum中扣除它们的值。向量中的所有元素都按照到达时间进行排序,因此您无需迭代整个向量。 添加总和尚未添加的新元素的值。
您需要一种方法来消除已添加(用于总和)的项目和尚未求和的项目。您可以为此使用布尔值或将它们放在新的dataStructure中(类的内部)。
保持元素数量并计算平均值。