|
Тяпничная труба с рейтингом
|
|||
---|---|---|---|
#18+
Привет котаны-бротаны. Очередная пятничная. Дан поток данных имеющих целочисленные ключи. Поток бесконечный. У него есть точка начала но нет конца. Пример ключей. Код: sql 1.
В любой момент времени пользователь может запросить из него top 1000 элементов ранжированных по ключу. Пример output: Код: sql 1.
Язык разработки: C++/Delphi/C# вобщем любой. Алгоритмы и структуры данных: счетчики, биткарты, хештаблички, деревья... вобщем что угодно. Единственное пожелание - чтоб были сорцы на для уточнения алгоритма. Что мы не будем использовать Базы данных и готовые коробочные продукты. Физический смысл Физический смысл этого потока может быть любой. Например top 1000 сделок на бирже за нарастающий период, ранжироанных по цене. Какой-то более глубокий и точный смысл у это задачи отсуствует. Считайте что это просто разминка мозга. Сами данные которые пристёгнуты к ключам мы пока игнорируем. Поэтому нам достаточно целых чисел. Бесконечный поток - суть сетевой интерфейс на который что-то приходит. P.S. Топик похож на топик Ивана но мы не будем обсуждаеть его тему. Go-go кодить!! ... |
|||
:
Нравится:
Не нравится:
|
|||
21.05.2021, 15:28 |
|
Тяпничная труба с рейтингом
|
|||
---|---|---|---|
#18+
ИМХО надо какой-то здравый смысл добавить. Из того что мне известно тут просятся биржевые котировки (бесконечный поток) и их технический анализ. Насколько помню Иван именно этим увлекался. Тут элементарно строятся всякие скользящие средние и т.п. Только это не работает! Я тоже поигрываю немного на бирже, читаю форумы трейдеров, там есть такой термин "кукл", типа пришел кто-то с кучей денег и сломал всю математику игры и дальше хоть запредсказывайся. ... |
|||
:
Нравится:
Не нравится:
|
|||
21.05.2021, 21:10 |
|
Тяпничная труба с рейтингом
|
|||
---|---|---|---|
#18+
Не знаю. Я - не азартный. Пробовал приспособить бинарную кучу (или пирамиду). Но у нее нет строгого доказательства что top 1000 элементов ляжет в лимитированную пирамиду в правильном порядке. Из гарантий - только максимум. Остальные (листовые узлы) могут вытеснятся в случайном порядке. На картинке показан кейс. Наименьшим элементом является ключ "1" но он не индексируется для быстрого удаления. А если мы добавляем новый элемент (допустим 101) то он спустит вниз поддерево узлов и вытеснен будет элемент с ключом "3" при условии что мы сохраняем фиксированный размер кучи равно 9 элементов как показано на картинке. Если снять ограничение на 9 элементов - тогда открыт вопрос - а сколько вообще надо хранить чтобы поднять top 1000. По другим структурам. Можно приспособить красно-черное дерево, но оно избыточно в стационарной фазе когда есть уже 1000 элементов и нужно будет постоянно добавлять +1 элемент и выбрасывать еще -1. Ненужное число ре-балансов. ... |
|||
:
Нравится:
Не нравится:
|
|||
21.05.2021, 22:57 |
|
Тяпничная труба с рейтингом
|
|||
---|---|---|---|
#18+
Может я задачу не так понял, но в чем сложность-то? Держи в памяти 1000 топовых элементов и проверяй по ним каждый новый поступивший. Код: c# 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12.
... |
|||
:
Нравится:
Не нравится:
|
|||
21.05.2021, 23:08 |
|
Тяпничная труба с рейтингом
|
|||
---|---|---|---|
#18+
fkfka, а как устроен внутри SortedList? ... |
|||
:
Нравится:
Не нравится:
|
|||
21.05.2021, 23:10 |
|
Тяпничная труба с рейтингом
|
|||
---|---|---|---|
#18+
mayton fkfka, а как устроен внутри SortedList? https://github.com/dotnet/runtime/blob/main/src/libraries/System.Collections/src/System/Collections/Generic/SortedList.cs ... |
|||
:
Нравится:
Не нравится:
|
|||
21.05.2021, 23:24 |
|
Тяпничная труба с рейтингом
|
|||
---|---|---|---|
#18+
Сортированный список? Неплохо для удаления хвостика. Но не очень быстро для вставки нового элемента. У меня под рукой нет .Net компиллятора. Ты можешь сделать бенчмарк? Добавь например 1 млрд целых чисел и скажи сколько времени это займет. ... |
|||
:
Нравится:
Не нравится:
|
|||
21.05.2021, 23:32 |
|
Тяпничная труба с рейтингом
|
|||
---|---|---|---|
#18+
Ну это просто классическая задача на кучу. Только не на max как на картинке, а на min-heap, где в корне минимальное значение. Сложность n*log(k). Есть еще алгоритм похожий на быструю сортировку, который в среднем может найти k первый элементов со сложностью 2n, но он тут не подойдет, если данные в потоке. ... |
|||
:
Нравится:
Не нравится:
|
|||
21.05.2021, 23:57 |
|
Тяпничная труба с рейтингом
|
|||
---|---|---|---|
#18+
Всегда-ли куча будет хороша? Возможен-ли кейс, когда красно-черное дерево лучше? ... |
|||
:
Нравится:
Не нравится:
|
|||
22.05.2021, 09:04 |
|
Тяпничная труба с рейтингом
|
|||
---|---|---|---|
#18+
mayton Всегда-ли куча будет хороша? Возможен-ли кейс, когда красно-черное дерево лучше? красно-чёрное дерево будет лучше, если потребуется вынимать строго 15й из отобранной тысячи, без получения всей сортированной 1000, а потом, случайно, строго 115й или при использовании полученного набора как структуры индексированного поиска. В построении куча будет немного дешевле, нужен будет +1 элемент в массиве, т.е. - 1001. И да, в ранговых задачах - min-heap. За одно сравнение с первым элементом ты решаешь, добавлять ли элемент в кучу. И всегда добавляешь, пока куча не выросла до своего максимально допустимого размера в 1000 хранимых элементов. ------------------- И это простейший вариант - кучи с единственным источником данных. А так как снаружи куча - всегда интерфейс, ничто не мешает внутри реализации часть кучи держать в базе данных, например, смерживая при отдаче сортированного набора источник памяти с его продолжением на диске. ... |
|||
:
Нравится:
Не нравится:
|
|||
22.05.2021, 11:40 |
|
Тяпничная труба с рейтингом
|
|||
---|---|---|---|
#18+
Dima T ИМХО надо какой-то здравый смысл добавить. Из того что мне известно тут просятся биржевые котировки (бесконечный поток) и их технический анализ. Насколько помню Иван именно этим увлекался. Тут элементарно строятся всякие скользящие средние и т.п. Давай я придумаю здравый смысл. Возможно он пригодится не для этого а для моих будущих топиков. Потом просто кину ссылку сюда. Есть приложение которое анализирует события мира ценных бумаг в разрезе одной биржи. Приложение используют заинтерсованные лица (ЗЛ). Кто эти лица - мы не знаем. События - месседжи. Хотя не всякий месседж нам интересен. Здесь я могу немного ошибаться. Но нам может быть интересен например filled ордера. И нам может быть интересно цена (= произведение цены ценной бумаги (price) на ее количество (quantity)). Заполнение ордера означает что пакет ценных бумаг куплен. Пример месседжа (я взял с Вики образец) https://ru.wikipedia.org/wiki/Financial_Information_eXchange. Код: sql 1. 2.
В данном примере нас в сортировке бы интересовало произведение 15 штук акций * цену акции 15 $ = 225 $. Только тип события не 35=D (новый ордер) а другой код связанный с заполнением количества штук (я не помню его точно). Какие поиски или какие views ЗЛ может заказывать - мы не знаем. Но пока мы собираем топы сделок в разрезе всего торгового дня или в разреде какого-то конкретного тикера (например Microsoft/Apple/IBM). Скорость реакции интерфейса - важна и наши заинтересованные не хотят долго ждать выборок из БД. Наше приложение слушает события в этом формате (TCP/UDP/JMS/...e.t.c) по сетевым и прикладным протоколам и публикует на экране топчик. Возможно смысл что я придумал - не совершенен, и кто знающий - можете добавить больше смыслов. Только так чтобы главная постановка задачи кардинально не изменилась. ... |
|||
:
Нравится:
Не нравится:
|
|||
22.05.2021, 13:51 |
|
Тяпничная труба с рейтингом
|
|||
---|---|---|---|
#18+
booby mayton Всегда-ли куча будет хороша? Возможен-ли кейс, когда красно-черное дерево лучше? красно-чёрное дерево будет лучше, если потребуется вынимать строго 15й из отобранной тысячи, без получения всей сортированной 1000, а потом, случайно, строго 115й или при использовании полученного набора как структуры индексированного поиска. В построении куча будет немного дешевле, нужен будет +1 элемент в массиве, т.е. - 1001. И да, в ранговых задачах - min-heap. За одно сравнение с первым элементом ты решаешь, добавлять ли элемент в кучу. И всегда добавляешь, пока куча не выросла до своего максимально допустимого размера в 1000 хранимых элементов. Я еще немного поборюсь за кучу (двоичную кучу или пирамиду). Далее я с вашего позволения буду называть "кучу" пирамидой . Мне так удобнее чтоб не было терминологической тавтологии с кучей как механизмом аллокации памяти. Мне нравится пирамида своей компактностью в противоположность дереву. Моя первая идея была как предложил Зяма выше - использовать мин-пирамиду. Только я хотел трекать две пирамиды сразу. Мин-пирамиду - для решения собственно задачи. И макс-пирамиду для показа первых 10-15 значений (типа pagination). Но я уже сомневаюсь что можно доверять макс-пирамиде. Есть вероятность что она просто станет хуже обычной пирамидальной сортировки (мин-пирамида -> сортировка по месту -> реверс массива наоборот). Сами тела месседжей - хранить отдельно от пирамид. В идеале элемент пирамиды должен быть ключом + указателем на месседж в пуле месседжей. Это также удобно тем что мы можем сделать несколько views. По цене сделки за день. По заданному типу сделок за день. И т.п. вариации. ... |
|||
:
Нравится:
Не нравится:
|
|||
22.05.2021, 14:01 |
|
Тяпничная труба с рейтингом
|
|||
---|---|---|---|
#18+
booby mayton Всегда-ли куча будет хороша? Возможен-ли кейс, когда красно-черное дерево лучше? красно-чёрное дерево будет лучше, если потребуется вынимать строго 15й из отобранной тысячи, без получения всей сортированной 1000, а потом, случайно, строго 115й или при использовании полученного набора как структуры индексированного поиска. В деревьях - хотелось-бы избежать insert/delete ключей и произвести сразу update минимального на текущий новый с ребалансировкой как обычно. Это моя наивная попытка избежать операций с new/delete памяти. ... |
|||
:
Нравится:
Не нравится:
|
|||
22.05.2021, 14:05 |
|
Тяпничная труба с рейтингом
|
|||
---|---|---|---|
#18+
mayton, Двоичная куча, возможно, будет эффективнее, но асимптотика будет все равно та же - O(N), т.к. размер хранимой коллекции всегда ограничен тысячью и разница будет только по множителю. На самом деле, я просто к тому, что в этой задаче ничего особо любопытного нет. Другое дело, вот, если нужно, например, искать медиану потенциально неограниченной последовательности - вот там действительно нужны не совсем тривиальные подходы, хотя и тут уже все изучено и алгоритмы готовые есть (они либо приближенные, либо вероятностные). ... |
|||
:
Нравится:
Не нравится:
|
|||
22.05.2021, 14:11 |
|
Тяпничная труба с рейтингом
|
|||
---|---|---|---|
#18+
fkfka, почему o(n)? Для пирамиды: Добавление в хвост O(1) + Перебалансировка O(Log n) Чтение max (peek) - O(1). Изьятие max (poll) - O(Log n) ... |
|||
:
Нравится:
Не нравится:
|
|||
22.05.2021, 20:50 |
|
Тяпничная труба с рейтингом
|
|||
---|---|---|---|
#18+
mayton fkfka, почему o(n)? Имеется в виду обработка N айтемов входящих данных. У тебя-то "куча" или что-либо еще никогда не вырастет больше 1000 элементов, т.ч. вставка/удаление и т.п. одного отдельного элемента не будут зависеть хоть у тебя их поступило миллион, хоть миллиард. Вполне возможно, что на конкретно 1000 элементах какая-нибудь самая тупая структура сможет оказаться быстрее, чем какое-нибудь навороченное дерево. Надо будет, например, любопытства ради сравнить SortedSet и HashSet. ... |
|||
:
Нравится:
Не нравится:
|
|||
22.05.2021, 21:45 |
|
Тяпничная труба с рейтингом
|
|||
---|---|---|---|
#18+
Не надо сравнивать с HashSet. Это просто бесполезно т.к. цели не те. ... |
|||
:
Нравится:
Не нравится:
|
|||
23.05.2021, 12:15 |
|
Тяпничная труба с рейтингом
|
|||
---|---|---|---|
#18+
mayton Не надо сравнивать с HashSet. Это просто бесполезно т.к. цели не те. Ну почему бесполезно. По сути задача, это хранить коллекцию с возможностью быстрой вставки и поиска/удаления минимального элемента. Можно даже на совсем простом массиве реализовать - вопрос только в скорости. ... |
|||
:
Нравится:
Не нравится:
|
|||
23.05.2021, 13:10 |
|
Тяпничная труба с рейтингом
|
|||
---|---|---|---|
#18+
Ну сделай на массиве. Посмотрим. ... |
|||
:
Нравится:
Не нравится:
|
|||
23.05.2021, 14:55 |
|
Тяпничная труба с рейтингом
|
|||
---|---|---|---|
#18+
mayton Ну сделай на массиве. Посмотрим. Лень. Да и других дел полно. ... |
|||
:
Нравится:
Не нравится:
|
|||
23.05.2021, 17:39 |
|
Тяпничная труба с рейтингом
|
|||
---|---|---|---|
#18+
mayton Дан поток данных имеющих целочисленные ключи. Поток бесконечный. У него есть точка начала но нет конца. ... В любой момент времени пользователь может запросить из него top 1000 элементов ранжированных по ключу. Пример output: Код: sql 1.
Я думаю что при бесконечном потоке top 1000 выродится в набор значений около абсолютного максимума, типа такого Код: sql 1.
... |
|||
:
Нравится:
Не нравится:
|
|||
23.05.2021, 20:00 |
|
Тяпничная труба с рейтингом
|
|||
---|---|---|---|
#18+
У нас бесконечность - это опер-день. С утреца - будет снова по нулям. ... |
|||
:
Нравится:
Не нравится:
|
|||
24.05.2021, 00:04 |
|
Тяпничная труба с рейтингом
|
|||
---|---|---|---|
#18+
Начал строить дом с крыши. До 1000 элементов кучу можно наполнять. Или пакетно впихнуть. А после 1000 делать замены вершинного элемента (там будет минимальный) на новый. Вот этот метод replaceTopItem() я сделал в целях оптимизации insert/poll. Хотя чорт его знает будет ли дешевле. Код: java 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23.
Из готовых имплементаций есть в std готовый метод делания пирамиды https://en.cppreference.com/w/cpp/algorithm/make_heap и кажется он был там уже очень давно. Я его называю "пирамидизация". Но мне также еще понадобиться метод для проталкивания "бульбы" вверх и вниз методом пузыря. ... |
|||
:
Нравится:
Не нравится:
|
|||
24.05.2021, 14:56 |
|
Тяпничная труба с рейтингом
|
|||
---|---|---|---|
#18+
mayton ... А после 1000 делать замены вершинного элемента (там будет минимальный) на новый. ... Из готовых имплементаций есть в std готовый метод делания пирамиды https://en.cppreference.com/w/cpp/algorithm/make_heap и кажется он был там уже очень давно. .... ты точно понимаешь, что делаешь? если верить твоей ссылке, то make_heap в вершину максимальный поместит, а не минимальный. ... |
|||
:
Нравится:
Не нравится:
|
|||
24.05.2021, 15:07 |
|
|
start [/forum/topic.php?fid=16&msg=40072221&tid=1339659]: |
0ms |
get settings: |
10ms |
get forum list: |
12ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
59ms |
get topic data: |
11ms |
get forum data: |
3ms |
get page messages: |
58ms |
get tp. blocked users: |
1ms |
others: | 243ms |
total: | 403ms |
0 / 0 |