Жадный алгоритм![]() Жадный алгоритм (англ. Greedy algorithm) — алгоритм, заключающийся в принятии локально оптимальных решений на каждом этапе, допуская, что конечное решение также окажется оптимальным. Известно, что если структура задачи задается матроидом, тогда применение жадного алгоритма выдаст глобальный оптимум. Если глобальная оптимальность алгоритма имеет место практически всегда, его обычно предпочитают другим методам оптимизации, таким как динамическое программирование. Условия применимостиОбщего критерия оценки применимости жадного алгоритма для решения конкретной задачи не существует, однако для задач, решаемых жадными алгоритмами, характерны две особенности: во-первых, к ним применим Принцип жадного выбора, а во-вторых, они обладают свойством Оптимальности для подзадач. Принцип жадного выбораГоворят, что к оптимизационной задаче применим принцип жадного выбора, если последовательность локально оптимальных выборов даёт глобально оптимальное решение. В типичном случае доказательство оптимальности следует такой схеме:
Оптимальность для подзадачГоворят, что задача обладает свойством оптимальности для подзадач для выведения результата, если оптимальное решение задачи содержит в себе оптимальные решения для всех её подзадач. Например, в задаче о выборе заявок можно заметить, что если — оптимальный набор заявок, содержащий заявку номер 1, то — оптимальный набор заявок для меньшего множества заявок , состоящего из тех заявок, для которых . ПримерыРазмен монетЗадача. Монетная система некоторого государства состоит из монет достоинством . Требуется выдать сумму наименьшим возможным количеством монет. Жадный алгоритм решения этой задачи таков. Берётся наибольшее возможное количество монет достоинства : . Таким же образом получаем, сколько нужно монет меньшего номинала, и т. д. Для данной задачи жадный алгоритм не всегда даёт оптимальное решение, а только для некоторых, называемых каноническими, монетных систем, вроде используемых в США (1, 5, 10, 25 центов). Неканонические системы таким свойством не обладают. Так, например, сумму в 24 копейки монетами в 1, 5 и 7 коп. жадный алгоритм разменивает так: 7 коп. — 3 шт., 1 коп. — 3 шт., в то время как правильное решение — 7 коп. — 2 шт., 5 коп. — 2 шт.[1] Выбор заявокФормулировка № 1. Даны заявок на проведение занятий в некоторой аудитории. В каждой заявке указаны начало и конец занятия ( и для -й заявки). В случае пересечения заявок можно удовлетворить лишь одну из них. Заявки с номерами и совместны, если интервалы и не пересекаются (то есть или ). Задача о выборе заявок состоит в том, чтобы набрать максимальное количество совместных друг с другом заявок. Формулировка № 2. На конференции, чтобы отвести больше времени на неформальное общение, различные секции разнесли по разным аудиториям. Учёный с чрезвычайно широкими интересами хочет посетить несколько докладов, проходящих в разных секциях. Известно начало и конец каждого доклада. Определить, какое максимальное количество докладов можно посетить. Приведём жадный алгоритм, решающий данную задачу. При этом полагаем, что заявки упорядочены в порядке возрастания времени окончания. Если это не так, то можно отсортировать их за время ; заявки с одинаковым временем конца располагаем в произвольном порядке. Функция на языке Python: def activity_selector(s, f):
n = len(s) # количество занятий
A = [0] # включаем первое занятие (предполагается, что занятия отсортированы по времени окончания)
j = 0 # индекс последней выбранной активности
for i in range(1, n):
if s[i] >= f[j]: # если текущее занятие начинается после окончания последнего выбранного
A.append(i) # добавляем его в список выбранных
j = i # обновляем индекс последней выбранной активности
return A
На вход данному алгоритму подаются массивы начала и окончания занятий. Множество A состоит из номеров выбранных заявок, а j — номер последней заявки. Жадный алгоритм ищет заявку, начинающуюся не ранее окончания j-й, затем найденную заявку включает в A, а j присваивает её номер. Таким образом, каждый раз мы выбираем то (ещё не начавшееся) занятие, до конца которого осталось меньше всего времени. Алгоритм работает за , то есть сортировка плюс выборка. На каждом шаге выбирается наилучшее решение. Покажем, что в итоге получится оптимум. Доказательство. Заметим, что все заявки отсортированы по неубыванию времени окончания. Заявка номер 1, очевидно, входит в оптимум (если нет, то заменим самую раннюю заявку в оптимуме на неё, от этого хуже не станет). Выкинув все заявки, противоречащие первой, получим исходную задачу с меньшим количеством заявок. Рассуждая по индукции, аналогичным образом приходим к оптимальному решению. Другие жадные алгоритмы
Обобщением жадных алгоритмов является алгоритм Радо — Эдмондса. Задачи, в которых жадные алгоритмы не дают оптимального решенияДля ряда задач, относящихся к классу NP, жадные алгоритмы не дают оптимального решения. К ним относятся:
Тем не менее, в ряде задач жадные алгоритмы дают неплохие приближённые решения. См. такжеПримечания
Литература
Ссылки
|
Portal di Ensiklopedia Dunia