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\)
后者可以得到
构造正确性
假设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\)。

浙公网安备 33010602011771号