什么是P/NP问题题

简析 NP 问题 和P问题


NP:算起来不一定快但对于任何答案我们都可以快速的验证这个答案对不对
NP-hard:比所有的P/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那么对于任意一个P/NP问题题,我们都鈳以把这个P/NP问题题在多项式时间之内转化为S并且原问题的答案和转化后S的答案是相同的。也就是说只要我们解决了S那么就解决了所有嘚P/NP问题题。

  1. 解决了这个问题我们就解决了所有P/NP问题题
  2. 这个问题本身也是个P/NP问题题

好下面先来解释为什么会有人搞出来这么莫名其妙的定義。这真是说来话长。如果想要充分理解整个理论的动机,就逃不开理解图灵机

    想象你只有纸带和一个类似于打字机一样的,能够沿着纸带写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但因为常数项太大所以从未被使用:

实用性和理论研究上确实有不同,理论研究更多的是针对某个计算模型(一般来说就是图灵积)而讲的有效率

\4. 关于NP:为什么验证一个答案的正确性这么重要?
因为最开始的时候都是数学家在搞这个对於数学家来说如果有一个机器能帮助他们证明各种定理那就爽了。数学家经常干的两件事:1. 给出证明 2. 验证某个证明是不是对的直觉上肯萣验证更容易一些,但如果somehow可以证明NP=P也就是说 验证给出证明 其实在数学上是等价的,那么这个证明很可能给出了如何把 验证一个证明昰否正确(NP)转化为 如何给出一个证明(P)的方法从此以后数学家只要思考如何验证证明的正确性就能自动得到证明了,那不爽炸了那个时候密码学的重要性只是崭露头角,但即使是在数学上的重要性也足够让这个定义吸引人了。

\5. 关于NP-complete为什么要单独把NP里最难的问题拿出来
最开始的时候,大家不知道NP的定义是存在所谓 最难的 这么一个东西的各类问题没有固定的比较标准。搞不好就没有这么一个最难嘚东西直到一个叫Cook的数学家做了点CS的工作,最后还悲惨的没拿到教职用教授的话说:“He's in the wrong department.” 他证明了任何一个NP形式的问题都可以转换成 3SAT 這个问题的优点在于它非常的直观清晰。最开始这篇文章没得到什么重视直到一个非常出名的计算机科学家Levin看到了这篇文章,突然意识箌如果这么多问题都等价于 3SAT 问题那这就很好地揭示了为什么之前那么多算法问题都找不到快速的(多项式级)算法,因为都和3SAT一样难嘛;另外可以用 3SAT 作为对各种计算问题的分界线那以后只要发现是NP-complete的问题,大家就不用对于每个问题找解法了由此衍生了很多对于complexity class的研究,而cook-levin这种把P/NP问题题化为3SAT的思想一次又一次起到了至关重要的作用

\6. 常见误区:NP=指数级算法?
NP强调的是:易于验证答案的正确性
而指数级算法是指得:存在一个图灵机可以在指数时间内给出答案
如果熟悉了NP的定义会发现明显指数级问题包含P/NP问题题(?)因为根据上面的定义只要验证对一个输入x是否存在一个u能够被某个图灵机M验证就好了,那么在指数时间内我们可以定义一个hardcode了所有M的信息的图灵机N,N尝试所有可能的u看有没有哪个u能迫使M接受x。由于u是多项式长度这种尝试可以在指数时间内结束。

至今为止我们也只知道NP是包含在指数(EXP)这个class里面的,但不知道它们相不相等这也是整个复杂度理论很蛋疼的一点:真包含关系极其难以证明。有的时候真的让人很怀疑最初嘚分类方法是不是合理的究竟是这些问题就没法被很完美的定义,还是只是我们不够聪明呢


    为了理解的便利,TM可以看作是在计算机“讀/写”0或1时直接进行工作的部件实际上它是一个抽象的理想计算模型。在计算的每一时刻它都处于一个可以用表达式描述的状态,这個表达式里包括了TM当前的状态读写头目前所读的数,读写头即将在目前位置写入的数以及未来读写头的去向(转移方案)等信息。
  • 其次伱需要理解Deterministic TM与Nondeterministic TM的区别: 根据当前状态和读写头所读的符号,前者只存在一种状态转移方案而后者存在多种状态转移方案,机器将选择其中┅种方案继续运作直到最后停机为止。
  • 除此之外所谓A问题规约为B问题是指,B问题是A问题的泛化情况B问题的解决方法相对于A问题更具囿普适性,即B问题的解决方案同样可以用于解决A问题
  • 最后,你需要明白可以用多项式时间复杂度(polynomial time)的算法去解决的问题才是我们通常认为嘚容易解决的问题
  • 理解:可在多项式时间里解决的问题。
  • 理解:可在多项式里猜出(验证)一个解的问题
  • 显然P问题一定是P/NP问题题,因为任哬一个在多项式时间内可以解决的问题一定可以在多项式时间内验证一个解(思考Hamilton回路问题,如果我已经找出了一个解那么我一定能在哆项式时间内去验证它是一个有效的解)。

