23
Анализ комбинаторных алгоритмов Лекция №9 Жадные алгоритмы

Лекция 9 Жадные алгоритмы

Embed Size (px)

Citation preview

Page 1: Лекция 9 Жадные алгоритмы

Анализ комбинаторных алгоритмов

Лекция №9Жадные алгоритмы

Page 2: Лекция 9 Жадные алгоритмы

Жадные алгоритмы

Для многих оптимизационных задач можно предложить более простые и быстрые алгоритмы, чем построенные с использованием динамического программирования.

Жадный алгоритм – это алгоритм, делающий на каждом шаге локально оптимальный выбор, в расчете на то, что итоговое решение тоже окажется оптимальным.

Page 3: Лекция 9 Жадные алгоритмы

Задача о выборе заявок

Пусть даны n заявок на проведение занятий в аудитории.

Два разных занятия в аудитории не могут перекрываться во времени.

В каждой заявке указаны время начала и время конца занятия (s и f ).

Разные заявки могут перекрываться и тогда можно удовлетворить только одну из них.

Page 4: Лекция 9 Жадные алгоритмы

Задача о выборе заявок

Заявки i и j совместны, если интервалы [si,fi) и [sj,fj) не пересекаются (fi <= sj или fj <= si).

Задача о выборе заявок состоит в том, чтобы набрать максимальное количество совместных друг с другом заявок.

Page 5: Лекция 9 Жадные алгоритмы

Задача о выборе заявок

Жадный алгоритм работает в два этапа:

Сортирует заявки по возрастанию времени окончания занятия.

Выбирает первую заявку. После этого выбирает первую совместную с выбранной на предыдущем шаге заявку.

Page 6: Лекция 9 Жадные алгоритмы

Задача о выборе заявок

void GreedyActivitySelector(s,f){ n = length(s); A->Add(1); j = 1; for (i=2; i<=n; i++) { if (s[i]>=f[j]){ A->Add(i); j = i; } }}

1 2 3 4 5 6 7 8 9 10 11 12

1

23

54

67

8

Page 7: Лекция 9 Жадные алгоритмы

Задача о выборе заявок

Теорема.В задаче выбора заявок жадный алгоритм дает оптимальное решение.

Жадный алгоритм дает оптимальное решение не для всех задач.

Page 8: Лекция 9 Жадные алгоритмы

Применимость жадных алгоритмов

Существуют две особенности, характерные для задач, решаемых жадными алгоритмами: Принцип жадного выбора. Говорят, что к задаче

применим принцип жадного выбора, если последовательность локально оптимальных (жадных) выборов дает глобально оптимальное решение. Применимость принципа жадного выбора доказывается для каждой задачи отдельно.

Принцип оптимальности для подзадач. Оптимальное решение задачи содержит в себе оптимальные решения подзадач.

Page 9: Лекция 9 Жадные алгоритмы

Применимость жадных алгоритмов

И жадные алгоритмы и динамическое программирование основываются на свойстве оптимальности для подзадач.

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

Page 10: Лекция 9 Жадные алгоритмы

Применимость жадных алгоритмов

Дискретная задача о рюкзакеПусть вор пробрался на склад, на котором хранится n вещей. Вещь с номером I стоит v рублей весит w килограмм. Максимальный вес, который он может унести, равен W. Вещи ломать и дробить нельзя. Какие вещи должен положить в рюкзак вор, чтобы получить больше денег?

Непрерывная задача о рюкзаке.Отличается от дискретной тем, что вор может дробить вещи и от этого они своей ценности не теряют.

Page 11: Лекция 9 Жадные алгоритмы

Применимость жадных алгоритмов

Обе задачи обладают свойством оптимальности для подзадач. Вынув вещь j из оптимально загруженного рюкзака, получим решение для подзадачи с максимальным весом W- wj и набором из n-1 вещей. Аналогично для непрерывной задачи.

Жадный алгоритм дает оптимальное решение для непрерывной задачи, но не дает для дискретной.

Page 12: Лекция 9 Жадные алгоритмы

