Жадный алгоритм (greedy algorithm) на каждом шаге делает выбор, который выглядит лучшим сейчас, и никогда его не пересматривает.
Зачем нужно
Жадный алгоритм прост и быстр: никакой таблицы, один проход. Когда он верен, это лучшее решение. Беда в том, что верен он не всегда, и это надо доказывать для каждой задачи.
Как работает
Пример с лекции — выдать сумму наименьшим числом монет.
Жадно:
- сортируем номиналы по убыванию;
- берём максимальную монету, пока имеет смысл.
Номиналы , сумма 6:
Динамика: , — см. Динамическое программирование.
Не из лекции: где жадность ошибается
Оптимальный ответ — две монеты: . На доске он не записан, но ради него пример и приводится. Проверено запуском: ДП даёт , жадность — 3.
Жадный алгоритм взял четвёрку, потому что она крупнее тройки. А остаток 2 из набирается только двумя единицами. Пересмотреть первый выбор жадность не умеет. Динамика перебирает все варианты последней монеты, поэтому находит 3 + 3.
Тонкости
Не из лекции
- Для «обычных» номиналов жадный размен оптимален. Это свойство набора монет, а не алгоритма: добавьте номинал 4 к — и сумма 6 снова ломает жадность.
- Чтобы доверять жадному алгоритму, нужно доказательство: обычно — что любое оптимальное решение можно перестроить так, чтобы оно начиналось с жадного выбора, не ухудшив его.
- Время жадного размена — после сортировки номиналов, у ДП — . Жадность выигрывает, когда она верна.
Частые ошибки
- Считать, что «самая крупная монета» — всегда правильный первый шаг.
- Проверить жадный алгоритм на паре удобных примеров и не искать контрпример.