2015-05-14 52 views
0

我有一個存儲以不同時間間隔到達的值流的結構向量。該結構由兩個元素組成,一個用於值,另一個用於記錄值到達的時間。計算存儲在向量中的值流的移動平均值

struct Data { 
    Time timeOfArrival; 
    Time value; 
}cd; 

可以說,在另一個線程中,我想計算在最後10(說)秒內到達的值的移動平均值。所以在一個線程中,矢量正在填充,而在另​​一個線程中我想計算移動平均值。

+0

你會在矢量中存儲超過10個數據嗎?如果不是,你可以把它當作循環緩衝區。然後你可以計算整個矢量的總和。當你添加新的元素時,你需要開始在開始時添加。如果你沒有循環緩衝區,那麼你只需要一個迭代器到最後一個元素,並計算從它到10s之前的元素總和(取決於它有多少個元素)。 – rozina

回答

0

由於您已經決定一個線程將始終填充,另一個線程將移動平均線。然後,您可以執行此操作:

保留具有兩個元素RunningSum和向量中沒有項目的結構。

編寫一個循環,刪除10秒以前的元素並從RunningSum中扣除它們的值。向量中的所有元素都按timeofArrival排序,所以不需要迭代整個向量。 添加總和尚未添加的新元素的值。

您需要一種方法來對已添加的項目(總計使用)和尚未總結的項目進行分類。你可以爲此使用布爾值,或者將它們放在新的dataStructure中(類內部)。

保持元素數的計數並計算平均值。

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; 
+0

這是如何確保我平均持續10秒? – anikomei

+0

@anikomei你必須知道你在10秒內測量了多少個樣本。 – rozina