Главная страница


ru.algorithms

 
 - RU.ALGORITHMS ----------------------------------------------------------------
 From : Oleg I. Khovayko                     2:5020/400     10 Mar 2003  19:56:14
 To : Dmitri Khanevski
 Subject : Re: быстрая вставка в очередь
 -------------------------------------------------------------------------------- 
 
 Dmitri Khanevski wrote:
 
 > 
 > В общем всем больше спасибо, после пpаздников еще подумаю, может чего в голову
 > и пpидет.
 
 Я вот тоже подумал, и кажется, нашел решение.
 Это нечто промежуточное между деревом и "кольцом выполнения",
 описанным ранее.
 
 Работать будет чуть помедленее, чем "кольцо выполнения",
 но и память не особо будет использовать.
 
 Вводная:
 Как известно, в дереве поиск (элемента или места вставки) 
 очень быстрый - Log(N). Множитель N возникает за счет затрат
 на перестройку дерева после ввода/удаления узла.
 Если же дерево не перестраивать, легко свалиться в N^2.
 
 Идея в следующем:
 Hадо бы хранить данные в таком дереве, которое не требуется
 перестраивать. Структура такого дерева ко мне пришла из анализа
 дерева ветвлений поразрядной обменной сортировки.
 
 Суть вот в чем:
 
 Согласно твоему условию, макс. задержка
 не может превышать 3.6 миллионов тиков. Такую задержку гарантировано
 можно вместить в двоичное число разрядностью 22.
 
 Введем понятие кольцевого времени. Кольцевое время - это 22 младших
 бита от абсолютного времени. 
 
 Предположим, что таймерный счетчик считает время в кольцевом времени,
 то есть вместо 2^22 он переходит в ноль.
 
 Допустим, у тебя есть заявка на время T (абсолютное). 
 Посредством битовой маски преобразовываем его в кольцевое.
 (неоднозначность от этого не возникает, так как apriori известно,
 что заявка лежит на ближайшее время из циклов 2^22), и таймерный счетчик 
 кольевого времени совпадет с текущим кольцевым временим в "истинный" 
 момент выполнения заявки.
 
 Рассмотрим биты int-a этого кольцевого времени (от старших к младшим) как 
 путь в дереве глубиной 22. То есть если тек. бит = 0 - идем к левому потомку, 
 если бит = 1 - к правому.
 
 В терминальных узлах дерева в указателях left/right
 лежат не потомки - узлы дерева, а головы линейных 
 списков заявок на данное время.
 
 Таймерная программа, выполняющая заявки, живет в кольцевом времени.
 По каждому тику, посчитав текущее кольцевое
 время, она пытается из дерева вынуть список заявок и выполнить его.
 После выполнения очередного списка заявок на тек время она
 освобождает список и уникальную для этого списка часть дерева. Причем дерево не
 перестраивается - от него просто "отпиливается ветка". Поэтому время
 такой операции в худшем случае O(22). Точка пиления тоже находится
 в процессе спуска по дереву, когда идем к тек. узлу.
 Точка пиления - это наинизший узел дерева, имеющий всех детей непустыми. 
 
 Вставка в такое дерево делается аналогично, за время в худшем случае O(22).
 Заявка вставляется в позицию, определяемую битовой цепочкой
 значения кольцевого времени этой заявки.
 
 Расходы по памяти на дерево также небольшие. В худшем случае это число 
 заявок Z умноженое на маск. глубину дерева, т.е. 500 * 22  = 11K.
 
 Выше я рассмотрел дерево "ветвистостью 2". Hа самом деле,
 дерево может быть "ветвистостью 4,8, etc".
 При этом для дерева "ветвистостью 4" каждый шаг в дереве будет соответствовать
 2-м битам int-a, то есть для такого дерева время/память будет О(11).
 Хотя конечно при этом сам размер элемента дерева вырастет, и по памяти
 ты проиграешь немного. Зато скорость подымешь.
 
 Замечу, что каждая ветка дерева имеет фиксированую глубину 22.
 Тогда из глубины дерева ты однозночно определяешь, на что указывает
 указатель потомка - на след. элемент дерева, либо же на лин. список заявок.
 
 PS. Можно оптимизировать:
 Hе дергать таймерную программу, каждый тик, чтобы она в дерево ходила, а сделать
 так:
 После выполнения заявок на тек время и освобождения списка/части дерева
 таймерная программа определяет путь в дереве к след. узлу, и представляет 
 его в виде int-a. После чего ложится спать на время t, равное разнице в 
 битовых путях между тек. узлом (что только что был удален) и вновь найденым 
 узлом. 
 
 Только в этом случае надо не забыть после вставки очередного нового узла дерева 
 (если элемент добавляем в уже готовый список, ничего делать не надо)
 проверить - а не находится новая заявка в текушем sleep-интервале.
 И в случае чего подкорректировать sleep-интервал, чтобы обработчик
 не проспал текущую заявку.
 
 -- 
 #include <best/regards.hpp>
 Oleg I. KHOVAYKO  
 (301)435-5885 || WEB: http://olegh.spedia.net
 --- ifmail v.2.15dev5
  * Origin: National Center for Biotechnology Information (2:5020/400)
 
 

Вернуться к списку тем, сортированных по: возрастание даты  уменьшение даты  тема  автор 

 Тема:    Автор:    Дата:  
 быстрая вставка в очередь   Dmitri Khanevski   07 Mar 2003 00:29:00 
 Re: быстрая вставка в очередь   Oleg I. Khovayko   07 Mar 2003 01:07:46 
 Re: быстрая вставка в очередь   Dmitri Khanevski   07 Mar 2003 09:59:43 
 Re: быстрая вставка в очередь   Oleg I. Khovayko   07 Mar 2003 19:59:18 
 Re: быстрая вставка в очередь   Dmitri Khanevski   07 Mar 2003 23:14:51 
 Re: быстрая вставка в очередь   Oleg I. Khovayko   07 Mar 2003 23:20:12 
 Re: быстрая вставка в очередь   Dmitri Khanevski   08 Mar 2003 11:15:11 
 Re: быстрая вставка в очередь   Oleg I. Khovayko   10 Mar 2003 19:56:14 
 Re: быстрая вставка в очередь   Dmitri Khanevski   10 Mar 2003 23:55:00 
 Re: быстрая вставка в очередь   Oleg I. Khovayko   10 Mar 2003 23:18:22 
 Re: быстрая вставка в очередь   Dmitri Khanevski   11 Mar 2003 10:13:11 
 Re: быстрая вставка в очередь   Oleg I. Khovayko   11 Mar 2003 20:10:36 
 Re: быстрая вставка в очередь   Val Krigan   07 Mar 2003 03:05:45 
 Re: быстрая вставка в очередь   Dmitri Khanevski   07 Mar 2003 10:11:53 
 Re: быстрая вставка в очередь   Val Krigan   07 Mar 2003 23:29:57 
Архивное /ru.algorithms/11522b86f1652.html, оценка 2 из 5, голосов 10
Яндекс.Метрика
Valid HTML 4.01 Transitional