1. 程式人生 > 其它 >NPC問題:子集和、揹包、裝箱與雙機排程

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\)

\(S_3\)恰好覆蓋A,也就對應著\(x_2+x_3=N\)。m大小的選取避免了產生進位的可能,所以這種對應可以證明是正確的。

定理: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\)