Применимость жадных алгоритмов

5 кг

10 кг

7 кг

Непрерывная задача

30 $/кг

20 $/кг

10 $/кг

5

1017

1020

30

6 $/кг 5 $/кг 4 $/кг

50

10

20

20

$160 $220

30

Дискретная задача

Page 13: Лекция 9 Жадные алгоритмы

Коды Хаффмана

Для сжатия информации широко используются коды Хаффмана.

Степень сжатия информации с помощью кода Хаффмана составляет 20 - 90%, в зависимости от типа сжимаемой информации.

Алгоритм Хаффмана находит оптимальные коды символов (исходя из частоты их использования в тексте) с помощью жадного выбора.

Page 14: Лекция 9 Жадные алгоритмы

Коды Хаффмана

Пусть в файле известны частоты символов. Каждый символ может быть представлен

двоичным кодом (конечной последовательностью бит, называемых словом).

При использовании равномерного кода на каждый символ будет тратиться одинаковое количество бит.

Неравномерный код будет эффективнее равномерного, если часто встречающиеся символы заменить короткими последовательностями бит, а редко встречающиеся – длинными.

Page 15: Лекция 9 Жадные алгоритмы

Коды Хаффмана

a b c d e f

Частоты в тыс. 45 13 12 16 9 5

Равномерный код 000 001 010 011 100 101

Неравномерный код 0 101 100 111 1101 1100

Для файла из 100 000 символов размер будет составлять:При равномерном кодировании: 100 000 * 3 = 300 000При неравномерном кодировании: (45*1+13*3+12*3+16*3+9*4+5*4)*1000 = 224 000

Page 16: Лекция 9 Жадные алгоритмы

Коды Хаффмана

0 1

0 1 0

a b c d e f

0 0 01 1 1

0 1

1

10a

e

d

f

c b

0

0

110

Page 17: Лекция 9 Жадные алгоритмы

Коды Хаффмана

Для того чтобы декодирование неравномерного кода можно было однозначно осуществить слева направо, код должен быть префиксным.

В префиксном коде ни одна из последователь-ностей бит, представляющих символы не является префиксом другой.

Для эффективной реализации декодирования можно представить код в виде двоичного дерева, листьями которого являются символы.

Оптимальный код будет представлен деревом, у которого каждая вершина (кроме листьев) имеет двух детей.

Page 18: Лекция 9 Жадные алгоритмы

Коды Хаффмана

Хаффман построил жадный алгоритм строящий оптимальный префиксный код (код Хаффмана).

Алгоритм строит двоичное дерево кода, снизу вверх, начиная с листьев и делая n-1 «слияний».

В результате слияния получается внутренняя вершина, частота которой равна сумме частот сливаемых объектов.

Page 19: Лекция 9 Жадные алгоритмы

Коды Хаффмана

f:5 e:9 c:12 b:13 d:16 a:45

f:5 e:9

c:12 b:13 d:16 a:4514

Шаг 1

Шаг 2

Page 20: Лекция 9 Жадные алгоритмы

Коды Хаффмана

f:5 e:9 c:12 b:13

d:16 a:4514

Шаг 3

25

f:5 e:9

c:12 b:13 d:16

a:45

14

Шаг 4

25 30

Page 21: Лекция 9 Жадные алгоритмы

Коды Хаффмана

f:5 e:9

c:12 b:13 d:16

a:45

14

Шаг 5

25 30

55

Page 22: Лекция 9 Жадные алгоритмы

Коды Хаффмана

f:5 e:9

c:12 b:13 d:16

a:45

14

Шаг 6

25 30

55

1000 1

0

0 0

0

1

1

1

Page 23: Лекция 9 Жадные алгоритмы

Коды Хаффмана

void Huffman(C){ n = length(C); Q->Create(C); for (i=1; i<n; i++) {

z = new NODE;x = Q->ExtractMin();y = Q->ExtractMin();z->left = x;z->right = y;z->freq = x->freq + y->freq;Q->Insert(z);

} return Q->ExtractMin();}