首先需要介绍P(Polynomial,多项式)问题.P问题是可以在多项式时间内被确定机(通常意义的计算机)解决的问题.NP(Non-Deterministic Polynomial, 非确定多项式)问题,是指可以在多项式时间内被非确定机(他可以猜,他总是能猜到最能满足你需要的那种选择,如果你让他解决n皇后问题,他只要猜n次就能完成----每次都是那么幸运)解决的问题.这里有一个著名的问题----千禧难题之首,是说P问题是否等于NP问题,也即是否所有在非确定机上多项式可解的问题都能在确定机上用多项式时间求解.
简单的说,存在多项式时间的算法的一类问题,称之为P类问题;在多项式时间内可由非确定机解决的一类问题,称之为NP问题。另外,很多人相信P类问题是NP问题的一个子集,但既没有人证明出有某个问题属于NP但不属于P,也没有人证明所有NP问题都能在多项式时间内有解。
作者:匿名用户
链接:https://www.zhihu.com/question/24653072/answer/28536702
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
什么是P问题、NP问题和NPC问题
By Matrix67
还是先用几句话简单说明一下时间复杂度。时间复杂度并不是表示一个程序解决问题需要花多少时间,而是当问题规模扩大后,程序需要的时间长度增长得有多快。也就是说,对于高速处理数据的计算机来说,处理某一个特定数据的效率不能衡量一个程序的好坏,而应该看当这个数据的规模变大到数百倍后,程序运行时间是否还是一样,或者也跟着慢了数百倍,或者变慢了数万倍。不管数据有多大,程序处理花的时间始终是那么多的,我们就说这个程序很好,具有O(1)的时间复杂度,也称常数级复杂度;数据规模变得有多大,花的时间也跟着变得有多长,这个程序的时间复杂度就是O(n),比如找n个数中的最大值;而像冒泡排序、插入排序等,数据扩大2倍,时间变慢4倍的,属于O(n^2)的复杂度。还有一些穷举类的算法,所需时间长度成几何阶数上涨,这就是O(a^n)的指数级复杂度,甚至O(n!)的阶乘级复杂度。不会存在O(2*n^2)的复杂度,因为前面的那个“2”是系数,根本不会影响到整个程序的时间增长。同样地,O (n^3+n^2)的复杂度也就是O(n^3)的复杂度。因此,我们会说,一个O(0.01*n^3)的程序的效率比O(100*n^2)的效率低,尽管在n很小的时候,前者优于后者,但后者时间随数据规模增长得慢,最终O(n^3)的复杂度将远远超过O(n^2)。我们也说,O(n^100)的复杂度小于O(1.01^n)的复杂度。
容易看出,前面的几类复杂度被分为两种级别,其中后者的复杂度无论如何都远远大于前者:一种是O(1),O(log(n)),O(n^a)等,我们把它叫做多项式级的复杂度,因为它的规模n出现在底数的位置;另一种是O(a^n)和O(n!)型复杂度,它是非多项式级的,其复杂度计算机往往不能承受。当我们在解决一个问题时,我们选择的算法通常都需要是多项式级的复杂度,非多项式级的复杂度需要的时间太多,往往会超时,除非是数据规模非常小。
多项式倍数之所以特殊,主要是由于其值随n增大而加速增大的特性。如果是常数时间的话,意思就是无论n是什么值运算所花时间都一样。线性时间则是说多大n就花多少时间。多项式时间则意味着随着n增大,n每增加1所花的时间增长越来越多。对于n^2-3这样一个多项式时间来说,n=2的时候可能只要花1的时间,甚至低于线性时间,但n=4的时候可能就要花13的时间了,可以想象再大一些这个数值会变得巨大。
简而言之
n lg n n^x之类的就是多项式时间
x^n之类的就是非多项式时间
作者:李大雷
链接:https://www.zhihu.com/question/27039635/answer/83771163
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
首先这些p和np都是用来描述解决一个问题需要的时间和它输入规模之间的关系...
P问题:
一个问题可以在多项式(O(n^k))的时间复杂度内解决
例如:n个数的排序(不超过O(n^2))
NP问题:
一个问题的解可以在多项式的时间内被证实或证伪
例如:典型的子集求和问题,给定一个整数集合求是否存在一个非空子集它的和为零。如给定集合s={-1,3,2,-5,6},很明显子集{3,2,-5}能满足问题,并且验证该解只需要线性时间复杂度就能被证实。
NP-hard问题:
任意np问题都可以在多项式时间内归约为该问题。归约的意思是为了解决问题A,先将问题A归约为另一个问题B,解决问题B同时也间接解决了问题A。
例如,停机问题。
NPC问题:
既是NP问题,也是NP-hard问题。
例如,SAT问题(第一个NPC问题)。该问题的基本意思是,给定一系列布尔变量以及它的约束集,是否存在一个解使得它的输出为真。
相互关系:
显然,所有P问题都是NP问题,反之则不一定。npc问题是np问题的子集,也是p问题和np问题的差异所在。如果找到一个多项式内能被解决的npc问题的解决方法,那么P=NP。
作者:王宇
链接:https://www.zhihu.com/question/27039635/answer/101730260
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
最简单的解释:
P:算起来很快的问题
NP:算起来不一定快,但对于任何答案我们都可以快速的验证这个答案对不对
NP-hard:比所有的NP问题都难的问题
NP-complete:满足两点:
1. 是NP hard的问题
2. 是NP问题
接下来是比较严谨的定义:
问题:对于一个包含由0和1组成的字符串集合S,以某个01字符串x作为输入,要求某个图灵机判断x在不在S里面。这里的图灵机可以先想象成平时我们用的计算机,S也可以被看成我们要解决的问题。注意我们的问题非常简单,就是要判断某个字符串x是否在某个集合S里面,下面是定义:
P:有一个图灵机在多项式时间内能够判断x是否在S里面
NP:有一个图灵机M,如果某个字符串x在S里面,那么存在一个验证字符串u(注意这个u是针对这个x的,而且长度必须是x长度的多项式关系),M以x和u作为输入,能够验证x真的是在S里面。
NP-hard:如果某个问题S是NP-hard,那么对于任意一个NP问题,我们都可以把这个NP问题在多项式时间之内转化为S,并且原问题的答案和转化后S的答案是相同的。也就是说只要我们解决了S,那么就解决了所有的NP问题。
NP-complete:一个问题既是NP-hard,又在NP里面;也就是说
1. 解决了这个问题我们就解决了所有NP问题
2. 这个问题本身也是个NP问题
好,下面先来解释为什么会有人搞出来这么莫名其妙的定义。这真是说来话长。。。如果想要充分理解整个理论的动机,就逃不开理解图灵机。
1. 图灵机是什么?
想象你只有纸带和一个类似于打字机一样的,能够沿着纸带写0或1的自动写字装置(只能顺着纸带写不能跳跃),并且这个机器也能读在某个位置上的字符是0还是1,现在要求你用这样一套东西去实现一个算法,你会怎么做?observe,这就是计算机发明前数学家们手头的工具。粗略的说,这就是图灵机定义的来源。
另外我们还需要这个机器能够记录它之前做了什么事情,比如如果用这个机器算100+111,我们需要把纸带移到个位数,再开始加法,但我们需要及其能够记住 纸带已经到个位数 这件事,这样才能达到自动化,所以这个机器应该能够保存几个状态。这时有个问题:状态的数目可以根据输入变化吗?应该是不可以的,因为如果要机器能够自动执行某个算法,我们不希望换个输入就又要把机器重新制造一遍,这样简直比单独手算每个输入还麻烦,所以状态的数量应该是在造机器的时候就定死的(常数)。好奇的同学可能会问:那么状态数量就一定不能变化吗?答案是:如果变化,就不是一个图灵机模型了;图灵机只是很多种计算模型的一种,之所以它这么出名,是因为现代计算机就是一个通用图灵机,我们天天都在用。比如如果我们允许状态的数量根据输入长度变化,那么这就变成了一个boolean circuit,这个具体是什么就不展开了。
思考题:能否用上面定义的图灵机来实现一个简单的加法器呢?
2. 图灵机为什么这么重要?
如上所说,图灵机只是很多种计算模型中的一种。在计算理论之初,很多数学家提出过很多计算模型,图灵证明了其它很多计算模型都等价于图灵机(如果一个问题可以被其他计算模型解决,那么也可以被图灵机解决,反之亦然),时间的差距是多项式级别的(简单的理解为可忽略的差距)
如果你做了上面的思考题,那么对图灵机的运作模式应该有一定的感觉了。应该可以隐约感受到:所有的算法都是可以用这样简陋的图灵机实现的。那么问题来了:有没有一个图灵机可以执行所有的算法呢?这个脑洞来源于:图灵机本身无非包含纸袋,状态,字符表(简单的看成0和1),这样一个图灵机当然可以用二进制表示成一串字符,那么我可以构造一个“超级”图灵机N,每当我要计算某个问题S,不但把x输入进去,同时也把某个图灵机M输入进去,这个超级图灵机N就可以根据M的构造模仿M的执行模式,判断x是否在S里面。如果这样一个图灵机存在,那我们就获得了可怕的力量:有一个机器可以执行任意可以用图灵机标识的的算法了(你的电脑就是这样一台机器)!
3. 为什么是多项式时间
对啊为什么不用指数时间或者常数时间的区别来表示两个计算模型之间的等价呢,尤其是常数时间看起来更自然啊?比如刚才的加法器,如果你试着多增加几个状态,或者不光用01来表示数字,而是用十进制表示数字,你会发现你的计算速度有了多项式时间的提升!在理论体系里面我们不希望这么微小的变化就给我们带来本质上的提升,所以我们用多项式时间定义等价。
有的同学可能会问:那很大的多项式怎么办?比如几百次方之类的。。。一般来说常用的多项式算法(也就是P,能够被图灵机在多项式时间内计算),都是低次幂的。然而更合理的解释是:有的算法由于有高次幂,所以就不常用了,比如galactic algorithm,有很好的asymptotic behavior,但因为常数项太大所以从未被使用:
Galactic Algorithms
实用性和理论研究上确实有不同,理论研究更多的是针对某个计算模型(一般来说就是图灵积)而讲的有效率。
4. 关于NP:为什么验证一个答案的正确性这么重要?
因为最开始的时候都是数学家在搞这个,对于数学家来说如果有一个机器能帮助他们证明各种定理那就爽了。数学家经常干的两件事:1. 给出证明 2. 验证某个证明是不是对的。直觉上肯定验证更容易一些,但如果somehow可以证明NP=P,也就是说 验证 和 给出证明 其实在数学上是等价的,那么这个证明很可能给出了如何把 验证一个证明是否正确(NP)转化为 如何给出一个证明(P)的方法,从此以后数学家只要思考如何验证证明的正确性就能自动得到证明了,那不爽炸了。那个时候密码学的重要性只是崭露头角,但即使是在数学上的重要性,也足够让这个定义吸引人了。
5. 关于NP-complete,为什么要单独把NP里最难的问题拿出来
最开始的时候,大家不知道NP的定义是存在所谓 最难的 这么一个东西的,各类问题没有固定的比较标准。搞不好就没有这么一个最难的东西。直到一个叫Cook的数学家做了点CS的工作,最后还悲惨的没拿到教职,用教授的话说:“He's in the wrong department.” 他证明了任何一个NP形式的问题都可以转换成 3SAT (某个NP问题),3SAT 就是说有n个variable,m个clause,每个clause都是某三个variable 或(|) 在一起, 最后再把所有的clause 和(&) 在一起, 问题是:“有没有一种对于这n个variable的取值可以让整个boolean formula的值为true?” 3SAT 这个问题的优点在于它非常的直观清晰。最开始这篇文章没得到什么重视,直到一个非常出名的计算机科学家Levin看到了这篇文章,突然意识到如果这么多问题都等价于 3SAT 问题,那这就很好地揭示了为什么之前那么多算法问题都找不到快速的(多项式级)算法,因为都和3SAT一样难嘛;另外可以用 3SAT 作为对各种计算问题的分界线,那以后只要发现是NP-complete的问题,大家就不用对于每个问题找解法了。由此衍生了很多对于complexity class的研究,而cook-levin这种把NP问题化为3SAT的思想一次又一次起到了至关重要的作用。
6. 常见误区:NP=指数级算法?
不是的。
NP强调的是:易于验证答案的正确性
而指数级算法是指得:存在一个图灵机可以在指数时间内给出答案
如果熟悉了NP的定义,会发现明显指数级问题包含NP问题(?)因为根据上面的定义,只要验证对一个输入x是否存在一个u能够被某个图灵机M验证就好了,那么在指数时间内,我们可以定义一个hardcode了所有M的信息的图灵机N,N尝试所有可能的u,看有没有哪个u能迫使M接受x。由于u是多项式长度,这种尝试可以在指数时间内结束。
至今为止,我们也只知道NP是包含在指数(EXP)这个class里面的,但不知道它们相不相等。这也是整个复杂度理论很蛋疼的一点:真包含关系极其难以证明。有的时候真的让人很怀疑最初的分类方法是不是合理的,究竟是这些问题就没法被很完美的定义,还是只是我们不够聪明呢?