d-кучи и их применение
TRANSCRIPT
D-кучи и их применение
Ражева Н.С., Цыганова А.О.Кафедра математического обеспечения ЭВМ
Нижегородский государственный университетим. Н.И. Лобачевского
Факультет Вычислительной математики и кибернетики
Содержание d-кучи
Общие понятия Структура хранения Основные утверждения
Реализация d-кучи Основные операции
Применение d-куч Сортировка с использованием d-куч Результаты экспериментов Алгоритм Дейкстры Приоритетная очередь
Обзор литературы
1. d-кучи
d-кучи: общие понятия…
Куча – представление взвешенного множества в виде корневого дерева, узлам которого ставятся во взаимно однозначное соответствие элементы рассматриваемого множества.
Соответствие между узлами дерева и элементами множества называется кучеобразным, если: ключ элемента, приписанного узлу, не превосходит ключей, приписанных его потомкам.
d-кучи: общие понятия… Завершенное d-арное дерево - корневое дерево. Свойства:
Каждый внутренний узел имеет ровно d потомков. Исключение - один узел, имеющий от 1 до d - 1 потомков
На глубине i ровно узлов ( ), k - глубина дерева;
Количество узлов глубины k в дереве глубины k варьируется от 1 до .
id 11 nk
kd
d-кучи: общие понятия
Глубина дерева – наибольшая глубина его узлов.
Глубина узла – число ребер в кратчайшем пути от корня до данного узла.
Высота узла - расстояние от него до наиболее далекого потомка.
d-кучи: структура хранения… Каждому узлу дерева приписываем по одному
элементу исходного массива Сохраняем кучеобразный порядок Номеруем узлы:
Корень получает номер 0; Потомки узла с номером i получают номера
от до . Для узла в позиции i родительский узел
расположен в позиции div d.
ddi 1di
1i
d-кучи: структура хранения…
…… …1 …
0
2 d
…
…… …
………
i i+1
Уровень 0
Уровень 1
Уровень j
Уровень j+1
…
…i*d+1 i*d+2 i*d+d
(i-1)*d+d
0 n-1
d-кучи: структура хранения…
1 ……… …
0
2 d
…
…… …
………
i i+1
Уровень 0
Уровень 1
Уровень j
Уровень j+1
…
…i*d+1 i*d+2 i*d+d
(i-1)*d+d
0
0n-1
d-кучи: структура хранения…
1 ……… …
0
2 d
…
…… …
………
i i+1
Уровень 0
Уровень 1
Уровень j
Уровень j+1
…
…i*d+1 i*d+2 i*d+d
(i-1)*d+d
0
0 1n-1
d-кучи: структура хранения…
1 ……… …
0
2 d
…
…… …
………
i i+1
Уровень 0
Уровень 1
Уровень j
Уровень j+1
…
…i*d+1 i*d+2 i*d+d
(i-1)*d+d
0
20 1n-1
d-кучи: структура хранения…
1 ……… …
0
2 d
…
…… …
………
i i+1
Уровень 0
Уровень 1
Уровень j
Уровень j+1
…
…i*d+1 i*d+2 i*d+d
(i-1)*d+d
0
20 1 … dn-1
d-кучи: структура хранения…
1 ……… …
0
2 d
…
…… …
………
i i+1
Уровень 0
Уровень 1
Уровень j
Уровень j+1
…
…i*d+1 i*d+2 i*d+d
(i-1)*d+d
0
20 1 … d i…n-1
d-кучи: структура хранения…
1 ……… …
0
2 d
…
…… …
………
i i+1
Уровень 0
Уровень 1
Уровень j
Уровень j+1
…
…i*d+1 i*d+2 i*d+d
(i-1)*d+d
0
20 1 … d i… i+1n-1
d-кучи: структура хранения…
1 ……… …
0
2 d
…
…… …
………
i i+1
Уровень 0
Уровень 1
Уровень j
Уровень j+1
…
…i*d+1 i*d+2 i*d+d
(i-1)*d+d
0
… … …20 1 … d … i+1 … i*d+1in-1
d-кучи: структура хранения…
1 ……… …
0
2 d
…
…… …
………
i i+1
Уровень 0
Уровень 1
Уровень j
Уровень j+1
…
…i*d+1 i*d+2 i*d+d
(i-1)*d+d
0
20 1 … d … i+1 … i*d+1 i*d+2in-1
d-кучи: структура хранения…
1 ……… …
0
2 d
…
…… …
………
i i+1
Уровень 0
Уровень 1
Уровень j
Уровень j+1
…
…i*d+1 i*d+2 i*d+d
(i-1)*d+d
0
20 1 … d … i+1 … i*d+1 i*d+2 i*d+d…in-1
d-кучи: структура хранения…
1 ……… …
0
2 d
…
…… …
………
i i+1
Уровень 0
Уровень 1
Уровень j
Уровень j+1
…
…i*d+1 i*d+2 i*d+d
(i-1)*d+d
0 n-1
20 1 … d … i+1 … i*d+1 i*d+2 i*d+d…i … n-1
d-кучи: структура хранения…
Пример: n = 8, d = 3
key[n] = [2, 2, 4, 5, 5, 6, 6, 5]2
2 4 5
5 6 6 5
0
1
5
2
4
3
76
d-кучи: основные утверждения
Утверждение 1: Длина h пути из корня завершенного d-арного дерева с n > 1 узлами в любой лист удовлетворяет неравенствам:
Утверждение 2: Количество узлов высоты h не превосходит .
1log1log nhn dd
hdn
2. Реализация d-кучи.Основные операции
d-кучи: основные операции
Основные операции над d-кучами: Всплытие Погружение Вставка Удаление Уменьшение ключа Окучивание
Основные операции: Всплытие(i)… Всплытие(i)
Применяется для элемента x в узле i , нарушающего кучеобразный порядок, т.е если ключ элемента меньше ключа родителя.
Procedure Всплытие(i)begin
p := (i-1)div dwhile (i≠0) and (key[p]>key[i]) do
begintr(i,p);i:= p; p:=(i-1)div d
end;end;
Вычислительная сложность: )(log nO d
Основные операции: Всплытие(i)…Пример: d = 3, n = 8
7
7 6 9
9 6 8 7
0
1
5
2
4
3
76
Основные операции: Всплытие(i)…Пример: d = 3, n = 8
7
7 8 9
9 6 8 9
0
1
5
2
4
3
76
!!!
Основные операции: Всплытие(i)…Пример: d = 3, n = 8
7
7 8 9
9 6 8 9
0
1
5
2
4
3
76
Основные операции: Всплытие(i)…Пример: d = 3, n = 8
7
6 8 9
9 7 8 9
0
1
5
2
4
3
76
Основные операции: Всплытие(i)…Пример: d = 3, n = 8
7
6 8 9
9 7 8 9
0
1
5
2
4
3
76
!!!
Основные операции: Всплытие(i)…Пример: d = 3, n = 8
7
6 8 9
9 7 8 9
0
1
5
2
4
3
76
Основные операции: Всплытие(i)Пример: d = 3, n = 8
6
7 8 9
9 7 8 9
0
1
5
2
4
3
76
Основные операции: Погружение(i)… Погружение(i)
Применяется для элемента x в узле i , нарушающего кучеобразный порядок, т.е если ключ элемента больше ключа потомка.
Вспомогательная функция min_child(i):Function min_child(i)begin
if (i*d+1>=n) return 0;elsebegin
s:=i*d+1; min_key:=key[s]; last:=(i+1)*d;if (last>=n) last:=n-1;for j:=s+1 to j:=last dobegin
if (min_key > key[j]) min_key=key[j]; s=j;return s;
end; end;
Основные операции: Погружение(i)…
Procedure Погружение(i)begin
s:=min_child(i);while (s≠0) and (key[i]>key[s])
begintr(i,s);i:=s;s:=min_child(i);
end;end;
Вычислительная сложность: )log( ndO d
Основные операции: Погружение(i)…Пример: d = 3, n = 8
8
7 6 9
9 7 8 7
0
1
5
2
4
3
76
Основные операции: Погружение(i)…Пример: d = 3, n = 8
8
7 6 9
9 7 8 7
0
1
5
2
4
3
76
!!!
Основные операции: Погружение(i)…Пример: d = 3, n = 8
8
7 6 9
9 7 8 7
0
1
5
2
4
3
76
Основные операции: Погружение(i)…Пример: d = 3, n = 8
6
7 8 9
9 7 8 7
0
1
5
2
4
3
76
Основные операции: Погружение(i)…Пример: d = 3, n = 8
6
7 8 9
9 7 8 7
0
1
5
2
4
3
76
!!!
Основные операции: Погружение(i)…Пример: d = 3, n = 8
6
7 8 9
9 7 8 7
0
1
5
2
4
3
76
Основные операции: Погружение(i)Пример: d = 3, n = 8
6
7 7 9
9 7 8 8
0
1
5
2
4
3
76
Основные операции: Вставка(key_insert) Вставка(key_insert):
Добавление n+1 узла с номером n; Применение операции Всплытие(n).
Procedure Вставка(key_insert)begin
key[n]:=key_insert;ВСПЛЫТИЕ(n);n:=n+1;
end;
Вычислительная сложность: )(log nO d
Основные операции: Вставка(key_insert)
6
7 8 9
9 7 8
0
1
5
2
4
3
6
Пример: d = 3, n = 7
Основные операции: Вставка(key_insert)
6
7 8 9
9 7 8
0
1
5
2
4
3
36
Пример: d = 3, n = 7 Добавление элемента:
Основные операции: Вставка(key_insert)
6
7 8 9
9 7 8
0
1
5
2
4
3
376
Пример: d = 3, n = 7
n = n+1
Добавление элемента:
Основные операции: Вставка(key_insert)
6
7 8 9
9 7 8
0
1
5
2
4
3
376
Пример: d = 3, n = 7 Всплытие:
!!!
Основные операции: Вставка(key_insert)
6
7 8 9
9 7 8
0
1
5
2
4
3
376
Пример: d = 3, n = 7 Всплытие:
Основные операции: Вставка(key_insert)
6
7 3 9
9 7 8
0
1
5
2
4
3
876
Пример: d = 3, n = 7 Всплытие:
Основные операции: Вставка(key_insert)
6
7 3 9
9 7 8
0
1
5
2
4
3
876
Пример: d = 3, n = 7 Всплытие:
!!!
Основные операции: Вставка(key_insert)
6
7 3 9
9 7 8
0
1
5
2
4
3
876
Пример: d = 3, n = 7 Всплытие:
Основные операции: Вставка(key_insert)
3
7 6 9
9 7 8
0
1
5
2
4
3
876
Пример: d = 3, n = 7 Всплытие:
Основные операции: Удаление(i) Удаление(i):
Перенести последний элемент на место удаляемого элемента с номером i;
Если узел i имеет родителя с большим ключом, то применяется операции Всплытие(i), иначе операция Погружение(i)
Procedure Удаление(i)begin
key[i]:=key[n-1]; n:=n-1;if (i≠0) and (key[i]<key[(i-1)div d] then ВСПЛЫТИЕ(i)else ПОГРУЖЕНИЕ(i);
end;
Вычислительная сложность: )log( ndO d
Основные операции: Удаление(i)
6
7 8 9
9 7 8
0
1
5
2
4
3
376
Пример: d = 3, n = 8, i = 1
Основные операции: Удаление(i)
6
7 8 9
9 7 8
0
1
5
2
4
3
376
Пример: d = 3, n = 8, i = 1
Основные операции: Удаление(i)
6
7 8 9
9 7 8
0
1
5
2
4
3
376
Пример: d = 3, n = 8, i = 1
Основные операции: Удаление(i)
6
3 8 9
9 7 8
0
1
5
2
4
3
76
Пример: d = 3, n = 8, i = 1 Удаление:
n = n-1
Основные операции: Удаление(i)
6
3 8 9
9 7 8
0
1
5
2
4
3
6
Пример: d = 3, n = 8, i = 1 Всплытие:
!!!
n = n-1
Основные операции: Удаление(i)
6
3 8 9
9 7 8
0
1
5
2
4
3
6
Пример: d = 3, n = 8, i = 1 Всплытие:
n = n-1
Основные операции: Удаление(i)
3
6 8 9
9 7 8
0
1
5
2
4
3
6
Пример: d = 3, n = 8, i = 1 Всплытие:
n = n-1
Основные операции: Уменьшение_ключа(i,k) Уменьшение_ключа(i,k):
Уменьшить ключ элемента в узле i на заданную константу
k = const ; Выполнить операцию Всплытие(i).
Procedure Уменьшение_ключа(i,k)
beginkey[i]:=key[i]-k;ВСПЛЫТИЕ(i);
end;
Вычислительная сложность: )(log nO d
Основные операции: Уменьшение_ключа(i,k)
6
7 8 9
9 7 8
0
1
5
2
4
3
976
Пример: d = 3, n = 8, i = 2, k = 3
Уменьшение ключа:
Основные операции: Уменьшение_ключа(i,k)
6
7 5 9
9 7 8
0
1
5
2
4
3
976
Пример: d = 3, n = 8, i = 2, k = 3
!!!
Всплытие:
Основные операции: Уменьшение_ключа(i,k)
6
7 5 9
9 7 8
0
1
5
2
4
3
976
Пример: d = 3, n = 8, i = 2, k = 3
Всплытие:
Основные операции: Уменьшение_ключа(i,k)
5
7 6 9
9 7 8
0
1
5
2
4
3
976
Пример: d = 3, n = 8, i = 2, k = 3
Всплытие:
Основные операции: Окучивание Окучивание:
Применение операции Погружение(i) по очереди к узлам .
Procedure Окучивание
beginfor i:=(n-1)/d downto 0 do ПОГРУЖЕНИЕ(i);
end;
Вычислительная сложность: )(nO
0,,1 n
Утверждение 3. Вычислительная сложность операции ОКУЧИВАНИЕ равна
Доказательство.1. Трудоемкость погружения с высоты i равна O(i);2. Число узлов высоты i не превосходит3. Суммарная трудоемкость окучивания:
, где - высота d-арного дерева с n узлами.
Основные операции: Окучивание
hh 2
1...21...
161
81
)(nO
idn
h
oiid
ni
nh dlog
h
ihi
h
oii
hidi
0 2...
83
42
210
2
hh 2
1...81
41
21...
41
21
consth 22
1...41
211 1
Т.о.,
h
oiid
ni
nOn 2
3. Применение d-куч3.1. Сортировка массива
Сортировка массива…
Задача сортировки с использованием d-куч:
Требуется упорядочить массив key[n] по неубыванию, путем перестановки его элементов с
использованием d- кучи.
На выходе требуется получить последовательностьkey[1] key[2] … key[n].
Сортировка массива… Алгоритм сортировки с использованием d-куч:
Применение операции Погружение(i) по очереди к узлам (Окучивание);
Обмен первого и последнего элемента кучи: уменьшение размера кучи на 1;
Применение операции погружения к первому элементу кучи.
Повторение описанных операций до тех пор, пока размер кучи не будет равен 1.
0,),1( n
В результате к моменту выполнения всех операций получаем массив упорядоченный по невозрастанию. Далее массив следует упорядочить по неубыванию.
Сортировка массива… Реализация сортировки с использованием d-куч:
Procedure Heap_Sort(n);
beginОКУЧИВАНИЕ;k = n-1;while (k > 0) begin
tr(0, k); k = k - 1; ПОГРУЖЕНИЕ(0);end;for i:=0 to (n mod 2)do tr(i,n-1-i);
end;
Вычислительная сложность: )log( nnO d
Недостатки сортировки с помощью d-кучи
Алгоритм является неустойчивым (меняет взаимное расположение равных элементов)
Алгоритм является неестественным (частичная упорядоченность массива никак не учитывается)
Достоинства сортировки с помощью d-кучи
Не использует дополнительной памяти, размер которой зависит от длины сортируемого массива
Даже в среднем, а так же в лучшем и худшем случаях сортировка имеет трудоемкость
Сортировка массива
)log( nnO d
3. Применение d-куч3.2. Результаты экспериментов
Вычислительные эксперименты
нижняя граница значений элементов q = 1
верхняя граница значений элементов w = 10000
размер массива с шагом
Вычислительный эксперимент…
110,1 6 n 410
Вычислительный эксперимент…Сортировка с помощью D-кучи
0,00,10,20,30,40,50,60,70,80,91,01,11,21,31,41,5
1
5000
1
1000
01
1500
01
2000
01
2500
01
3000
01
3500
01
4000
01
4500
01
5000
01
5500
01
6000
01
6500
01
7000
01
7500
01
8000
01
8500
01
9000
01
9500
01
1000
001
Количество элементов в массиве
Врем
я, с
ек.
2-heap3-heap4-heap5-heap6-heap7-heap8-heap9-heap10-heap11-heap
Вычислительный эксперимент… Сравнение сортировок с помощью d-куч с Quick_Sort
Сортировка с помощью D-кучи и Quick_Sort
0,00,10,20,30,40,50,60,70,80,91,01,11,21,31,41,5
1
5000
1
1000
01
1500
01
2000
01
2500
01
3000
01
3500
01
4000
01
4500
01
5000
01
5500
01
6000
01
6500
01
7000
01
7500
01
8000
01
8500
01
9000
01
9500
01
1000
001
Количество элементов в массиве
Врем
я, с
ек.
2-heap
3-heap
4-heap
5-heap
6-heap
7-heap
8-heap
9-heap
10-heap
11-heap
Quick Sort
Вычислительный эксперимент…График зависимости времени от d (при n= ).610
Анализ сортировки с помощью 7-кучи
7-heap
0,0
0,1
0,2
0,3
0,4
0,5
0,6
0,7
0,8
1
4000
1
8000
1
1200
01
1600
01
2000
01
2400
01
2800
01
3200
01
3600
01
4000
01
4400
01
4800
01
5200
01
5600
01
6000
01
6400
01
6800
01
7200
01
7600
01
8000
01
8400
01
8800
01
9200
01
9600
01
1000
00
7-heap
Анализ сортировки с помощью 7-кучи
7-heap
0,0
0,1
0,2
0,3
0,4
0,5
0,6
0,7
0,8
1
4000
1
8000
1
1200
01
1600
01
2000
01
2400
01
2800
01
3200
01
3600
01
4000
01
4400
01
4800
01
5200
01
5600
01
6000
01
6400
01
6800
01
7200
01
7600
01
8000
01
8400
01
8800
01
9200
01
9600
01
1000
00
7-heapax+b
Построение МНК с помощью прямой
Анализ сортировки с помощью 7-кучи
Проверим, является ли наша теоретическая оценка о трудоемкости алгоритма сортировки с помощью d-кучи верной на практике.
Поделим полученное время на nn dlog
Анализ сортировки с помощью 7-кучиx(n)/(n*logn)
0
0,00000002
0,00000004
0,00000006
0,00000008
0,0000001
0,00000012
0,00000014
3000
1
1300
01
2300
01
3300
01
4300
01
5300
01
6300
01
7300
01
8300
01
9300
01
x(n)/(n*logn)
С ростом длинны массива зависимость между x и у становится похожей на линейную.
Анализ сортировки с помощью 7-кучи
С использованием с = 1,05Е-7 получаем более точное приближение. Делаем вывод, что зависимость между х и у n*logn.
7-heap
0,0
0,1
0,2
0,3
0,4
0,5
0,6
0,7
0,8
1
4000
1
8000
1
1200
01
1600
01
2000
01
2400
01
2800
01
3200
01
3600
01
4000
01
4400
01
4800
01
5200
01
5600
01
6000
01
6400
01
6800
01
7200
01
7600
01
8000
01
8400
01
8800
01
9200
01
9600
01
1000
00
7-heapax+bc*nlogn
Анализ сортировки с помощью 7-кучи7-heap
0,0
0,1
0,2
0,3
0,4
0,5
0,6
0,7
0,8
1
4000
1
8000
1
1200
01
1600
01
2000
01
2400
01
2800
01
3200
01
3600
01
4000
01
4400
01
4800
01
5200
01
5600
01
6000
01
6400
01
6800
01
7200
01
7600
01
8000
01
8400
01
8800
01
9200
01
9600
01
1000
00
7-heapc1*nlognc*nlogn
Было построено МНК приближение с помощью функции nn dlog
Аппаратная часть
3. Применение d-куч3.3. Алгоритм Дейкстры
Алгоритм Дейкстры…
d-кучи используются для ускорения алгоритма Дейкстры, который ищет минимальные пути в графе. Этот алгоритм применим только к взвешенным графам с неотрицательными весами.
Алгоритм ищет кратчайший путь от вершины ко всем вершинам.
Алгоритм Дейкстры… Алгоритм Дейкстры: Шаг 1.
Для каждой вершины введем метку, которую обозначим.
Тогда для вершины положим и будем считать эту метку постоянной. Для всех остальных вершин положим
и будем считать эти метки временными.За обозначим текущую вершину и положим .
Алгоритм Дейкстры…Шаг 2. Для всех вершин являющихся смежными с р и метки
которых временные, изменить метки в соответствии со следующим выражением:
Где - это вес дуги Шаг 3.Среди всех вершин с временными метками найти такую,
для которой
Множество можно организовать с помощью d-кучи, тогда поиск минимума будет происходить быстрее.
Алгоритм Дейкстры Шаг 4. Метку вершины сделаем постоянной и положим . Шаг 5.
Если все вершины отмечены постоянными метками, то эти метки дают длины кратчайших путей.
Если некоторые метки являются временными, то следует перейти к Шагу 2.
3. Применение d-куч3.4. Приоритетная очередь
Приоритетная очередь…
Приоритетная очередь - абстрактный тип данных, предназначенный для представления взвешенных множеств.
Взвешенное множество - каждому элементу множества однозначно соответствует число, называемое ключом или весом.
Приоритетная очередь: основные операции
Основные операции: ВСТАВИТЬ; НАЙТИ MIN или МАХ; УДАЛИТЬ.
Приоритетная очередь: применение…
Очереди с приоритетом могут использоваться в операционных системах разделения времени для хранения списка заданий с приоритетами.
После выполнения очередного задания из списка
выбирается задание с наибольшим приоритетом.
Приоритетная очередь: применение…
Приоритетные очереди также используются в управляемом событиями моделировании.
В данной очереди приоритетом является время, в которое событие должно произойти.
Каждый раз из очереди выбирается событие с минимальным временем.
Приоритетная очередь: применение
Приоритетные очереди могут использоваться в численных расчетах
Приоритетом является ошибка вычислений
Наиболее грубая ошибка обрабатывается в первую очередь
Обзор литературы Алексеев В.Е., Таланов В.А. Графы. Модели вычислений.
Структуры данных: Учебник. – Нижний Новгород ННГУ, 2005. - 307 с.
Кормен Т., Лейзерсон Ч., Ривест Р., Штайн К. Алгоритмы: построение и анализ. 2-е издание. – М.: Вильямс, 2010. – 1296 с.
Седжвик Р. Фундаментальные алгоритмы на С++. Анализ/Структуры данных/Сортировка/Поиск. – К.: ДиаСофт, 2001. – 688 с.
LaMarca A., Ladner R. The influence of Caches on the Performance of Heaps. – Seattle University of Washington, 1996. – 29 p.