2014-06-25 30 views
3

最好給出一個例子。基於另一個向量中的相似性的向量的條件平均值C++

假設向量A包括:

A = {3 ,2 ,1 ,4 ,6 ,3 ,8 ,4} 

和向量​​B包括:在向量B

B = {1.5,2 ,2 ,1.5,3 ,3 ,3 ,2} 

的唯一值是{1.5, 2, 3}

我想要得到的矢量結果成爲:

RESULT[0] = Average(A given B=1.5) = Average(3,4) 

RESULT[1] = Average(A given B=2) = Average(2,1,4) 

RESULT[2] = Average(A given B=3) = Average(6,3,8) 

什麼是最有效的計算方法。我自己的方法是循環遍歷B中的唯一元素,併爲每個元素循環遍歷每個B值,嘗試匹配該唯一編號並在每個匹配中不斷總結向量A的相應元素,並計算匹配數量我可以找到平均值。

這太慢了。因爲我的向量A是8M元素,向量B由0.5M唯一值組成。

任何幫助,將不勝感激。

+0

排序以鎖步兩種載體,然後遍歷B'的'相等範圍? –

+0

這似乎很有希望,我現在會試試看看我能獲得多少速度提升。 – user1780424

+0

雖然這是一種依賴於浮點值的確切平等的氣味。 – sehe

回答

3

這是一個懶惰的想法:以鎖步遍歷這兩個向量並將結果聚合到一個單獨的容器中。例如:

#include <cassert> 
#include <cmath> 
#include <iostream> 
#include <map> 
#include <utility> 

std::map<double, std::pair<int, std::size_t>> m; 

assert(A.size() == B.size()); 

for (std::size_t i = 0; i != A.size(); ++i) 
{ 
    assert(!std::isnan(B[i])); 

    auto & p = m[B[i]]; 
    p.first += A[i]; 
    p.second += 1; 
} 

最後,你只報告結果:

for (const auto & p : m) 
    std::cout << "Average for bin " << p.first << " is " 
       << static_cast<double>(p.second.first)/p.second.second 
       << "\n"; 

(要注意的是你的關鍵值不得楠:在一個有序圖,楠並不是嚴格排序的一部分;在一個無序的地圖,它不比較等於本身)

+0

爲什麼使用'map'而不是'unordered_map'? –

+0

@DDmmmmr:有序的遍歷報告? –

+0

很好的觸摸斷言!isnan :)我記得要SO問題(+1) – sehe

1

你可以做一個(哈希)表的循環:看到它Live On Coliru

int main() 
{ 
    vector<int> A = {3 ,2 ,1 ,4 ,6 ,3 ,8 ,4}; 
    vector<double> B = {1.5,2 ,2 ,1.5,3 ,3 ,3 ,2}; 

    assert(A.size() == B.size()); 

    struct accum { 
     uintmax_t sum = 0; 
     size_t number_of_samples = 0; 
     void sample(int val) { sum += val; ++number_of_samples; } 
    }; 
    map<double, accum> average_state; 

    for(size_t i = 0; i<B.size(); ++i) 
     average_state[B[i]].sample(A[i]); 

    for(auto& entry : average_state) 
    { 
     accum& state = entry.second; 
     double average = static_cast<double>(state.sum)/state.number_of_samples; 
     std::cout << "Bucket " << entry.first << "\taverage of " << state.number_of_samples << " samples:\t" << average << "\n"; 
    } 
} 

打印

Bucket 1.5 average of 2 samples: 3.5 
Bucket 2 average of 3 samples: 2.33333 
Bucket 3 average of 3 samples: 5.66667 
+0

爲什麼平均值被稱爲有效?因爲它是經過計算的,所以它是 – 4pie0

+0

。當然,你可以把它命名爲「平均」。我不知道問題域,所以我做了一些事情。 **更新** – sehe

+0

好了,謝謝 – 4pie0

相關問題