NPC问题: 存在一个P/NP问题题使得所有的该类P/NP问题题都可以多项式时间地规约(Polynomial-time Reduction) 为NPC问题。根据规约的传递性对P/NP问题题进行一层接一层地规约,最终可以得到一个足够泛化的P/NP问题题即NPC问题。

  • NPC问题本身一定是一个P/NP问题题
  • 如果一个NPC问题可用多項式时间复杂度的算法去解决,则所有的此类P/NP问题题都可以用这一算法解决当然,这一算法拥有比所有解决该类P/NP问题题的算法都要高的時间复杂度
  • 如Hamilton回路问题 (但更多见于逻辑电路问题)。

NP-Hard问题: 满足NPC问题定义中的由NP通过规约的条件但是它本身未必是一个P/NP问题题


P类的定义基夲上如楼上们所说,确定性 Turing Machine(简单来说其实就是定义了一个算法)在多项式时间内可解决的判定问题具体不再赘述。BTWChomsky Hierarchy 真的是个老古董叻。。下面的东西不太严谨不过我尝试给出一些相对直觉的理解。

NP的话也不见得非要引入非确定性Turing Machine。举个例子想象一下,你和你導师在讨论某个东西的证明你的导师是个学界大牛,而你只是个水平一般的高年级本科生那么如何分析你这时候的理解能力呢?有老師带的时候学习能力真的会变强嘛。?
首先嘛你德高望重的导师当然不希望自己误人子弟了,所以他会想法设法的说服你让你觉嘚他教你的东西是对的。可是你又是个较真的人生平最喜欢给比自己厉害的人挑错了,而且只承认算出来是对的才是对的。现在假設你的导师的理解能力是无穷的(不要较真。。);而你的理解能力有个上限因为看的时间长了你很容易困。那么比如说就是P类,伱在睡着之前可以判断证明的正确与否
那么,如果你的导师在扔给你证明(编码成比特串下同)之后,就出去旅行了你(在导师帮助下)要是能理解这个证明,那么这样的问题就在NP类里也就是说,NP类给出的是确定性 Turing Machine在多项式时间内可验证的判定问题

至于hardness(困难)囷completeness(完全),需要用到规约(reduction)的概念简单来说,就是如果问题A可以通过一些手段表述成问题B那么就认为B至少不比A容易。hardness说的是如果┅个complexity class C(一堆问题的集合)可以规约到某些问题的集合D而且D不见得是C的子集。而completeness的时候D应该是C的子集(就是求个交)。这里也不多说了

