NPC問題:子集和、揹包、裝箱與雙機排程
子集和:給定正整數的集合\(X=\{x_1,...x_n \}\)及正整數N,是否存在X的子集T,使得T中的元素之和等於N?
裝箱:給定n件物品,物品j的重量為正整數\(w_j\),\(1\le j\le n\),以及箱子數K。規定每隻箱子裝入物品的總重量不超過正整數B,是否能用K只箱子裝入所有物品?
雙機排程:兩臺機器和n項作業\(J_1,...J_n\)。這兩臺機器完全相同,每一項作業可以在任意一臺機器上進行,沒有先後順序。作業\(J_i\)的處理時間為\(t_i\),\(1\le i\le n\),截止時間為D,所有\(t_i\)和D都是正整數。是否能把n項作業分配給兩臺機器,在截止時間D內完成所有的作業?
問題包含關係:子集和是雙機排程的子問題,雙機排程是裝箱問題的子問題
例題4:子集和是NP完全的
子集和\(\in\)NP是顯然的
下證 恰好覆蓋\(\le_p\)子集和
證明思路
給定有窮集\(A=\{a_1,a_2,...a_n \}\)和A的子集的集合\(W=\{S_1,...S_n \}\)
對應的子集和例項為正整數集合\(X=\{x_1,...x_m\}\)及正整數N
相當於要構造一種對應關係,使得A可以被W恰好覆蓋 \(\iff\) X中有子集元素之和為N
證明構造
每個\(x_j\)和N都可表示成\(kn\)位二進位制數,這kn位分成n段,每段k位,其中\(k=\lceil \log _2(m+1)\rceil\)
N的每一段的第一位(最右的一位)為1,其餘的為0。
\(x_j\)對應於子集\(S_j\)。當\(a_i\in S_j\)時,從左到右\(x_j\)的第i段的第一位為1,其餘的為0。
例項如下所示
在這個例子中,\(n=4\),\(m=3\),\(k=\lceil \log_2 (4)\rceil = 2\)
所以就是用01來表示這個元素在集合中出現,00表示這個元素沒有出現,例如\(\{a_1,a_2 \}\)表示為\(x_1 = 01010000\)
所以可以看到對於\(x_i\)來說,其分成n個1和0,用於表示這個元素是否出現;其中0和1的長度,取決於W中子集的總數。
構造正確性
可以注意到這種對應是非常直觀的,如上例所示。\(S_2\)
定理:0-1揹包是NP完全的
例題5:雙機排程是NP完全的
顯然雙機排程$\in \(NP,要證 子集和\)\le_p$雙機排程
證明思路
任給一個子集和例項,由正整數的集合\(X=\{x_1,...x_n \}\)及正整數N組成
雙機排程例項有n+2項作業\(J_1,...J_{n+2}\),處理時間分別為\(x_1,...x_n,a,b\), 截止時間為D。
相當於 存在X的子集T使得\(\sum_{x_i\in T}x_i = N ~\iff ~ N+a = \sum^n_{i=1}x_i - N+b = D\)
後者可以得到
\[a = \sum^n_{i=1}x_i-2N+b \]構造正確性
假設X的子集使得\(\sum_{x_i\in T}x_i = N\)
將${J_i|x_i\in T }\cup {J_{n+1}} $分配給第一臺機器,總時間為N+a
將${J_i|x_i\notin T }\cup {J_{n+2}} \(分配給第二臺機器,總時間為\)\sum^n_{i=1}x_i-N+b$
只要調整a和b以及D使得之前的構造成立即可,比如\(b=\sum^n_{i=1}x_i+2N,a=2\sum^i_{i=1}x_i\)
此時\(D = 2\sum^n_{i=1}x_i+N\)
假設這n+2項作業可以分配到兩臺機器上,使得每臺機器的工作時間都不超過D。因為\(\sum^n_{i=1}x_i+a+b=2D\),所以兩臺機器的工作時間恰好為D。
因為\(a+b=2\sum^n_{i=1}x_i+2N>D\),所以\(J_{n+1}\)和\(J_{n+2}\)不能分配給同一臺機器。不妨設\(J_{n+1}\)分配給第一臺機器,只要將除了\(J_{n+1}\)外的其他作業構成集合\(T\),\(\sum_{x_i\in T}x_i = D-a=N\)。