Эффективная структура данных для хранения предварительно вычисленных максимумов

Рассмотрим эту таблицу, в которой хранятся значения двух переменных stock A и B в каждый момент времени:

         A   B
day 1   10   0 
day 2    0  10
day 3    7   7
day 4    7   7

Мы хотим ответить на такие вопросы, как:

  • Какое максимальное значение было достигнуто переменной A в заданном диапазоне дней?

  • Каково максимальное значение, полученное с помощью суммы переменных A и B в заданном диапазоне дней?

Однако реальная таблица может содержать миллиарды строк и множество переменных. Чтобы быстрее получать ответы, мы планируем предварительно вычислить сводную таблицу с меньшей степенью детализации по времени.

Проблема в том, что наивного вычисления максимума по новой временной гранулярности для A и B по отдельности недостаточно для ответа на второй вопрос. Например:

         Max-A  Max-B
day 1&2     10     10
day 3&4      7      7

Мы упустили тот факт, что максимум A + B достигается за дни 3 и 4.

Мы можем добавить новый столбец Max-(A+B) в сводную таблицу. Но если будет много разных переменных, мы столкнемся с комбинаторным взрывом. Сводная таблица может оказаться больше исходной!

Существует ли алгоритм/структура данных для эффективного хранения таких предварительно вычисленных максимумов таким образом, чтобы мы могли задавать вопросы о произвольных комбинациях переменных, избегая при этом комбинаторного взрыва? Я предполагаю, что он мог предположить некоторые закономерности в данных и попытаться использовать их — за счет некоторой общности.


person danidiaz    schedule 04.05.2019    source источник
comment
Как насчет вычисления разреженных таблиц для каждой из переменных акций? Затем для каждого временного диапазона вычислите максимум A и B, чтобы получить максимум A + B.   -  person xrisk    schedule 04.05.2019
comment
cp-algorithms.com/data_structures/sparse-table.html   -  person xrisk    schedule 04.05.2019
comment
Сколько места вы можете использовать? Если он по существу бесконечен, это подразумевает разные ответы, чем если он очень ограничен.   -  person Richard    schedule 04.05.2019
comment
Вы должны искать проблемы с максимальным запросом диапазона — вот хороший общий подход к проблеме topcoder.com/community/competitive-programming/tutorials/   -  person xrisk    schedule 04.05.2019
comment
@Richard В идеале используемое пространство должно быть не больше, чем пространство, занимаемое исходной таблицей.   -  person danidiaz    schedule 04.05.2019
comment
Имеет смысл рассмотреть систему OLAP, например clickhouse, и схему, например table{date, param_id, value} где индекс построен на основе пары {date, param_id}. Используя AggregatingMergeTree, вы можете предварительно вычислить агрегаты для каждого параметра на дату и получить требуемые результаты. на лету.   -  person vladimir    schedule 04.05.2019
comment
Ну, вы можете либо использовать разреженную таблицу, которая занимает пространство O (n log n) и отвечает на максимальные запросы за O (1), либо использовать дерево сегментов, которое использует пространство O (4 * n) и отвечает на максимальные запросы за время O (log n).   -  person Photon    schedule 04.05.2019
comment
@danidiaz Можете ли вы привести примеры некоторых запросов и ожидаемого результата?   -  person nice_dev    schedule 05.05.2019
comment
@vivek_23 Каково было максимальное значение, достигнутое суммой значений A и B за всю записанную историю? Ответ — 14 (7 + 7 как в день 3, так и в день 4), но эту информацию нельзя вывести из таблицы с более низкой степенью детализации, если только явно не добавить предварительно вычисленный столбец для суммы. Я пришел к выводу, что прошу слишком многого: если я хочу понизить гранулярность таблицы, мне придется стиснуть зубы и добавить столбцы для каждой комбинации переменных (A+B, B+C). , A+B+C, A+D...), которые меня интересуют.   -  person danidiaz    schedule 05.05.2019
comment
Похоже, что даунсэмплинг (уменьшение степени детализации или полученных данных) /influxdb/v1.7/guides/ и предварительные вычисления агрегатов druid.io/blog/2011/04/30/introduction-druid.html — это обычно используемые базы данных временных рядов, которые имеют функции для аналитики, такие как Druid.   -  person danidiaz    schedule 05.05.2019
comment
@Rishav: вычислить максимум A и B, чтобы получить максимум A + B: это не так. Вы читали вопрос?   -  person ruakh    schedule 05.05.2019
comment
Связано: stackoverflow.com/questions/38513382/   -  person danidiaz    schedule 05.05.2019
comment
@ruakh да, кажется, я неправильно понял проблему. Виноват!   -  person xrisk    schedule 05.05.2019


Ответы (1)


Не существует действительно хорошей структуры данных для всего, что вы хотите... но вы знаете, что в году всего 365 дней, т. е. в вашей таблице не будет миллиардов строк.

В таблице будет не более нескольких тысяч строк, поэтому не потребуется много времени, чтобы просто перебрать ее и вычислить любую статистику, которая вам нравится.

person Matt Timmermans    schedule 04.05.2019