NP-полнота задачи о сумме подмножества — различия между версиями
Miron (обсуждение | вклад) (стилистические изменения) |
Miron (обсуждение | вклад) (Добавлен пример сведения.) |
||
Строка 23: | Строка 23: | ||
*Пусть формула <math>\phi</math> выполнима, то есть существует набор значений <math>\{y_{i}\}^{n}_{i=1}:~\phi(y_{1}\ldots y_{n})=1 </math>. И пусть <math>(S,s) = f(\phi)</math>. Тогда в полученном множестве <math>S</math> существует подмножество с суммой <math>s</math>. Действительно, для каждой переменной, если <math>y_{k} = 1</math>, то добавим в <math>S'~ v_{i}</math>. Иначе добавим <math>w_{i}</math>. Теперь <math>S'</math> содержит уже <math>n</math> чисел. Заметим, что для каждого "скобочного"разряда в уже набранной части <math>S'</math> есть не менее одного и не более трех чисел, у которых в данном разряде стоит <math>1</math>. Значит для каждого соответствующего паре скобок <math>C_{j}</math> разряда мы сможем выбрать одно или оба числа <math>d_{j}</math> и <math>e_{j}</math> так, чтобы сумма в данном разряде совпадала с требуемой (стала равна <math>4</math>). Добавим их в <math>S'</math>. Также заметим, что суммы во всех "переменных" разрядах равны <math>1</math>, так как для каждого <math>i</math> выбиралось строго одно число из <math>v_{i}</math> и <math>u_{i}</math>. Значит, <math> \sum_{s_{k} \in S'}{s_{k}} = s</math>. | *Пусть формула <math>\phi</math> выполнима, то есть существует набор значений <math>\{y_{i}\}^{n}_{i=1}:~\phi(y_{1}\ldots y_{n})=1 </math>. И пусть <math>(S,s) = f(\phi)</math>. Тогда в полученном множестве <math>S</math> существует подмножество с суммой <math>s</math>. Действительно, для каждой переменной, если <math>y_{k} = 1</math>, то добавим в <math>S'~ v_{i}</math>. Иначе добавим <math>w_{i}</math>. Теперь <math>S'</math> содержит уже <math>n</math> чисел. Заметим, что для каждого "скобочного"разряда в уже набранной части <math>S'</math> есть не менее одного и не более трех чисел, у которых в данном разряде стоит <math>1</math>. Значит для каждого соответствующего паре скобок <math>C_{j}</math> разряда мы сможем выбрать одно или оба числа <math>d_{j}</math> и <math>e_{j}</math> так, чтобы сумма в данном разряде совпадала с требуемой (стала равна <math>4</math>). Добавим их в <math>S'</math>. Также заметим, что суммы во всех "переменных" разрядах равны <math>1</math>, так как для каждого <math>i</math> выбиралось строго одно число из <math>v_{i}</math> и <math>u_{i}</math>. Значит, <math> \sum_{s_{k} \in S'}{s_{k}} = s</math>. | ||
*Пусть теперь в наборе <math>S</math> есть подмножество <math>S':~ \sum_{s_{k} \in S'}{s_{k}} = s</math>. Тогда исходная формула <math>\phi</math> выполнима. Действительно, если <math>v_{i} \in S'</math>, то установим переменную <math>x_{i}=1</math>. Если же <math>w_{i} \in S'</math>, то <math>x_{i}=0</math>. Покажем, что <math>\phi(x_{1}\ldots x_{n}) = 1 </math>. Действительно, так как <math> \sum_{s_{k} \in S'}{s_{k}} = s</math>, в каждой паре скобок хотя бы один терм равен <math>1</math>. Значит каждый терм равен <math>1</math>. А тогда и вся <math>\phi = 1</math>. | *Пусть теперь в наборе <math>S</math> есть подмножество <math>S':~ \sum_{s_{k} \in S'}{s_{k}} = s</math>. Тогда исходная формула <math>\phi</math> выполнима. Действительно, если <math>v_{i} \in S'</math>, то установим переменную <math>x_{i}=1</math>. Если же <math>w_{i} \in S'</math>, то <math>x_{i}=0</math>. Покажем, что <math>\phi(x_{1}\ldots x_{n}) = 1 </math>. Действительно, так как <math> \sum_{s_{k} \in S'}{s_{k}} = s</math>, в каждой паре скобок хотя бы один терм равен <math>1</math>. Значит каждый терм равен <math>1</math>. А тогда и вся <math>\phi = 1</math>. | ||
+ | ====Пример сведения==== | ||
+ | Пусть исходная функция <math>\phi(x_{1} \ldots x_{4}) = (x_{1} \or x_{2} \or \neg x_{3}) \and (\neg x_{1} \or x_{2} \or x_{4})</math>. | ||
+ | Пометим разряды следующим образом (слева направо): <math>x_{1},x_{2},x_{3},x_{4},C_{1},C_{2}</math>. Тогда: | ||
+ | *<math>v_{1} = 100010</math> | ||
+ | *<math>w_{1} = 100001</math> | ||
+ | |||
+ | *<math>v_{2} = 010011 = 10011</math> | ||
+ | *<math>w_{2} = 010000 = 10000</math> | ||
+ | |||
+ | *<math>v_{3} = 001000 = 1000</math> | ||
+ | *<math>w_{3} = 001010 = 1010</math> | ||
+ | |||
+ | *<math>v_{4} = 000101 = 101</math> | ||
+ | *<math>w_{4} = 000100 = 100</math> | ||
+ | |||
+ | *<math>d_{1} = 000010 = 10</math> | ||
+ | *<math>e_{1} = 000020 = 20</math> | ||
+ | |||
+ | *<math>d_{2} = 000001 = 1</math> | ||
+ | *<math>e_{2} = 000002 = 2</math> | ||
+ | |||
+ | *<math>s = 111144</math> | ||
+ | |||
+ | <math>S = (\cup_{i=1 \ldots 4} v_{i}) \cup (\cup_{i=1 \ldots 4} w_{i}) \cup (\cup_{i=1 \ldots 2} d_{i}) \cup (\cup_{i=1 \ldots 2} e_{i})</math> | ||
+ | |||
+ | Тогда набору значений <math>Y = (0,0,0,1):~ \phi(Y) = 1</math> соответствует <math>S' = \{w_{1},~w_{2},~w_{3},~v_{4},~d_{1},~e_{1},~e_{2}\}</math>. И действительно, <math>100001 + 10000 + 1010 + 101 + 10 + 20 + 2 = 111144</math>. |
Версия 09:41, 10 марта 2010
Содержание
Формулировка задачи
В задаче о сумме подмножества (Subset sum problem) входными данными являются набор из
целых чисел и целое число . Требуется выяснить, возможно ли выбрать подмножество с суммой :
Доказательство NP-полноты
Для доказательства того, что Subset sum problem NPC, необходимо доказать два факта:
Доказательство принадлежности к NP
В качестве сертификата возьмем удовлетворяющее условию задачи множество
с суммой . Очевидно, оно удовлетворяет всем требованиям, налагаемым на сертификат. Проверяющая функция строится очевидным образом, работает за полиномиальное от размера входа время.Доказательство принадлежности к NPH
Сведем 3-CNF_Sat к задаче о о сумме подмножества. Пусть задана 3-CNF формула от переменных , состоящая из пар скобок . Будем считать, не умаляя общности, что ни одна пара скобок не содержит одновременно переменную и ее отрицание. Также предположим, что каждая переменная входит хотя бы в одну пару скобок. Построим сводящую функцию (эквивалентная запись: ).
Построение сводящей функции
Для каждой переменной
и каждой пары скобок создадим по два числа в десятичной системе счисления, каждое длиной цифр. Эти числа образуют . Также создадим число длиной цифр. Присвоим каждому разряду полученных чисел (одинаковую для всех чисел) метку, соответствующую либо переменной, либо паре скобок. Метки, соответствующие парам скобок, присвоены младшим разрядам чисел.- В числе все разряды, соответствующие переменным, установим , а оставшиеся сделаем равными .
- Каждой переменной соответствуют два числа из : и . Опишем создание этих чисел. Разряд, соответствующий установим равным , а все остальные разряды, соответствующие переменным, установим равными . Далее, для числа установим все разряды, соответствующие парам скобок, содержащих , равными . Во все остальные "скобочные" разряды поставим . В числе установим все разряды, соответствующие парам скобок, содержащих , равными , а во все остальные "скобочные" разряды поставим .
- Каждой паре скобок соответствуют два числа из : и . Оба этих числа содержат во всех разрядах, кроме соответствующего . В этом разряде у поставим , а у поставим .
Корректность сводящей функции
- Получаемое сводящей функцией множество состоит из десятичных чисел длиной каждое, выставление каждого разряда занимает полиномиальное время. Таким образом, сведение выполняется за полиномиальное время.
- Пусть формула выполнима, то есть существует набор значений . И пусть . Тогда в полученном множестве существует подмножество с суммой . Действительно, для каждой переменной, если , то добавим в . Иначе добавим . Теперь содержит уже чисел. Заметим, что для каждого "скобочного"разряда в уже набранной части есть не менее одного и не более трех чисел, у которых в данном разряде стоит . Значит для каждого соответствующего паре скобок разряда мы сможем выбрать одно или оба числа и так, чтобы сумма в данном разряде совпадала с требуемой (стала равна ). Добавим их в . Также заметим, что суммы во всех "переменных" разрядах равны , так как для каждого выбиралось строго одно число из и . Значит, .
- Пусть теперь в наборе есть подмножество . Тогда исходная формула выполнима. Действительно, если , то установим переменную . Если же , то . Покажем, что . Действительно, так как , в каждой паре скобок хотя бы один терм равен . Значит каждый терм равен . А тогда и вся .
Пример сведения
Пусть исходная функция
. Пометим разряды следующим образом (слева направо): . Тогда:
Тогда набору значений
соответствует . И действительно, .