Изменения

Перейти к: навигация, поиск

NP-полнота задачи о сумме подмножества

849 байт добавлено, 19:22, 4 сентября 2022
м
rollbackEdits.php mass rollback
{{Задача|definition ==Формулировка задачи==В '''задаче о сумме подмножества''' (Subset sum problem) входными данными являются набор из Дано множество <mathtex>nS</mathtex> целых чисел , содержащие <mathtex>Sn</mathtex> целых чисел и целое число <mathtex>s</mathtex>. Требуется выяснить, возможно ли выбрать подмножество <mathtex>S' \subseteq S</mathtex> с суммой <mathtex>s</mathtex>:<p style="text-align:center;"br><mathtex>\exist exists S' \subseteq S: \sum_sum\limits_{s_{i} \in S'}{s_{i}} = s</mathtex></p>}} 
==Доказательство NP-полноты==
Для доказательства того, что '''задаче о сумме подмножества''' (англ. ''Subset sum problem '', <mathtex>\inmathrm{SSP}</mathtex> ) [[NPC| NP-полной]], необходимо доказать два факта:*Subset sum problem <mathtex>\mathrm{SSP} \in</mathtex> [[NP| <tex>\mathrm{NP}</tex>]] *Subset sum problem <mathtex>\mathrm{SSP} \in</mathtex>[[NPH| <tex>\mathrm{NPH}</tex>]]  ===Доказательство принадлежности к NP===В качестве сертификата возьмем удовлетворяющее условию задачи множество <mathtex>S'</mathtex> с суммой <mathtex>s</mathtex>. Очевидно, оно Оно удовлетворяет всем требованиям, налагаемым на сертификат. Проверяющая функция строится очевидным образом, работает проверит вхождение всех элементов <tex>S'</tex> в множество <tex>S</tex> за полиномиальное от размера входа время<tex>\left\vert{S'}\right\vert \times \left\vert{S}\right\vert</tex>. ===Доказательство принадлежности к NPH===Сведем [[NP-полнота_задачи_о_выполнимости_булевой_формулы_в_форме_3-КНФ|3-CNF_Sat<tex>\mathrm{3CNFSAT}</tex>]] к задаче о о сумме подмножества. Пусть задана 3-CNF <tex>\mathrm{3CNF}</tex> формула <mathtex>\phivarphi</mathtex> от <mathtex>n</mathtex>переменных <mathtex>x_{i}</mathtex>, состоящая из <mathtex>k</mathtex> пар скобок <mathtex>C_{i}</mathtex>. Будем считать, не умаляя общности, что ни одна пара скобок не содержит одновременно переменную и ее отрицание. Также предположим, что каждая переменная входит хотя бы в одну пару скобок. Построим сводящую функцию <mathtex>f\!\!:(\{x_{i}\}^{n}_{i=1},\{C_{j}\}^{k}_{j=1}) \to (S,s)</math> (эквивалентная запись: <math>f\!\!:\phi varphi \to (S,s)</mathtex>)
====Построение сводящей функции====
Для каждой переменной <mathtex>x_{i}</mathtex> и каждой пары скобок <mathtex>C_{j}</mathtex> создадим по два числа в десятичной системе счисления, каждое длиной <mathtex>n+k</mathtex> цифр. Эти числа образуют <mathtex>S</mathtex>. Также создадим число <mathtex>s</mathtex> длиной <mathtex>n+k</mathtex> цифр. Присвоим каждому разряду полученных чисел (одинаковую для всех чисел) метку, соответствующую либо переменной, либо паре скобок.Метки, соответствующие парам скобок, присвоены <mathtex>k</mathtex> младшим разрядам чисел.*В числе <mathtex>s</mathtex> все разряды, соответствующие переменным, установим <mathtex>1</mathtex>, а оставшиеся сделаем равными <mathtex>4</mathtex>.*Каждой переменной <mathtex>x_{i}</mathtex> соответствуют два числа из <mathtex>S</mathtex>: <mathtex>v_{i}</mathtex> и <mathtex>u_{i}</mathtex>. Опишем создание этих чисел. Разряд, соответствующий <mathtex>x_{i}</mathtex> установим равным <mathtex>1</mathtex>, а все остальные разряды, соответствующие переменным, установим равными <mathtex>0</mathtex>. Далее, для числа <mathtex>v_{i}</mathtex> установим все разряды, соответствующие парам скобок, содержащих <mathtex>x_{i}</mathtex>, равными <mathtex>1</mathtex>. Во все остальные "скобочные" разряды поставим <mathtex>0</mathtex>. В числе <mathtex>w_{i}</mathtex> установим все разряды, соответствующие парам скобок, содержащих <mathtex>\neg x_{i}</mathtex>, равными <mathtex>1</mathtex>, а во все остальные "скобочные" разряды поставим <mathtex>0</mathtex>.*Каждой паре скобок <mathtex>C_{j}</mathtex> соответствуют два числа из <mathtex>S</mathtex>: <mathtex>d_{i}</mathtex> и <mathtex>e_{i}</mathtex>. Оба этих числа содержат <mathtex>0</mathtex> во всех разрядах, кроме соответствующего <mathtex>C_{j}</mathtex>. В этом разряде у <mathtex>d_{i}</mathtex> поставим <mathtex>1</mathtex>, а у <mathtex>e_{i}</mathtex> поставим {{---}} <mathtex>2</mathtex>.
====Корректность сводящей функции====
*Получаемое сводящей функцией множество <mathtex>S</mathtex> состоит из <mathtex>2(n+k)</mathtex> десятичных чисел длиной <mathtex>(n+k)</mathtex> каждое, выставление каждого разряда занимает полиномиальное время. Таким образом, сведение выполняется за полиномиальное время.*Пусть формула <mathtex>\phivarphi</mathtex> выполнима, то есть существует набор значений <mathtex>\{y_{i}\}^{n}_{i=1}:~\phivarphi(y_{1}\ldots y_{n})=1 </mathtex>. И пусть <mathtex>(S,s) = f(\phivarphi)</mathtex>. Тогда в полученном множестве <mathtex>S</mathtex> существует подмножество с суммой <mathtex>s</mathtex>. Действительно, для каждой переменной, если <mathtex>y_{k} = 1</mathtex>, то добавим в <mathtex>S'~ v_{i}</mathtex> в <tex>S'</tex>. Иначе добавим <mathtex>w_{i}</mathtex>. Теперь <mathtex>S'</mathtex> содержит уже <mathtex>n</mathtex> чисел. Заметим, что для каждого "скобочного"разряда в уже набранной части <mathtex>S'</mathtex> есть не менее одного и не более трех чисел, у которых в данном разряде стоит <mathtex>1</mathtex>. Значит для каждого соответствующего паре скобок <mathtex>C_{j}</mathtex> разряда мы сможем выбрать одно или оба числа <mathtex>d_{j}</mathtex> и <mathtex>e_{j}</mathtex> так, чтобы сумма в данном разряде совпадала с требуемой (стала равна <mathtex>4</mathtex>). Добавим их в <mathtex>S'</mathtex>. Также заметим, что суммы во всех "переменных" разрядах равны <mathtex>1</mathtex>, так как для каждого <mathtex>i</mathtex> выбиралось строго одно число из <mathtex>v_{i}</mathtex> и <mathtex>u_{i}</mathtex>. Значит, <mathtex> \sum_sum\limits_{s_{k} \in S'}{s_{k}} = s</mathtex>.*Пусть теперь в наборе <mathtex>S</mathtex> есть подмножество <mathtex>S':~ \sum_sum\limits_{s_{k} \in S'}{s_{k}} = s</mathtex>. Тогда исходная формула <mathtex>\phivarphi</mathtex> выполнима. Действительно, если <mathtex>v_{i} \in S'</mathtex>, то установим переменную <mathtex>x_{i}=1</mathtex>. Если же <mathtex>w_{i} \in S'</mathtex>, то <mathtex>x_{i}=0</mathtex>. Покажем, что <mathtex>\phivarphi(x_{1}\ldots x_{n}) = 1 </mathtex>. Действительно, так как <mathtex> \sum_sum\limits_{s_{k} \in S'}{s_{k}} = s</mathtex>, в каждой паре скобок хотя бы один терм равен <mathtex>1</mathtex>. Значит каждый терм равен <mathtex>1</mathtex>. А тогда и вся <mathtex>\phi varphi = 1</mathtex>.
====Пример сведения====
Пусть исходная функция <mathtex>\phivarphi(x_{1} \ldots x_{4}) = (x_{1} \or lor x_{2} \or lor \neg x_{3}) \and land (\neg x_{1} \or lor x_{2} \or lor x_{4})</mathtex>.Пометим разряды следующим образом (слева направо): <mathtex>x_{1},x_{2},x_{3},x_{4},C_{1},C_{2}</mathtex>. Тогда:*<mathtex>v_{1} = 100010</mathtex>*<mathtex>w_{1} = 100001</mathtex> *<tex>v_{2} = 010011 = 10011</tex>*<tex>w_{2} = 010000 = 10000</tex> *<tex>v_{3} = 001000 = 1000</tex>*<tex>w_{3} = 001010 = 1010</tex> *<tex>v_{4} = 000101 = 101</tex>*<tex>w_{4} = 000100 = 100</tex>
*<mathtex>v_d_{21} = 010011 000010 = 1001110</mathtex>*<mathtex>w_e_{21} = 010000 000020 = 1000020</mathtex>
*<mathtex>v_d_{32} = 001000 000001 = 10001</mathtex>*<mathtex>w_e_{32} = 001010 000002 = 10102</mathtex>
*<mathtex>v_{4} s = 000101 = 101</math>*<math>w_{4} = 000100 = 100111144</mathtex>
*<mathtex>d_S = (\bigcup\limits_{i=1}^{4} v_{i}) \cup (\bigcup\limits_{i=1} ^{4} w_{i}) \cup (\bigcup\limits_{i= 000010 1}^{2} d_{i}) \cup (\bigcup\limits_{i= 10</math>*<math>1}^{2} e_{1i} = 000020 = 20)</mathtex>
*Тогда набору значений <mathtex>d_{2} Y = 000001 (0,0,0,1):~ \varphi(Y) = 1</mathtex>*соответствует <mathtex>S' = \{w_{1},~w_{2},~w_{3},~v_{4},~d_{1},~e_{1},~e_{2} \}</tex>. И действительно, <tex>100001 + 10000 + 1010 + 101 + 10 + 20 + 2 = 000002 = 2111144</mathtex>.
==См. также==* [[NP]]* [[NPH]]*<math>s = 111144</math>[[NPC]]* [[Классы NP и Σ₁]]* [[3CNFSAT]]* [[Примеры NP-полных языков]]
<math>S = (\cup_=Источники информации==* Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, Clifford Stein "Introduction to Algorithms, 3rd Edition" {{i=1 \ldots 4---}} v_Издательство MIT Press, 2009. {i{---}) \cup (\cup_} 1086 c. {{i=1 \ldots 4---} w_{i}ISBN 978-0-262-03384-8 (англ.) \cup (\cup_* Хопкрофт Дж., Мотвани Р., Ульман Дж. Введение в теорию автоматов, языков и вычислений. 2-е издание. {{i=1 \ldots 2---}} d_М.: Издательский дом "Вильямс", 2002. {{i---}}) \cup (\cup_423 с. {{i=1 \ldots 2---} e_{i}ISBN 5-8459-0261-4 (рус.)</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>.Примеры NP-полных языков]]
1632
правки

Навигация