![]() |
|
![]() ![]() ![]() |
|
_Y_ |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1651 Регистрация: 27.11.2006 Репутация: 8 Всего: 34 |
Задумался над проблемой стояния в очереди.
Имеем очередь. Не важно какую. Например, очередь наборов данных, обрабатываемых каким-то процессом. Новый набор ставится в хвост и по мере обработки предшественников продвигается в голову (ну очереди за пивом все знают). Но, каждый набор данных имеет "коэффициент ветеранности". Чем выше коэффициент - тем быстрее набор данных должен продвигаться из конца в голову. Для простоты - принцип ускорения не важен. Ну, например, за то время пока набор с коэффициентом 10 сдвинется на 10 мест, набор с коэффициентом 15 сдвинется, соответственно на 15. При этом мелкие "конфликты" не важны (пусть не 15, а от 14 до 16, скажем). В более сложном варианте, приоритет набора может меняться в то время, пока этот набор стоит в очереди. ------------------ Мне в голову пришло только присвоить каждому набору счетчик и с каждым шагом очереди увеличивать его у всех стоящих в соответствии с коэффициентом. На каждом следующем шаге считать головным набор с наибольшим значением счетчика. Но не чувствуется это разумным - длинная очередь будет жрать ресурсы за счет постоянных пересчетов коэффициентов. Есть ли какие-то более разумные варианты? ЗЫ: Чистый интерес, честно говоря. Никакой программы на эту тему не пишу сейчас. -------------------- Я вот в этом поучаствовал: http://sbor-nik.appspot.com/kick.jsp?id=sbor5737960678883328 (на правах саморекламы:) |
|||
|
||||
tzirechnoy |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1173 Регистрация: 30.1.2009 Репутация: нет Всего: 16 |
Классический вариант: сделайте три очереди. Выбирайте 1 элемент из первой (низкоприоритетной), 6 из второй (среднего приоритета) и 9 из третьей (высокого приоритета). Это не совсем то, что Вы просили -- но приоритеты обеспечивает.
|
|||
|
||||
1000000dollars |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 231 Регистрация: 6.10.2007 Репутация: 1 Всего: 8 |
Раз уж приоритеты могут меняться - очередь всё равно будет жрать время. Я бы элементу дал поле "ветеранности" и при выборе из неё делал бы один проход пузырьком по этому самому полю. Если заморачиваться низкоуровневой оптимизацией, то надо смотреть на реализацию очереди. Серебрянной пули не существует.
|
|||
|
||||
Akina |
|
|||
Советчик ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 20581 Регистрация: 8.4.2004 Где: Зеленоград Репутация: 20 Всего: 454 |
Навскидку: я бы для каждого задания ввёл... ммм... ну, скажем, "время гарантированного поступления на обработку"... и ставил бы в очередь именно по этому параметру. Для расчёта же такого времени для новопоступившего задания хранил бы текущий "суммарный вес" очереди, корректируя его после постановки или изъятия в обработку очередного задания. Соответственно "время гарантированного поступления на обработку" расчитывается, исходя из текущего времени, веса нового задания и среднего веса заданий в очереди. -------------------- О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума. |
|||
|
||||
1000000dollars |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 231 Регистрация: 6.10.2007 Репутация: 1 Всего: 8 |
||||
|
||||
_Y_ |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1651 Регистрация: 27.11.2006 Репутация: 8 Всего: 34 |
Вот это я не очень понял. Как это ставить в очередь по параметру? -------------------- Я вот в этом поучаствовал: http://sbor-nik.appspot.com/kick.jsp?id=sbor5737960678883328 (на правах саморекламы:) |
|||
|
||||
Akina |
|
|||
Советчик ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 20581 Регистрация: 8.4.2004 Где: Зеленоград Репутация: 20 Всего: 454 |
Ну то есть не в конец очереди, а в середину. В соответствии с расчётным приоритетом. -------------------- О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума. |
|||
|
||||
_Y_ |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1651 Регистрация: 27.11.2006 Репутация: 8 Всего: 34 |
Понятно. В пронципе, должно вроде работать. Вот, примерно, так получается, если я все правильно понял: Позиция, на которую вставляется новый элемент (p): p = L * K / k где K - средний коеффициент приоритета по всей очереди. L - длина очереди. k - коеффициент приоритета нового элемента. Понятно, что если k < K, элемент ставится в конец. После добавления элемента пересчитываем К и L: K = (K * L + k) / (L + 1) L = L + 1 При отправлении первого элемента на обработку, сначала: L = L - 1 после чего преобразуя первую формулу: K = (K * (L + 1) - k0) / L где k0 - коеффициент приоритета изьятого элемента. Последняя формула особой точности не обеспечивает, но это, по условию задачи, и не обязательно. При изменении приоритета поступаем так же, как и при постановке в очетредь, но вместо длины всей очереди L берем текущую позицию элемента. Вроде все я понял. Или нет? Особой точности не будет, но общий принцип должен работать. -------------------- Я вот в этом поучаствовал: http://sbor-nik.appspot.com/kick.jsp?id=sbor5737960678883328 (на правах саморекламы:) |
|||
|
||||
disputant |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 210 Регистрация: 28.11.2011 Репутация: 2 Всего: 3 |
А что-то типа очереди с приоритетами из стандартнойго набора STL (http://www.cplusplus.com/reference/stl/priority_queue/) не подойдет?...
Раз тут рассматриваются алгоритмы, то вкратце - в очередь встраивать в соответствии с приоритетом. Т.е. очередь - что-то вроде сортированного по приоритету списка. В более сложном варианте динамического приоритета без время от времени выполняемого пересчета, похоже, не обойтись. Но его можно реализовывать как сортировку (если только повышение приоритета, то просто устойчивую, если может быть и понижение - о принципе сортировки надо думать). Это сообщение отредактировал(а) disputant - 30.1.2012, 13:23 |
|||
|
||||
Akina |
|
|||
Советчик ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 20581 Регистрация: 8.4.2004 Где: Зеленоград Репутация: 20 Всего: 454 |
Не всё. У тебя не учитывается, сколько элемент уже простоял в очереди... и элемент с наинизшим приоритетом имеет шанс вообще не добраться до исполнения. -------------------- О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума. |
|||
|
||||
1000000dollars |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 231 Регистрация: 6.10.2007 Репутация: 1 Всего: 8 |
Зачем всю-то очередь сортировать? Когда из очереди надо забрать элемент, один проход пузырьком ставит нужный элемент в начало, а дальше обычная выборка. Ну или поиск делать, вместо сортировки. Особого смысла сортировать всю очередь нет, ибо приоритеты динамические... |
|||
|
||||
_Y_ |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1651 Регистрация: 27.11.2006 Репутация: 8 Всего: 34 |
В том и дело, что хочется обойтись без сортировок всей очереди. То, что предлагает Akina, вроде позволяет проводить на каждом шаге мелкие рассчеты и только - гораздо меньше ресурсов съест, чем любая сортировка. Понятно, что в жертву приносится точность.
Прошу прощения, но C++ для меня странен и загадочен. Ага. Это-то я и забыл. Тогда при постановке в очередь лучше, наверное, брать не L - длину очереди, а некую условную длину очереди M рассчитываемую с учетом того, сколько уже простоял последний элемент. Например так: М = L * (t - t0)/(tl - t0), где t0 - время когда в очередь был поставлен элемент, в настоящий момент являющийся головным. tl - время когда в очередь был поставлен элемент, в настоящий момент являющийся последним. t - настоящий момент времени. Понятно, что при этом новый элемент, имеющий низкий приоритет, получит место в двух трамвайных остановках от хвоста очереди. Такой просто становится в конец. Т.е. формула p = L * K / k будет заменена на p = ( L * (t - t0)/(tl - t0) ) * K / k IF (p > L + 1) p = L + 1 -------------------- Я вот в этом поучаствовал: http://sbor-nik.appspot.com/kick.jsp?id=sbor5737960678883328 (на правах саморекламы:) |
|||
|
||||
ksnk |
|
|||
![]() прохожий ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 6855 Регистрация: 13.4.2007 Где: СПб Репутация: 7 Всего: 386 |
_Y_, Какие накладные расходы существуют? Очередь это массив (доступны все элементы) или список (доступны только голова-хвост)? Не дорого ли к каждому сообщению приписывать его вес?
Если недорого, то вес всей очереди будет вычисляться из суммы весов всех сообщений. Каждое сообщение, после постановки в очередь очередного сообщения, увеличивает свой вес. Снятое с очереди сообщение уменьшает вес очереди. Так гарантированно все сообщения будут обслужены, без малоприоритетных пробок. -------------------- Человеку свойственно ошибаться, программисту свойственно ошибаться профессионально ! ![]() |
|||
|
||||
_Y_ |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1651 Регистрация: 27.11.2006 Репутация: 8 Всего: 34 |
ksnk, но это, как понимаю, подразумевает на каждом шаге обращаться к каждому элементу (переприсваивать вес).
-------------------- Давайте рассмотрим практический пример. Процесс или компьютер или группа китайских детей выполняет какие-то задания. Та же группа детей выбирает по какому-то алгоритму какое задание выполнять следующим. Пока очередь заданий небольшая, можно на каждом шаге ее пересортировывать или пересчитывать вес каждого ждущего задания. А теперь предположим бурный рост китайской экономики. Заданий приходит все больше и больше. А выполняется заданий все меньше и меньше. Поскольку дети все больше времени тратят на выбор того, что же делать следующим. Поэтому и флеймлю я на тему как уменьшить время рассчетов (уж во всяком случае не растить его с ростом очереди), пожертвовав взамен точностью - не очень важно что будет сшито первым: правый кед или левый. -------------------- Я вот в этом поучаствовал: http://sbor-nik.appspot.com/kick.jsp?id=sbor5737960678883328 (на правах саморекламы:) |
|||
|
||||
Akina |
|
|||
Советчик ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 20581 Регистрация: 8.4.2004 Где: Зеленоград Репутация: 20 Всего: 454 |
Для этого прекрасно подходит системное время - при условии, что известно среднее время исполнения запроса, и разброс невелик. Иначе да, приходится вводить некий синтетический аналог. -------------------- О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума. |
|||
|
||||
_Y_ |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1651 Регистрация: 27.11.2006 Репутация: 8 Всего: 34 |
А на что повлияют эти условия? Вроде бы продвижение в очереди оценивается по времени стояния. При этом не столь важно сколько времени ушло на каждый шаг. -------------------- Я вот в этом поучаствовал: http://sbor-nik.appspot.com/kick.jsp?id=sbor5737960678883328 (на правах саморекламы:) |
|||
|
||||
ksnk |
|
|||
![]() прохожий ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 6855 Регистрация: 13.4.2007 Где: СПб Репутация: 7 Всего: 386 |
Тогда нужно определить задачу поточнее
![]() Интересно рассматривать случай, когда поток сообщений слегка "заваливает" очередь сообщений. То есть система обработки сообщений уже не справляется с нагрузкой, и очередь медленно растет, но ресурсы системы позволяют жить в таком состоянии достаточно долго. Примерное определение приоритета: Приоритет означает, что при "заваливании" очереди сообщениями с приоритетом 10 и 1 на каждое обработанное сообщение с приоритетом 1 будет обработано 10 сообщений с 10-м приоритетом. Итого, задача: Устроить все таким образом, чтобы сообщение с любым приоритетом не "застревало" в очереди навечно, при условии примерно равномерного "заваливания" очереди сообщениями с разным приоритетом. Можно предложить "поиск в глубину". Все сообщения вставляются в конец очереди. При изымании сообщения из очереди будем просматривать X сообщений в глубину очереди и искать среди них сообщение с максимальным приоритетом. У всех сообщений, которые "пропустили" свою очередь - повышать приоритет на 1. Так получится, что очередь будет двигаться, приоритет примерно будет соблюдаться и расходы на обслуживание очереди не будут зависеть от величины очереди. -------------------- Человеку свойственно ошибаться, программисту свойственно ошибаться профессионально ! ![]() |
|||
|
||||
Akina |
|
|||
Советчик ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 20581 Регистрация: 8.4.2004 Где: Зеленоград Репутация: 20 Всего: 454 |
О том и речь... Допустим, некое сообщение категории "нахрен не надо" приходит на обработку. В полночь... очередь - на 8 часов. Соответственно мы назначаем этому сообщению время обработки 8:00... время идёт... и вот 8:00... и мы обрабатываем именно это сообщение, несмотря на то, что в очереди подпрыгивает парочка секунду назад пришедших сообщений с пометкой "супер-пупер-гипер-срочно". Это при условии, что очередь не переполняется. Если же она переполняется, вместо времени вводим синтетику, которая позволяет дробить любой интервал, тем самым устанавливая нужный порядок обработки. Или, как вариант (который мне лично нравится меньше), вводим динамическую важность сообщения, которая зависит от исходной важности и времени сидения под дверью кабинета обработчика. Главная идея - если было принято решение, что сообщение А обрабатывается раньше сообщения Б, то это решение окончательно и ничем не может быть изменено. -------------------- О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума. |
|||
|
||||
_Y_ |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1651 Регистрация: 27.11.2006 Репутация: 8 Всего: 34 |
Так, вроде бы, формула
p = ( L * (t - t0)/(tl - t0) ) * K / k и обеспечивает отсутствие застревания для любого, даже самого медленного, элемента. С одной стороны мы забираем элементы и знаменатель (tl - t0) все время уменьшается. С другой стороны, каждый следующий элемент добавляется через какое-то время после предидущего. Значит t все время растет по сравнению с постоянным tl(i) некоего медленного элемента. Рано или поздно даже элементы с самым большим приоритетом будут встваляться после этого i-того медленного. -------------------- Я вот в этом поучаствовал: http://sbor-nik.appspot.com/kick.jsp?id=sbor5737960678883328 (на правах саморекламы:) |
|||
|
||||
![]() ![]() ![]() |
Правила форума "Алгоритмы" | |
|
Форум "Алгоритмы" предназначен для обсуждения вопросов, связанных только с алгоритмами и структурами данных, без привязки к конкретному языку программирования и/или программному продукту.
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, maxim1000. |
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | Алгоритмы | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |