Задача о рюкзакеЗадача о рюкзаке (также задача о ранце) — NP-полная задача комбинаторной оптимизации. Своё название получила от конечной цели: уложить как можно большее число ценных вещей в рюкзак при условии, что вместимость рюкзака ограничена. С различными вариациями задачи о рюкзаке можно столкнуться в экономике, прикладной математике, криптографии и логистике. В общем виде задачу можно сформулировать так: из заданного множества предметов со свойствами «стоимость» и «вес» требуется отобрать подмножество с максимальной полной стоимостью, соблюдая при этом ограничение на суммарный вес. Классическая постановка задачиПусть имеется набор предметов, каждый из которых имеет два параметра — масса и ценность. Также имеется рюкзак определённой грузоподъёмности. Задача заключается в том, чтобы собрать рюкзак с максимальной ценностью предметов внутри, соблюдая при этом ограничение рюкзака на суммарную массу. Математически задача формулируется следующим образом: имеется грузов. Для каждого -го груза определены его масса и ценность , . Ограничение суммарного веса предметов в рюкзаке задаётся грузоподъёмностью . Необходимо
Варианты задачи о рюкзакеПостановка задачи допускает большое количество обобщений, в зависимости от условий, наложенных на рюкзак, предметы или их выбор. Наиболее популярными разновидностями являются следующие:
Нелинейная задача о рюкзакеОдним из наиболее общих вариантов задачи о рюкзаке является нелинейный. Его можно сформулировать следующим образом: Пусть вектор определяет количество экземпляров каждого предмета в рюкзаке. Тогда задача состоит в нахождении минимума функции , при заданном ограничении: . Функции предполагаются непрерывными и дифференцируемыми на . — целочисленная константа, множество непусто[7]. В случае линейных функций , задача сводится к одной из классических постановок, в зависимости от множества :
Свобода в выборе функций позволяет решать более широкий класс задач, включая организацию производственных мощностей[англ.], оптимальное распределение семплов в районированной выборке или решение квадратичной задачи о рюкзаке[7]. Точные методы решенияКак было сказано выше, задача о рюкзаке относится к классу NP-полных, и для неё пока что не найден полиномиальный алгоритм, решающий её за разумное время. Поэтому при решении задачи о рюкзаке необходимо выбирать между точными алгоритмами, которые неприменимы для «больших» рюкзаков, и приближенными, которые работают быстро, но не гарантируют оптимального решения задачи. Полный переборКак и для других дискретных задач, задачу о рюкзаке можно решить, полностью перебрав все возможные решения. По условию задачи имеется предметов, которые можно укладывать в рюкзак, и нужно определить максимальную стоимость груза, вес которого не превышает . Для каждого предмета существует 2 варианта: предмет кладётся в рюкзак либо предмет не кладётся в рюкзак. Тогда перебор всех возможных вариантов имеет временну́ю сложность , что позволяет его использовать лишь для небольшого количества предметов[8]. С ростом числа предметов задача становится неразрешимой данным методом за приемлемое время. На рисунке показано дерево перебора для трёх предметов. Каждый лист соответствует некоторому подмножеству предметов. После составления дерева необходимо найти лист с максимальной ценностью среди тех, вес которых не превышает [9]. Метод ветвей и границМетод ветвей и границ является вариацией метода полного перебора с той разницей, что исключаются заведомо неоптимальные ветви дерева полного перебора. Как и метод полного перебора, он позволяет найти оптимальное решение и поэтому относится к точным алгоритмам. Оригинальный алгоритм, предложенный Питером Колесаром (англ. Peter Kolesar) в 1967 году, предлагает отсортировать предметы по их удельной стоимости (отношению ценности к весу) и строить дерево полного перебора. Его улучшение заключается в том, что в процессе построения дерева для каждого узла оценивается верхняя граница ценности решения, и продолжается построение дерева только для узла с максимальной оценкой[10]. Когда максимальная верхняя граница оказывается в листе дерева, алгоритм заканчивает свою работу. Способность метода ветвей и границ уменьшать количество вариантов перебора сильно опирается на входные данные. Его целесообразно применять, только если удельные ценности предметов значительно отличаются[11]. Методы динамического программированияЗадача о неограниченном рюкзакеПри дополнительном ограничении на веса предметов, задачу о рюкзаке можно решить за псевдополиномиальное время методами динамического программирования. Пусть вес каждого предмета является целым положительным числом. Тогда для решения задачи необходимо вычислить оптимальные решения для всех , где — заданная грузоподъемность. Определим как максимальную ценность предметов, которые можно поместить в рюкзак грузоподъемностью . Для можно записать рекуррентные формулы:
где — ценность и вес -го предмета соответственно, а максимум из пустого множества следует считать равным нулю. Фактически последнее уравнение является функциональным уравнением Р. Беллмана или функциональным уравнением динамического программирования. В данном случае для его решения достаточно вычислить все значения , начиная с и до [12]. Если дополнительно хранить на каждом шаге набор предметов, который реализует максимальную ценность, то алгоритм выдаст и оптимальный набор предметов. Так как на каждом шаге необходимо найти максимум из предметов, алгоритм имеет вычислительную сложность . Поскольку может зависеть экспоненциально от размера входных данных, алгоритм является псевдополиномиальным. Поэтому эффективность данного алгоритма определяется значением . Алгоритм даёт отличные результаты при , но не очень хорошие для [13]. Задача о рюкзаке 0-1Решение задачи о рюкзаке 0-1 близко к решению предыдущей задачи, но необходимо учесть тот факт, что каждый предмет имеется в единственном экземпляре. Пусть — максимальная ценность предметов, полученных из первых имеющихся предметов, с суммарным весом не превышающим .
Вычисляя , можно найти точное решение. Если массив помещается в памяти машины, то данный алгоритм, вероятно, является одним из наиболее эффективных[12]. // Ввод:
// Ценности предметов (загруженные в массив v)
// Веса предметов (загруженные в массив w)
// Количество предметов (n)
// Грузоподъемность (W)
for j from 0 to W do:
m[0, j] := 0
for i from 1 to n do:
for j from 0 to W do:
if w[i] > j then:
m[i, j] := m[i-1, j]
else:
m[i, j] := max(m[i-1, j], m[i-1, j-w[i]] + v[i])
Проиллюстрировать решение методом динамического программирования можно следующим образом: на двумерной плоскости по оси откладывается количество предметов, по оси — их вес. На первом шаге из начала координат строятся две линии: горизонтальная, соответствующая тому, что первый предмет не был взят, и наклонная, соответствующая взятому первому предмету. Их проекции на ось равны весу предмета. На втором шаге опять строятся 2 линии, горизонтальная (второй предмет не был взят) или наклонная (второй предмет взят). Положим длину горизонтальных дуг равной нулю, а наклонных — ценности предмета[14]. Таким образом, любому решению задачи соответствует некоторый путь в построенном дереве. Задача сводится к нахождению пути максимальной длины[14]. Пусть вместимость рюкзака .
Из рисунка видно, что суммарная ценность для оптимального решения равна 7, так как это максимальная ценность в построенном дереве. Динамическое программирование над ценностями предметовРекуррентные соотношения можно записывать не только относительно веса предметов, но также и относительно ценности. Для этого обозначим за минимальный вес предметов суммарной ценностью , который можно получить из первых предметов. Если необходимый вес получить невозможно, то отметим это как . После этого решим функциональное уравнение динамического программирования: ,
Приближенные методы решенияКак и для большинства NP-полных задач, не всегда необходимо получать точное решение, так как решения, близкие к оптимальным, могут применяться в прикладных задачах. Жадный алгоритмДля решения задачи жадным алгоритмом необходимо отсортировать вещи по их удельной ценности (то есть отношению ценности предмета к его весу), и поместить в рюкзак предметы с наибольшей удельной ценностью[10]. Время работы данного алгоритма складывается из времени сортировки и времени укладки. Сложность сортировки предметов составляет . Далее происходит вычисление того, сколько предметов поместится в рюкзак за общее время [10]. Итоговая сложность при необходимости сортировки и при уже отсортированных данных[10]. Пример. Пусть вместимость рюкзака . Предметы уже отсортированы по удельной ценности. Применим жадный алгоритм.
Кладём в рюкзак первый предмет, а за ним второй. Третий предмет в рюкзак не влезет. Суммарная ценность вещей в рюкзаке равна 150. Если бы были взяты второй и третий предметы, то суммарная ценность составила бы 190. Таким образом, мы получили некоторое неоптимальное решение. Следует понимать, что жадный алгоритм может привести к ответу, сколь угодно далёкому от оптимального. Например, если один предмет имеет вес 1 и стоимость 2, а другой — вес W и стоимость W, то жадный алгоритм наберёт итоговую стоимость 2 при оптимальном ответе W. При этом тот же алгоритм для неограниченной задачи о рюкзаке приведёт к ответу, составляющему не менее 50 % от ценности оптимального[10]. Впервые жадный алгоритм был предложен Джорджем Данцигом[16] для решения задачи о неограниченном рюкзаке. Приближенная схема полностью полиномиального времениТак как точного алгоритма решения задачи за полиномиальное время не было найдено, появилась задача получить полиномиальное решение с гарантированной точностью . Для этого существует целый ряд приближённых схем полностью полиномиального времени, то есть со сложностью, являющейся полиномом от и . Идея, стоящая за классической схемой, заключается в снижении точности, с которой заданы ценности предметов. Объединяя предметы близкой ценности в одну группу, можно снизить количество разных предметов. Алгоритм записывается следующим образом[15]:
Существует множество различных схем аппроксимации. Тем не менее, они сильно зависят от формулировки задачи о рюкзаке. Например, если в условии появляется второе ограничение типа неравенства (двухмерный рюкзак), то задача уже не имеет известной схемы полиномиального времени[17]. Генетические алгоритмыКак и для других NP-трудных задач оптимизации, для решения задачи о рюкзаке применяются генетические алгоритмы. Они не гарантируют нахождения оптимального решения за полиномиальное время и не дают оценку близости решения к оптимальному, но обладают хорошими временными показателями, позволяя найти достаточно хорошее решение быстрее других известных детерминированных или эвристических методов.[18] Каждая особь (генотип) представляет собой подмножество предметов, которые мы хотим упаковать в ранец (их общий вес может превысить допустимую грузоподъемность). Для удобства информация хранится в виде бинарных строк, в которых каждый бит определяет, помещается ли этот предмет в ранец[19]. Функция приспособленности определяет близость решения к оптимальному. Например, таковой может служить суммарная ценность предметов, при условии, что суммарный вес не превосходит грузоподъемность. После серии смен поколений, в которых скрещиваются наиболее приспособленные особи и игнорируются оставшиеся, алгоритм, по предположению, должен улучшить исходные решения[19]. Решение задачи о сумме подмножествЧастным случаем задачи рюкзака 0-1 является задача о сумме подмножеств. Пусть — грузоподъёмность рюкзака, — вес -го предмета, а его стоимость . Таким образом, задача состоит в том, чтобы нагрузить рюкзак наиболее плотно, или полностью исчерпать ресурсы:
Для решения можно воспользоваться упомянутым генетическим алгоритмом. Особью является вектор . В качестве функции приспособленности следует использовать близость суммарного веса предметов к , с той лишь особенностью, что более предпочтительны наборы, помещающиеся в рюкзак (суммарный вес предметов меньше, чем )[19]. Определим формально функцию приспособленности . Пусть — сумма весов всех предметов. Тогда — максимально возможное отклонение веса предметов в рюкзаке от . Пусть — суммарный вес предметов для данного вектора. Тогда положим: Пользуясь общим алгоритмом, можно найти приближенное решение:
Выполнение прерывается либо при нахождении решения, либо после заданного числа итераций[19]. ПриложенияДоподлинно неизвестно, кто первым привел математическую формулировку задачи о рюкзаке. Одно из первых упоминаний о ней можно найти в статье Джорджа Балларда Мэтьюса[англ.][20][21], датированной 1897 годом. Интенсивное изучение данной проблемы началось после публикации Д. Б Данцигом в 1957 году книги «англ. Discrete Variable Extremum Problem»[22], особенно в 70—90-е годы XX века, как теоретиками, так и практиками[2]. Во многом интерес был вызван достаточно простой формулировкой задачи, большим числом её разновидностей и свойств и в то же время сложностью их решения. В 1972 году данная задача вошла в список М. Карпа NP-полных задач (статья англ. «Reducibility Among Combinatorial Problems»)[23]. Наглядная интерпретация задачи о рюкзаке привела к тому, что она нашла применение в разных областях знаний: в математике, информатике и на стыке этих наук — в криптографии. В одной из работ по вычислительной лингвистике[24] предложена формулировка задачи автоматического реферирования текстов, частный случай которой соответствует постановке задачи о рюкзаке. На основе задачи о рюкзаке был создан первый алгоритм асимметричного шифрования. Впервые идея криптографии с открытыми ключами была представлена Уитфилдом Диффи и Мартином Хеллманом на Национальной компьютерной конференции (англ. National Computer Conference) 1976 года[25][26]. Также задача о рюкзаке может служить моделью для большого числа промышленных задач[2][27]:
Задача о рюкзаке в криптографииВ 1978 году Ральф Меркл и Мартин Хеллман разработали первый алгоритм для обобщённого шифрования с открытым ключом — криптосистему Меркла — Хеллмана, построив её на основе задачи о ранце. Они опубликовали одностадийный (англ. singly-iterated) и мультистадийный (англ. multiply-iterated) варианты, а алгоритм мог быть использован только для шифрования. Но Ади Шамир адаптировал его и для использования в цифровых подписях[28]. В дальнейшем были предложены и другие криптосистемы на основе задачи о рюкзаке, часть из которых являются модификацией криптосистемы Меркла — Хеллмана. Известные криптосистемы[29]:
Шифрование с помощью задачи о рюкзакеБлагодаря тому, что задачу о рюкзаке в общем виде нельзя решить точно за приемлемое время, её можно использовать в криптографических задачах. Для этого, при публично известном наборе предметов, мы представим сообщение как набор передаваемых предметов, а отправим их суммарный вес[28]. Определение. Рюкзачным вектором назовём упорядоченный набор из n предметов, где — вес -го предмета[30]. Рюкзачный вектор является открытым ключом. Для шифрования открытого текста его разбивают на блоки длиной бит, при этом каждый бит определяет наличие предмета в рюкзаке (например, открытый текст соответствует наличию первых четырёх из шести возможных предметов в рюкзаке). Считается, что единица указывает на наличие предмета в рюкзаке, а ноль на его отсутствие[28]. После этого высчитывается суммарный вес предметов в рюкзаке для данного открытого текста, и передаётся в качестве шифротекста[28]. Пример шифрования данным алгоритмом: Пусть задан рюкзачный вектор с длиной .
Примечания
Литературана русском языке
на английском языке
Ссылки
|