一文看懂P问题,NP问题,NPC问题
多项式级的时间复杂度
多项式级别的时间复杂度指的是: O(1), O(n), O(log(n)), O(n^a)
(a为常数)
而非多项式级别的时间复杂度是: O(a^n), O(n!)
非多项式级的时间复杂度是计算机不能承受的。
P问题
如果一个问题可以找到一个多项式级复杂度的解法,那么该问题就是P问题。
(多项式的英文是 Polynomial , 因此使用这里的首字母来作为问题的名称。)
NP问题
给定一个问题,如果可以在多项式级的时间里去验证该问题的任意给定解是否有效,则该问题是NP问题。
(N是nondeterministic的缩写,即不确定型。 NP,字面含义即,"不确定是否有多项式级解法"。)
举一个例子,给定一个图以及其中的2个点,问:对于这2个点,能否找到一条长度小于100个单位的路径?
因为验证一个解,只需要O(n)的时间,所以这是一个NP问题。
那么有没有连验证一个解也无法做到在多项式级别时间内完成呢?
有。
问:对于给定一个的图,其是否不存在Hamilton回路?
只有试过所有的路,才能断定该图没有Hamilton回路,因此验证“无”这个解,就无法在多项式时间内完成。
Hamilton 问题
给定一个图,能否找到一条经过每个顶点一次且只有一次而最后又走回来的路。
满足这个条件的路径叫做Hamilton回路。
Hamilton问题就是一个NP问题,并且它也是一个NPC问题(见后)。
P问题与NP问题的关系
- 所有的P问题都是NP问题。
这是显而易见的。既然找到解都是多项式级复杂度,那么验证解就更没有问题了。
- NP问题一定是P问题吗?
不知道。这就是著名的"P=NP?"问题。
换句话说,“P=NP?”问题就是:
“给定一个问题,若可以在多项式级时间里验证其任意一个解,则该问题是否一定也有多项式级的解法呢?”
目前为止,既没有人真正地证明了 P = NP,也没有人真正地证明了 P ≠ NP,也没有人真正地证明了这个问题的不可解性。
(虽然大多数人倾向于NP问题并不是P问题。)
归约 (Reducibility)
“问题A可以归约为问题B”的含义是,可以用问题B的解法解决问题A,或者说,问题A可以“变成”问题B。
“问题A可约化为问题B”的一个隐含的含义: B的时间复杂度 >= A的时间复杂度
这里的意义是: 既然更复杂的B问题能被解决,那么相对简单的A问题自然也能被解决了。
通过对某些问题的不断归约,就能不断寻找到复杂度更高但应用范围也更广的算法,以此来代替复杂度虽低但应用范围也较小的算法。
NPC问题 (NP-完全问题)
NPC中的C指的是Complete.
什么是 NPC 问题呢?
首先假设有这样一个NP问题,所有的NP问题都可以归约为它; 那么只要该问题能找到多项式级的解法,则所有NP问题也都能通过规约为它从而找到多项式级解法。
因为这个NP问题是如此之复杂与强大,所以称之为 NPC 问题。
由此可见,NPC问题是最复杂的NP问题,但NP问题不一定是NPC问题。(比如,P问题是NP问题,但P问题就不是NPC问题。)
事实上,NPC问题并不是只有一个,而是有很多个。
当然,说一个问题是NPC问题,是需要证明的。
怎么证明一个问题是NPC问题?
分2步。
首先,证明它是一个NP问题;
然后,证明一个已知的NPC问题可以归约为它。(根据归约的传递性)
那么,第一个NPC问题是怎么证明的呢?
逻辑电路问题就是第一个NPC问题。它的证明确实比较复杂。
逻辑电路问题 (第一个NPC问题)
逻辑电路问题,就是第一个被证明的NPC问题。
逻辑电路问题:
给定一个逻辑电路,问:是否存在一种输入,使得输出为True?
它显然是一个NP问题,因为要验证它的一个解并不困难;并且可以证明所有的NP问题都可以归约为它。只是证明过程相当复杂,其大概意思是说任意一个NP问题的输入和输出都可以转换成逻辑电路的输入和输出。
有了第一个NPC问题之后,人类已经发现了至少数百个NPC问题。
前面提到的Hamilton问题也是NPC问题。
NP-Hard问题
NP-Hard问题满足NPC问题的第二条证明,但不满足第一条。
即:
某个NPC问题可以归约为一个特定的问题,但这个问题并不是一个NP问题,则称这个问题为NP-Hard问题。
由定义可见,对于NP-Hard问题,想验证它的一个解,都无法在多项式时间内完成。
一些有趣的问题
质数判定问题
能够在多项式级的时间里,证明一个数字是或不是质数吗?
可以的。因此,质数判定问题,看起来很难,但它其实是一个P问题。
这个问题,在2002年由印度理工学院的3个人证明,论文是《PRIMEs is in P》
线性规划(linear programming)
1979 年,人们才迎来了线性规划的第一个多项式级的算法,它是由前苏联数学家列昂尼德·哈奇扬(Leonid Khachiyan)提出的。
因此,线性规划问题也是P问题,而不是找不到多项式级解法的问题。
整数分解问题
给定一个整数,它能否被分解为若干质数的乘积?
目前没有找到多项式级解法。人们不知道该问题是否为P问题。
子集和问题
给定一个整数集合S以及一个大整数M,问: 能否在S里选出一些数字,使得它们的和为M?
目前也没有多项式级的解法。因此人们猜测子集和问题不是P问题。
第K大子集问题
给定一个含有n个整数的集合S,一个大整数M,以及一个不超过2n的整数K,
问: 是否存在至少K个不同的子集,使得每个子集里的元素之和都小于等于M?
目前没有多项式级的检验方法(注意,不是解法,是核验方法),因此不知道它是否是NP问题。