我想试着把p, np, npc, np-hard问题讲清楚。
在介绍之前,先说一下什么是确定性问题,什么是非确定性问题。
比如小学学的加减乘除之类的,你只要按部就班的算,这个算法就能得到结果。
比如找大质数的问题。有没有一个公式,你一套公式,就可以一步步推算出来,下一个质数应该是多少,这样的公式是没有的。但可以告诉你一个答案,如果可以在多项式的时间内验证这个答案对不对,则为后面将要说的NP问题(非确定性多项式)。有的NP问题可以通过穷举法验证所有可能答案,但计算的时间随问题的复杂度成指数的增长,很快便变得不可计算了。
再举个通俗的例子就懂了。
“你去参加一个宴会,此时你一定想在宴会上找个你认识的人,这时主家走过来告诉你,在一个角落的人你可能认识,你放眼望去,果然是一个你认识的人。也就是验证了这个解是正确的,但若你自己找人的话,要把整个大厅找一遍,时间非常长,难以找到一个确定的解。”
P(Polynomial(多项式))问题最简单也是最好理解的。
P问题是具有多项式算法的判定问题。即可以在多项式时间内解决的问题。更准确的说可以在时间O(nk)内解决,其中k为某一常量,n是此问题输入的规模。它的输入规模n出现在底数的位置。比如排序问题、最小生成树、单源最短路径。
另一种是O(an)和O(n!)型复杂度,它是非多项式级的,其复杂度计算机往往不能承受。
直观的讲,我们将P问题视为可以较快解决的问题,并能确定的输出答案,是确定性问题。
理解NP有两个角度:一个角度是作为确定性图灵机的一个推广,另一个角度是作为多项式时间可验证解的算法问题的集合。我主要用后者角度讲解,前者还不太明白。
NP(Non-deterministic(非确定性)Polynomial)非确定性多项式问题可以看成是由无限个确定性的 P 问题的集合。
NP问题不是非P类问题,是指可以在多项式的时间里验证一个解的问题。虽然非确定性算法无法通过按部就班的计算在多项式时间内得到准确答案的。但如果我能猜到一个答案,并能在多项式时间内验证这个答案是否正确,也就是如果我猜得准,就能在多项式时间内解决这个NP问题。
即非确定性算法将问题分解成猜测和验证两个阶段,算法的猜测阶段是非确定性的,算法的验证阶段是确定性的,它验证猜测阶段给出解的正确性。
当然有不是NP问题的问题,即你猜到了解,但你不能在多项式的时间里去验证它,可能需要的时间是指数级或更复杂甚至无法计算。也就是说连多项式地验证它的一个解都不行,那它更不可能用多项式级的算法来解决它了。
NP问题如果找到了多项式解法就是P问题了。目前为止人们还未证明,NP问题有多项式的解法,但也无法证明一定不存在多项式的解法。
这就是著名的数学难题NP=P?,到底NP等于P,还是NP不等于P。目前为止这个问题还“啃不动”。不过人们普遍认为,P=NP不成立,即多数人相信,存在至少一个NP问题不能在多项式时间内解决。
现在我相信你已经了解了P和NP问题的含义,下图的是他们的包含关系,NP范围大,P范围小,因为在这个复杂的世界难解的问题太多,易解的问题只占一小部分:
人们如此坚信P≠NP是有原因的,就是在研究NP问题的过程中找出了一类非常特殊的NP问题叫做NP-完全问题,也即所谓的 NPC问题。
NP完全问题是NP类中“最难”的问题,也就是说它们是最可能不属于P类的。正是NPC问题的存在,使人们相信P≠NP。
NPC问题至少与其他所有NP问题一样难。并且不加证明的给出一个结论,如果任何NPC问题可以在多项式时间内解决,那么所有NP问题都有一个多项式时间算法。但现在还没人发现任何NPC的多项式时间解法。
如果你发现一个问题是NPC问题,你可以直接跟老板说这个问题无解。
事实上,只要是NP-hard问题可以在多项式时间内解决,那么所有NP问题都有一个多项式时间算法。NPC是NP-hard的子集。也可以这么理解,如果一个问题既是NP-hard问题又是NP问题,我们称之为NPC问题。
NP困难问题(NP-hard)是指这样的一类问题,它们本身的复杂度是多少无所谓(至少是NP),但是只要这个问题找到确定的多项式时间的解,那么我们可以证明出所有的NP问题都一定存在确定的多项式时间的解。
NP-hard不一定是NP,即使证明了NP=P=NPC,NP-hard也不一定有多项式解,它是更难的一类问题。