У меня есть структура данных, содержащая вектор векторов, каждый из которых содержит около ~ 16000000 двойных значений.Медиана нескольких векторов double (C++, vector <vector <double>>)
Теперь я хочу срединно-объединить эти векторы, что означает, что каждый из исходных векторов я принимаю значения в месте i, вычисляет их медиану, а затем сохраняет в результирующем векторе в месте i.
У меня уже есть прямой вперед решение, но это невероятно медленно:
vector< vector<double> > vectors; //vectors contains the datavectors
vector<double> tmp;
vector<double> result;
vector<double> tmpmedian;
double pixels = 0.0;
double matrixcount = vectors.size();
tmp = vectors.at(0);
pixels = tmp.size();
for (int i = 0; i < pixels; i++) {
for (int j = 0; j < matrixcount; j++) {
tmp = vectors.at(j);
tmpmedian.push_back(tmp.at(i));
}
result.push_back(medianOfVector(tmpmedian));
tmpmedian.clear();
}
return result;
И medianOfVector выглядит следующим образом:
double result = 0;
if ((vec.size() % 2) != 0) {
vector<double>::iterator i = vec.begin();
vector<double>::size_type m = (vec.size()/2);
nth_element(i, i + m, vec.end());
result = vec.at(m);
} else {
vector<double>::iterator i = vec.begin();
vector<double>::size_type m = (vec.size()/2) - 1;
nth_element(i, i + m, vec.end());
result = (vec.at(m) + vec.at(m + 1))/2;
}
return result;
Я есть алгоритм или способ сделать это быстрее , для этого требуется почти целая вечность.
Edit: Спасибо за ваши ответы, в случае, если кому-то интересно здесь фиксированная версия, теперь он занимает около 9sec медианной объединить три вектора с ~ 16000000 элементов, значит, объединение занимает около 3 секунд:
vector< vector<double> > vectors; //vectors contains the datavectors
vector<double> *tmp;
vector<double> result;
vector<double> tmpmedian;
tmp = &vectors.at(0);
int size = tmp->size();
int vectorsize = vectors.size();
for (int i = 0; i < size; i++) {
for (int j = 0; j < vectorsize; j++) {
tmp = &vectors.at(j);
tmpmedian.push_back(tmp->at(i));
}
result.push_back(medianOfVector(tmpmedian));
tmpmedian.clear();
}
return result;
И medianOfVector:
double result = 0;
if ((vec.size() % 2) != 0) {
vector<double>::iterator i = vec.begin();
vector<double>::size_type m = (vec.size()/2);
nth_element(i, i + m, vec.end());
result = vec.at(m);
} else {
vector<double>::iterator i = vec.begin();
vector<double>::size_type m = (int) (((vec.size() - 1)/2));
nth_element(i, i + m, vec.end());
double min = vec.at(m);
double max = *min_element(i + m + 1, vec.end());
result = (min + max)/2;
}
return result;
}
Я не уверен, сколько полезных алгоритмических предложений люди смогут сделать без дополнительной информации о обрабатываемых данных. Могут ли быть сделаны какие-либо дополнительные предположения относительно данных или свойств, которые, как вы знаете, будут иметь? Если вы имеете дело с множеством векторов переменной длины неизвестного содержимого, может быть, вы не можете сделать алгоритмически (но, возможно, еще некоторое улучшение через реализацию). – Owen
Мне кажется, что это можно сделать параллельно? Рассматривали ли вы разгрузку этого на GPU (используя CUDA/C++ AMP/OpenCL ...)? – Borgleader
Вы делаете много копий векторов. Можете ли вы передать указатели на исходные векторы? –