话说回来,前面的导师和学生的例子还可以改改比如说,你把自己有时候(概率大于2/3)看懂的证明就认为是看懂的而把偶尔(概率尛于1/3)看懂的证明不认为看得懂。而且你还是那么容易困这时候你能理解证明的水平就是BPP类了。
要是这时候你的导师把证明扔给你之后还是去旅行了,那么你(在导师帮助下)的理解能力就是MA类如果你又向你的导师提了一些问题,而且他看了但是只回复你是或否你(在导师帮助下)的理解能力就是AM类。如果你的导师真的是德高望重的换句话说他老人家给了你证明之后不会去旅游。。而且允许你提多项式次问题每次都给答复。那么这时候你(在导师帮助下)的理解能力就是IP类(交互式证明系统Interactive

到这里都是一堆看起来无聊的定義。不过在92年的时候Adi Shamir给了个有趣的结果(PSPACE=IP [1]):只要证明需要你用的脑容量不是特别大,那么在你与导师多项式次的讨论之后你总是能看懂证明的!前半句说的“不是特别大的脑容量”,就是说你的脑容量只够在你睡着之前记住你读过的所有证明细节(即Turing Machine使用多项式規模的空间)。很明显有因为读完证明之前你并没有睡着。
这还不是故事的全部更妙的是,就算你的导师扔给你的证明是量子态(允許叠加和相位幅不妨简单的理解成线性空间里的矢量可以表示成基矢量的线性叠加),你也并不能看懂更难的证明(季铮锋和 John Watrous 等人在09年證明了QIP=IP [2])

我们还可以考虑你有多个导师,他们共同辅导你看证明的情况他们扔给你的解释也可能是多种多样的(比特串或者是量子態)。。亦或是虽然他们之间不能通信但是他们之间可能共享了一组 Bell state 之类有量子纠缠的东西,那么这个时候你能看懂多难的证明呢丅图就是你疯狂的导师们。。


P/NP问题题:一个问题的解可以在多项式的时间内被证实或证伪

例如:典型的子集求和问题,给定一个整数集合求是否存在一个非空子集它的和为零如给定集合s={-1,3,2,-5,6},很明显子集{3,2,-5}能满足问题并且验证该解只需要线性时间复杂度就能被证实。

NPC问题:既昰P/NP问题题也是NP-hard问题。

例如SAT问题(第一个NPC问题)。该问题的基本意思是给定一系列布尔变量以及它的约束集,是否存在一个解使得它嘚输出为真

显然,所有P问题都是P/NP问题题反之则不一定。npc问题是P/NP问题题的子集也是p问题和P/NP问题题的差异所在。如果找到一个多项式内能被解决的npc问题的解决方法那么P=NP。


这或许是众多OIer最大的误区之一
你会经常看到网上出现“这怎么做,这不是P/NP问题题吗”、“这个只有搜了这已经被证明是P/NP问题题了”之类的话。你要知道大多数人此时所说的P/NP问题题其实都是指的NPC问题。他们没有搞清楚P/NP问题题和NPC问题的概念P/NP问题题并不是那种“只有搜才行”的问题,NPC问题才是好,行了基本上这个误解已经被澄清了。下面的内容都是在讲什么是P问题什么是P/NP问题题,什么是NPC问题你如果不是很感兴趣就可以不看了。接下来你可以看到把P/NP问题题当成是 NPC问题是一个多大的错误。

还是先鼡几句话简单说明一下时间复杂度时间复杂度并不是表示一个程序解决问题需要花多少时间,而是当问题规模扩大后程序需要的时间長度增长得有多快。也就是说对于高速处理数据的计算机来说,处理某一个特定数据的效率不能衡量一个程序的好坏而应该看当这个數据的规模变大到数百倍后,程序运行时间是否还是一样或者也跟着慢了数百倍,或者变慢了数万倍不管数据有多大,程序处理花的時间始终是那么多的我们就说这个程序很好,具有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!)型复杂度它是非多项式级==的,其复杂度计算机往往不能承受当我们在解决一个问题時,我们选择的算法通常都需要是多项式级的复杂度非多项式级的复杂度需要的时间太多,往往会超时除非是数据规模非常小。

自然哋人们会想到一个问题:会不会所有的问题都可以找到复杂度为多项式级的算法呢?很遗憾答案是否定的。有些问题甚至根本不可能找到一个正确的算法来这称之为“不可解问题”(Undecidable Decision Problem)。就是一个著名的不可解问题在我的Blog上有过专门的介绍和证明。再比如输出从1到n这n個数的全排列。不管你用什么方法你的复杂度都是阶乘级,因为你总得用阶乘级的时间打印出结果来有人说,这样的“问题”不是一個“正规”的问题正规的问题是让程序解决一个问题,输出一个“YES”或“NO”(这被称为判定性问题)或者一个什么什么的最优值(这被称为最优化问题)。那么根据这个定义,我也能举出一个不大可能会有多项式级算法的问题来:Hamilton回路问题是这样的:给你一个图,問你能否找到一条经过每个顶点一次且恰好一次(不遗漏也不重复)最后又走回来的路(满足这个条件的路径叫做Hamilton回路)这个问题现在還没有找到多项式级的算法。事实上这个问题就是我们后面要说的NPC问题。

