《Algorithms》第8章:NP完全问题 学习笔记

来源:互联网 发布:vmware 12 mac 编辑:程序博客网 时间:2024/05/20 18:01
/*
* 第0~第8章的全部笔记已经整理在http://zjsblog.com/ALGO/index.html
* Algorithms 是一本很经典的算法入门书,希望对朋友们有所帮助
*/

Chapter 8:NP-完全问题

8.1 一些搜索问题:

搜索问题定义:
一个搜索问题是由一个算法C描述的,以问题实例I和一个可能的解S为输入,运行在关于|I|的多项式时间内。我们说S是I的一个解,当且仅当C(I,S) = true。

可满足性问题(简称SAT)
问题定义:给定一个采取合取范式的布尔公式,为其找到一个可满足赋值或判定该赋值不存在。
eg:



旅行商问题(TSP)
给定n个顶点和两两之间的距离,以及预算b。我们需要确定一条路线,该路线为一个恰好经过每个顶点一次的环,且总的预算不能超过b,否则报告解不存在。

什么情况下,可以一笔画某个图形?
a)该图是连通的
b)除最多两个顶点外,所有顶点上的边数都为偶数

Euler路径的搜索问题如下:给定一个图,寻找一条恰好包含每条边一次的路径。

Rudrata环路搜索问题如下:给定一个图,求一条经过每个顶点恰好一次的环路,或者报告该环路不存在。

整数线性规划(ILP)
在线性规划中,所有的数值必须都是整数。
问题定义:给定A和b,求一个非负整数值向量x,满足不等式Ax<=b,或者报告该解不存在。
至今没有高效解法

ILP有一个困难的特例:目标是求0和1构成的向量x,满足Ax=1,其中A是一个由0和1构成的m*n阶矩阵。我们称之为零一方程(ZERO-ONE EQUATION,ZOE)

3D匹配
有n个男孩,n个女孩和n个宠物,他们之间的相容关系被表达为一个三元组的集合,集合中每个元素都包含一个男孩、一个女孩和一个宠物。我们需要求n个独立的三元组,从而形成n个和谐的“家庭组合”。


独立集、顶点覆盖和团
独立集问题:给定一个图和整数g,目标求图中的g个互相独立的顶点。
顶点覆盖问题:给定一个图和预算b,求b个能覆盖到每条边的顶点。
顶点覆盖是集合覆盖的一个特例。
团问题:给定一个图以及目标g,求图中的g个顶点,使得这些顶点间两两都存在相连的边。

背包问题与子集和
动态规划给出了背包问题一个O(nW)的算法(填一个n*W的表格)。由于运行时间中包含的是W而不是logW,因此该时间与输入规模(输入位数)是指数关系。
背包问题有多项式时间算法吗?至今现在还没人知道答案。
另一个变型:假设每件物品的价值都等于其重量。等价于求一个整数集子集的问题,目标是使子集中的所欲元素的和恰好为W。这个问题也非常困难。


8.2 NPC问题

困难的问题和容易的问题:


P和NP
我们将所有搜索问题称为NP问题。所有能在多项式时间内求解的搜索问题被记为P。

搜索问题中的归约:由搜索问题A到搜索问题B的归约是一个多项式时间算法f,其将A的任何实例I转化为问题B的实例f(I);同时存在另一个多项式时间算法h,将f(I)的任意解S映射到I的一个解h(S),具体过程如下:

称一个搜索问题是NP完全的,是指其它所有搜索问题都可以归约到它。一个问题要成为NPC,它必须能用于解决世界上所有的搜索问题。

使用归约的两种途径
如果问题A可以归约为问题B(A->B),则
a)如果能高效求解B,也一定能高效求解A
b)如果A是难的,则B也是难的


8.3 所有的归约

搜索问题的相互归约:

为什么说是互相归约的?
上图中所有的NPC问题都可以归约为电路SAT问题,电路SAT可以归约为SAT问题,所以构成环。

Rudrata(s,t)-路径 --> Rudrata环路
Rudrata(s,t)-路径问题:指定两个特殊的顶点s,t,然后求一条由s到t的恰好经过每个顶点一次的路径。
Rudrata环路问题:给定一个图,求是否存在一个恰好经过每个顶点一次的环路
以下归约告诉我们前者不会比后者难:


3SAT --> 独立集
这里用一个具体的例子说明了归约过程,考虑3SAT:


我们将每一个子句表示为一个三角形,例如 子句(~x ∨ y ∨ ~z) (~x表示x取反),其中顶点分别标注为~x,y,~z。对所有子句重复这一做法。然后连接子句和子句间相反的文字(比如x和~x连接)
我们得到的最终图形如下:

我们只需找到大小为4的独立集即可(4从哪里来?答:4为子句的数量)

SAT --> 3SAT
用如下方法进行归约:

证明:
1)假设右侧子句都满足,则a_1,a_2,...,a_k中至少有一个为真,否则y_1必须为真,进而使y_2必须为真,依次类推,最终导致右侧最后一个子句不满足,矛盾。因此a_1 ∨ a_2 ∨ ... ∨ a_k 必然满足。
2)假设左侧子句满足,则必有某个a_i为真。令y_1,...y_i-2 为true,其余的都为false。这使得右侧满足。

独立集 --> 顶点覆盖
节点集合S是图G(V, E)的一个顶点覆盖,当且仅当剩余节点的集合V-S是G中的一个独立集。
证明(反证):
1)“ => ”
若V-S不是独立集,则必存在一条边e相连V-S中的两个顶点,则此边e没有被S中的顶点覆盖到,故S不是顶点覆盖,矛盾。
2)“ <= ”
若S不是顶点覆盖,则必存在一条边e的两个顶点都不在S中,则此两顶点必在V-S中,则V-S不是独立集,矛盾。

独立集 --> 团问题
节点集S是G的一个独立集当且仅当S是G的补图中的一个团

3D匹配 --> ZOE
转换过程如下:
A中的5列对应于5个三元组(eg,第一列对应于左图标记为1的三元组,以此类推),9行则分别对应于Al、Bob、Chet、Alice、Beatrice、Carol、Armadillo、Bobcat、Canary。
则只需找到一个x,使得Ax=1,即可。若x = (1,1,0,1,0)T,则原3D匹配问题的答案为选择标号为1、2、4的三元组。

ZOE --> 子集和
例如,给定如下ZOE实例:


我们要求A的一个列集合,将其相加恰好为值全部为1的向量。如果我们将列看成是二进制整数(自上向下读),则我们所求的就是整数18、5、4、8的一个子集,其中的数相加等于二进制数 11111 = 31。这恰好是子集和的一个实例。归约完成。

任意NP问题 --> SAT
归约思路:
任意NP问题 --> 电路SAT --> SAT
1)任意NP问题 --> 电路SAT
假设A是一个NP问题,我们所知的全部就是它是个搜索问题,主要特征是其任意解都能被快速检验。即存在算法C,以问题实例I和可能解S作为输入,判断S是否为I的解。此外C做出判断的时间关于I的长度是多项式规模的。因为任意多项式算法都可以被表示为一个电路,所以我们可以再多项式时间内构造一个电路,其已知输入为I对应的比特,未知输入为S对应的比特,则其最终输出为true当且仅当未知输入对应的S为I的解。
2)电路SAT --> SAT
归约方案如下: