Я работаю над реализацией гистограммы, и одним из ключевых моментов является быстрое объединение бинов гистограммы. Поскольку у меня нет априорных знаний о наборе данных, аппроксимируемом гистограммой, мне нужно найти способ быстрого объединения соседних бинов после того, как я превысил максимальное количество бинов.
Так, например, если вы аппроксимируете поток данных 23, 19, 10, 16, 36, 2, 9, 32, 30, 45 пятью ячейками гистограммы, вы прочитали бы первые пять элементов , получив:
(23, 1), (19,1), (10,1), (16,1), (36,1)
Добавление корзины (2,1) вызывает проблему, так как мы превысили максимальное количество корзин. Итак, мы добавляем (2,1) и объединяем два ближайших контейнера - (16,1) и (19,1) - чтобы получить новый контейнер (17.5,2), который заменяет эти два.
Повторение этого метода для остальной части гистограммы дает нам окончательный результат:
(2,1), (9,5,2), (19,33,3), (32,67,3), (45,1).
Реализация этого без учета сложностей является тривиальной. Тем не менее, я действительно обеспокоен оптимизацией этого для больших наборов данных, потому что моя «тривиальная» реализация в конечном итоге занимает 15 секунд для запуска в потоке 100 000 гауссовских распределенных значений.
Моя текущая мысль - использовать boost :: multi_index для отслеживания моей структуры HistogramBin, которая определяется как:
struct HistogramBin
{
double bin;
unsigned long count;
bool isNull;
HistogramBin(double x, bool n = false)
: bin(x), count(1), isNull(n) {}
bool operator<(const HistogramBin &other) const
{ return (bin < other.bin); }
// Merges other with this histogram bin
// E.g., if you have (2.0,1) and (3.0,2), you'd merge them into (2.67,3)
void merge(const HistogramBin &other)
{
unsigned long old_count = count;
count += other.count;
bin = (bin*old_count + other.bin*other.count)/count;
}
// Gets the difference between two histogram bins
const double getDifference(const HistogramBin &other) const
{ return (double)abs(bin - other.bin); }
};
Итак, multi_index будет использовать order_unique <> для сортировки по HistogramBin :: bin.
Теперь, это не решает проблему сортировки бинов по различиям между соседними бинами. Индексирование с помощью HistogramBin :: bin дает нам упорядоченный список объектов HistogramBin, но затем следующим шагом является вычисление разницы между текущим bin и следующим, а затем сортировка по этим значениям.
Есть ли способ сортировки по этим значениям, сохраняя целостность списка и не вводя новый контейнер (например, мультикарту пар разностей / ключей и значений итератора)?
Ведение этого списка - моя текущая идея почти оптимального решения проблемы сложности, потому что его нужно менять только при слиянии, а слияние происходит только при добавлении нового значения.
Будем благодарны за любые мысли или понимание.