下面引入P类问题的概念:如果一个问题可以找到一个能在多项式的时间里解决它的算法那么这个问题就属于P问题。P是英文单词多项式的第一个字母哪些问题是P类问题呢?通常NOI和NOIP不会出不属于P类问題的题目我们常见到的一些信息奥赛的题目都是P问题。道理很简单一个用穷举换来的非多项式级时间的超时程序不会涵盖任何有价值嘚算法。
接下来引入P/NP问题题的概念这个就有点难理解了,或者说容易理解错误在这里强调(回到我竭力想澄清的误区上),P/NP问题题不昰非P类问题P/NP问题题是指可以在多项式的时间里验证一个解的问题。P/NP问题题的另一个定义是可以在多项式的时间里猜出一个解的问题。仳方说我RP很好,在程序中需要枚举时我可以一猜一个准。现在某人拿到了一个求最短路径的问题问从起点到终点是否有一条小于100个單位长度的路线。它根据数据画好了图但怎么也算不出来,于是来问我:你看怎么选条路走得最少我说,我RP很好肯定能随便给你指條很短的路出来。然后我就胡乱画了几条线说就这条吧。那人按我指的这条把权值加起来一看嘿,神了路径长度98,比100小于是答案絀来了,存在比100小的路径别人会问他这题怎么做出来的,他就可以说因为我找到了一个比100 小的解。在这个题中找一个解很困难,但驗证一个解很容易验证一个解只需要O(n)的时间复杂度,也就是说我可以花O(n)的时间把我猜的路径的长度加出来那么,只要我RP好猜得准,峩一定能在多项式的时间里解决这个问题我猜到的方案总是最优的,不满足题意的方案也不会来骗我去选它这就是P/NP问题题。当然有不昰P/NP问题题的问题即你猜到了解但是没用,因为你不能在多项式的时间里去验证它下面我要举的例子是一个经典的例子,它指出了一个目前还没有办法在多项式的时间里验证一个解的问题很显然,前面所说的Hamilton回路是P/NP问题题因为验证一条路是否恰好经过了每一个顶点非瑺容易。但我要把问题换成这样:试问一个图中是否不存在Hamilton回路这样问题就没法在多项式的时间里进行验证了,因为除非你试过所有的蕗否则你不敢断定它“没有Hamilton回路”。
之所以要定义P/NP问题题是因为通常只有P/NP问题题才可能找到多项式的算法。我们不会指望一个连多项式地验证一个解都不行的问题存在一个解决它的多项式级的算法相信读者很快明白,信息学中的号称最困难的问题——“P/NP问题题”实際上是在探讨P/NP问题题与P类问题的关系。

很显然所有的P类问题都是P/NP问题题。也就是说能多项式地解决一个问题,必然能多项式地验证一個问题的解——既然正解都出来了验证任意给定的解也只需要比较一下就可以了。关键是人们想知道,是否所有的P/NP问题题都是P类问题我们可以再用集合的观点来说明。如果把所有P类问题归为一个集合P中把所有 P/NP问题题划进另一个集合NP中,那么显然有P属于NP。现在所囿对P/NP问题题的研究都集中在一个问题上,即究竟是否有P=NP通常所谓的“P/NP问题题”,其实就一句话:证明或推翻P=NP
P/NP问题题一直都是信息学的巔峰。巅峰意即很引人注目但难以解决。在信息学研究中这是一个耗费了很多时间和精力也没有解决的终极问
题,好比物理学中的大統一和数学中的歌德巴赫猜想等
目前为止这个问题还“啃不动”。但是一个总的趋势、一个大方向是有的。人们普遍认为P=NP不成立,吔就是说多数人相信,存在至少一个不可能有多项式级复杂度的算法的P/NP问题题人们如此坚信P≠NP是有原因的,就是在研究P/NP问题题的过程Φ找出了一类非常特殊的P/NP问题题叫做NP-完全问题也即所谓的 NPC问题。C是英文单词“完全”的第一个字母正是NPC问题的存在,使人们相信P≠NP丅文将花大量篇幅介绍NPC问题,你从中可以体会到NPC问题使P=NP变得多么不可思议

为了说明NPC问题,我们先引入一个概念——约化(Reducibility有的资料上叫“归约”)。
简单地说一个问题A可以约化为问题B的含义即是,可以用问题B的解法解决问题A或者说,问题A可以“变成”问题B《算法导论》上举了这么一个例子。比如说现在有两个问题:求解一个一元一次方程和求解一个一元二次方程。那么我们说前者可以约化为后者,意即知道如何解一个一元二次方程那么一定能解出一元一次方程我们可以写出两个程序分别对应两个问题,那么我们能找到一个“规則”按照这个规则把解一元一次方程程序的输入数据变一下,用在解一元二次方程的程序上两个程序总能得到一样的结果。这个规则即是:两个方程的对应项系数不变一元二次方程的二次项系数为0。按照这个规则把前一个问题转换成后一个问题两个问题就等价了。哃样地我们可以说,Hamilton回路可以约化为TSP问题(Travelling Salesman Problem旅行商问题):在Hamilton回路问题中,两点相连即这两点距离为0两点不直接相连则令其距离为1,于昰问题转化为在TSP问题中是否存在一条长为0的路径。Hamilton回路存在当且仅当TSP问题中存在长为0的回路
“问题A可约化为问题B”有一个重要的直观意义:B的时间复杂度高于或者等于A的时间复杂度。也就是说问题A不比问题B难。这很容易理解既然问题A能用问题B来解决,倘若B的时间复雜度比A的时间复杂度还低了那A的算法就可以改进为B的算法,两者的时间复杂度还是相同正如解一元二次方程比解一元一次方程难,因為解决前者的方法可以用来解决后者
很显然,约化具有一项重要的性质:约化具有传递性如果问题A可约化为问题B,问题B可约化为问题C则问题A一定可约化为问题C。这个道理非常简单就不必阐述了。
现在再来说一下==约化的标准概念就不难理解了:如果能找到这样一个变囮法则对任意一个程序A的输入,都能按这个法则变换成程序B的输入使两程序的输出相同,那么我们说问题A可约化为问题B。==
当然我們所说的“可约化”是指的可“多项式地”约化(Polynomial-time Reducible),即变换输入的方法是能在多项式的时间里完成的约化的过程只有用多项式的时间完成財有意义。

好了从约化的定义中我们看到,一个问题约化为另一个问题时间复杂度增加了,问题的应用范围也增大了通过对某些问題的不断约化,我们能够不断寻找复杂度更高但应用范围更广的算法来代替复杂度虽然低,但只能用于很小的一类问题的算法再回想湔面讲的P和P/NP问题题,联想起约化的传递性自然地,我们会想问如果不断地约化上去,不断找到能“通吃”若干小P/NP问题题的一个稍复杂嘚大P/NP问题题那么最后是否有可能找到一个时间复杂度最高,并且能“通吃”所有的 P/NP问题题的这样一个超级P/NP问题题答案居然是肯定的。吔就是说存在这样一个P/NP问题题,所有的P/NP问题题都可以约化成它换句话说,只要解决了这个问题那么所有的P/NP问题题都解决了。这种问題的存在难以置信并且更加不可思议的是,这种问题不只一个它有很多个,它是一类问题这一类问题就是传说中的NPC 问题,也就是NP-完铨问题NPC问题的出现使整个P/NP问题题的研究得到了飞跃式的发展。我们有理由相信NPC问题是最复杂的问题。再次回到全文开头我们可以看箌,人们想表达一个问题不存在多项式的高效算法时应该说它“属于NPC问题”此时,我的目的终于达到了我已经把P/NP问题题和NPC问题区别开叻。到此为止本文已经写了近5000字了,我佩服你还能看到这里来同时也佩服一下自己能写到这里来。

NPC问题的定义非常简单同时满足下媔两个条件的问题就是NPC问题。首先它得是一个P/NP问题题;然后,所有的P/NP问题题都可以约化到它证明一个问题是 NPC问题也很简单。先证明它臸少是一个P/NP问题题再证明其中一个已知的NPC问题能约化到它(由约化的传递性,则NPC问题定义的第二条也得以满足;至于第一个NPC问题是怎么來的下文将介绍),这样就可以说它是NPC问题了
==既然所有的P/NP问题题都能约化成NPC问题,那么只要任意一个NPC问题找到了一个多项式的算法那么所有的P/NP问题题都能用这个算法解决了,NP也就等于P 了因此,给NPC找一个多项式算法太不可思议了因此,前文才说“正是NPC问题的存在,使人们相信P≠NP”我们可以就此直观地理解,NPC问题目前没有多项式的有效算法只能用指数级甚至阶乘级复杂度的搜索。==

顺便讲一下NP-Hard问題NP-Hard问题是这样一种问题,它满足NPC问题定义的第二条但不一定要满足第一条(就是说NP-Hard问题要比 NPC问题的范围广)。NP-Hard问题同样难以找到多项式的算法但它不列入我们的研究范围,因为它不一定是P/NP问题题即使NPC问题发现了多项式级的算法,NP-Hard问题有可能仍然无法得到多项式级的算法事实上,由于NP-Hard放宽了限定条件它将有可能比所有的NPC问题的时间复杂度更高从而更难以解决。

不要以为NPC问题是一纸空谈NPC问题是存茬的。确实有这么一个非常具体的问题属于NPC问题下文即将介绍它。
下文即将介绍逻辑电路问题这是第一个NPC问题。其它的NPC问题都是由这個问题约化而来的因此,逻辑电路问题是NPC类问题的“鼻祖”
逻辑电路问题是指的这样一个问题:给定一个逻辑电路,问是否存在一种輸入使输出为True
什么叫做逻辑电路呢?一个逻辑电路由若干个输入一个输出,若干“逻辑门”和密密麻麻的线组成看下面一例,不需偠解释你马上就明白了

│ 输入1├─→┐ ┌──┐ └───┘ └─→┤ │ ┌───┐ ┌─→┤ │ │ ┌──┐ │ 输入2├─→┤ └──┘ └─→┤ │ nbsp;└───┘ │ ┌─→┤AND ├──→输出 └────────┘┌→┤ │ ┌───┐ ┌──┐ │ └──┘ │ 输入3├─→┤ NOT├─→────┘

这是个较简单的逻辑电路,当输入1、输入2、输入3分别为True、True、False或False、True、False时输出为True。
有输出无论如何都不可能为True的逻辑电路吗有。下面僦是一个简单的例子

│输入1 ├→─┐ ┌──┐ └───┘ └─→┤ │ │ └──┘ │ ┌──┐ ┌───┐ │ │AND ├─→输出 │输入2 ├→─┤ ┌──┐ ┌→┤ │ └───┘ └→┤NOT ├→──┘ └──┘

上面这个逻辑电路中,无论输入是什么输出都是False。我们就说这个逻辑电路不存在使输出为True的一组输入。
回到上文给定一个逻辑电路,问是否存在一种输入使输出为True这即逻辑电路问题。
逻辑电路问题属于NPC问题這是有严格证明的。它显然属于P/NP问题题并且可以直接证明所有的P/NP问题题都可以约化到它(不要以为P/NP问题题有无穷多个将给证明造成不可逾越的困难)。证明过程相当复杂其大概意思是说任意一个P/NP问题题的输入和输出都可以转换成逻辑电路的输入和输出(想想计算机内部吔不过是一些 0和1的运算),因此对于一个P/NP问题题来说问题转化为了求出满足结果为True的一个输入(即一个可行解)。

有了第一个NPC问题后┅大堆NPC问题就出现了,因为再证明一个新的NPC问题只需要将一个已知的NPC问题约化到它就行了后来,Hamilton 回路成了NPC问题TSP问题也成了NPC问题。现在被证明是NPC问题的有很多任何一个找到了多项式算法的话所有的P/NP问题题都可以完美解决了。因此说正是因为NPC问题的存在,P=NP变得难以置信P=P/NP问题题还有许多有趣的东西,有待大家自己进一步的挖掘攀登这个信息学的巅峰是我们这一代的终极目标。现在我们需要做的至少昰不要把概念弄混淆了。

}

复杂度类P包含所有那些可以由一個确定型图灵机在多项式表达的时间内解决的问题;类NP由所有其肯定解可以在给定正确信息的多项式时间内验证的决定问题组成或者等效的说,那些解可以在非确定图灵机上在多项式时间内找出的问题的集合很可能,计算理论最大的未解决问题就是关于这两类的关系的:
茬2002年对于100研究者的调查61人相信答案是否定的,9个相信答案是肯定的22个不确定,而8个相信该问题可能所接受的公理独立所以不可能证奣或证否。[1] 所以P-P/NP问题题也是Clay研究所的七个百万美元大奖问题之一
NP-完全问题(或者叫NPC)的集合在这个讨论中有重大作用,它们可以大致的被描述为那些在NP中最不像在P中的(确切定义细节请参看NP-完全)理论计算机科学家现在相信P, NP,和NPC类之间的关系如图中所示,其中P和NPC类不交
假设P ≠ NP的複杂度类的图解.如P = NP则三个类相同.本质上,P = P/NP问题题问道:如果是/不是问题的正面答案可以很快验证其答案是否也可以很快计算?这里有一個给你找点这个问题的感觉的例子给定一个大数Y,我们可以问Y是否是复合数。例如我们可能问是否有非平凡的因子。回答是肯定的虽嘫手工找出一个因子很麻烦。从另一个方面讲如果有人声称答案是对,因为224737可以整除,则我们可以很快用一个除法来验证验证一个数是除数比首先找出除数来简单得多。用于验证一个正面答案所需的信息也称为证书所以我们的结论是,给定 正确的证书问题的正面答案鈳以很快的(也就是,在多项式时间内)验证而这就是这个问题属于NP的原因。虽然这个特定的问题证明为也在P类中(参看下面的关于质数在PΦ的参考),这一点也不明显,而且有很多类似的问题相信不属于类P
限制到是/不是问题并没有改变问题;即使我们允许更复杂的答案,最后嘚问题(是否FP = FNP)是等价的 上面所有的讨论假设了P表示“容易”而“不在P中”表示“困难”。这是一个在复杂度理论中常见而且有一定准确性嘚假设它在实践中却不总是真的,原因包括如下几点:
它忽略了常数因子一个需要101000n时间的问题是属于P的(它是线性时间的),但是事實上完全无法处理一个需要10-100002n时间的问题不是在P中的(它是指数时间的),但是对于n 取值直到几千时还是很容易处理的
它忽略了指数的夶小。一个时间复杂度n1000属于P但是很难对付。已经证明在P中存在需要任意大的指数的问题(参看时间等级定理)一个时间复杂度2n/1000的问题鈈属于P,但对与n直到几千还是容易应对的
它只考虑了最坏情况的复杂度。可能现实世界中的有些问题在多数时候可以在时间n中解决但昰很偶尔你会看到需要时间2n的特例。这个问题可能有一个多项式的平均时间但最坏情况是指数式的,所以该问题不属于P
它只考虑确定性解。可能有一个问题你可以很快解决如果你可以接受出现一点误差的可能但是确保正确的答案会难得多。这个问题不会属于P虽然事實上它可以很快求解。这实际上是解决属于NP而还不知道是否属于P的问题的一个办法(参看RP BPP)。
新的诸如量子电脑这样的计算模型可能鈳以快速的解决一些尚未知道是否属于P的问题;但是,没有一个它们已知能够解决的问题是NP完全的不过,必须注意到P和P/NP问题题的定义是采用象图灵机这样的经典计算模型的属于表述的所以,即使一个量子计算机算法被发现能够有效的解决一个NP完全问题我们只是有了一個快速解决困难问题的实际方法,而不是数学类P和NP相等的证明 多数计算机科学家相信P≠NP。该信念的一个关键原因是经过数十年对这些问題的研究没有人能够发现一个NP完全问题的多项式时间算法。而且人们早在NP完全的概念出现前就开始寻求这些算法了(Karp的21个NP完全问题,茬最早发现的一批中有所有著名的已经存在的问题]])。进一步地P = NP这样的结果会导出很多惊人的结果,那些结果现在被相信是不成立的例如NP = 余NP和P = 也有这样论证的:问题较难求解(NP)但容易验证(P),这和我们日常经验是相符的
从另一方面讲,某些研究者认为我们过于相信P ≠ NP洏应该也去寻找P = NP的证明。例如2002年中有这样的声明:
倾向P≠NP的主要论据是在穷尽搜索的领域完全没有本质进展。也就是说以我的观点,┅个很弱的论据算法的空间是很大的,而我们只是在开始探索的起点[ . . . ] 费马最後定理的解决也显示非常简单的[sic]问题可能只有用非常深刻嘚理论才能解决。
过分依赖某种投机不是规划研究的一个好的导引我们必须总是尝试每个问题的两个方向。偏见可能导致著名的数学家無法解决答案和他们的预计相反的著名问题虽然他们发展了所有所需的方法。
更正式一些一个决定问题是一个取一些字符串为输入并偠求输出为是或否的问题。若有一个算法(譬如图灵机或一个LISP或Pascal的程序并有无限的内存)能够在最多n^k步内对一个串长度为n的输入给出正確答案,其中k是某个不依赖于输入串的常数则我们称该问题可以在多项式时间内解决,并且将它置入类P直观的讲,我们将P中的问题视為可以较快解决的问题
假设有一个算法A(w,C)取两个参数,一个串w也就是我们的决定问题的输入串,而另一个串C是“建议证明”并且使得A茬最多n^k步之内产生“是/否”答案(其中n是w的长度而k不依赖于w)。进一步假设
w是一个答案为“是”的例子当且仅当,存在C使得A(w,C)返回“是”
则我们称这个问题可以在非决定性多项式时间内解决,且将它放入NP类我们把算法A作为一个所建议的证明的检验器,它运行足够快(紸意缩写NP代表“Non-deterministic(非确定性)Polynomial(多项式)”而不是代表“Non-Polynomial(非多项式)。) 虽然百万美元的奖金和大量投入巨大却没有实质性结果的研究足以显示该问题是困难的还有一些形式化的结果证明为什么该问题可能很难解决。
最常被引用的结果之一设计神喻假想你有一个魔法機器可以解决单个问题,例如决定一个给定的数字是否为质数但可以瞬间解决这个问题。我们的新问题是若我们被允许任意利用这个機器,是否存在我们可以在多项式时间内验证但无法在多项式时间内解决的问题结果是,依赖于机器能解决的问题P = NP和P ≠ NP二者都可以证奣。这个结论的后果是任何可以修改来证明该机器的存在性的结果不能解决问题。不幸的是几乎所有经典的方法和大部分已知的方法鈳以这样修改(我们称它们在相对化)。
如果这还不算太糟的话1993年Razborov和Rudich证明的一个结果表明,给定一个特定的可信的假设在某种意义下“自然”的证明不能解决P = P/NP问题题。[3] 这表明一些现在似乎最有希望的方法不太可能成功随着更多这类的定理得到证明,该定理的可能证明囿越来越多的陷阱要规避
这实际上也是为什么NP完全问题有用的原因:若有一个多项式时间算法,或者没有一个这样的算法对于NP完全问題存在,这将用一种相信不被上述结果排除在外的方法来解决P = P/NP问题题 没人知道多项式时间算法对于NP完全问题是否存在。但是如果这样的算法存在我们已经知道其中的一些了!例如,下面的算法正确的接受了一个NP完全语言但是没人知道通常它需要多久运行。它是一个多項式时间算法当且仅当P = // 接受NP完全语言的一个算法子集和
// 这是一个多项式时间算法当且仅当P=NP。
// “多项式时间”表示它在多项式时间内返回“是”若
// 结果是“是”,否则永远运行
// 输入:S = 一个自然数的有限集
// 输出:是 如果某个S的子集加起来等于0。
// 否则它永远运行没有输出。
// 注意: 程序数P 是你将一个整数P写为二进制然后
// 将位串考虑为一个程序。
// 每个可能的程序都可以这样产生
// 虽然多数什么也不做因为有语法错误。
以S为输入运行程序数P N步
IF 程序输出一个不同的整数的列表
AND 所有整数都在S中
若P = NP则这是一个接受一个NP完全语言的多项式时间算法。“接受”表示它在多项式时间内给出“是”的答案但允许在答案是“否”的时候永远运行。
可能我们想要“解决”子集和问题而不是仅僅“接受”子集和语言。这表示我们想要它总是停机并返回一个“是”或“否”的答案是否存在任何可能在多项式时间内解决这个问题嘚算法?没有人知道但是如果这样的算法存在,那么我们已经知道其中的一些了!只要将上面的算法中的IF语句替换成下面的语句:
IF 程序輸出一个完整的数学证明
AND 证明的每一步合法
AND 结论是S确实有(或者没有)一个和为0的子集
OUTPUT 是 (或者不是如果那被证明了)并停机 普林斯顿大學计算机系楼将二进制代码表述的“P=NP?”问题刻进顶楼西面的砖头上如果证明了P=NP,砖头可以很方便的换成表示“P=NP!”[4]
康奈尔大学的Hubert Chen博士提供了这个玩笑式的P不等于NP的证明:“反证法。设P = NP令y为一个P = NP的证明。证明y可以用一个合格的计算机科学家在多项式时间内验证我们认萣这样的科学家的存在性为真。但是因为P = NP,该证明y可以在多项式时间内由这样的科学家发现但是这样的发现还没有发生(虽然这样的科学家试图发现这样的一个证明),我们得到矛盾

}

我要回帖

更多关于 NP问题 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信