什么是NP问题,什么是NP hard问题,什么是NP完全问题。

http://www.cs.pitt.edu/~ztliu/wordpress/2011/05/np-problem/


首先解释一下什么是NP问题,什么是NP hard问题,什么是NP完全问题。

看下面的图,他们之间的关系表示的比较清楚。

P Problem:这个应该最易理解,就是一个问题可以在Polynominal的时间的得到解决,当然,是对于任意input size。

NP Problem:对于一类问题,我们可能没有一个已知的快速的方法得到问题的答案,但是如果给我们一个candidate answer,我们能够在polynominal的时间内验证这个candidate answer到底是不是我们已知问题的答案,这类问题叫做NP problem。所以很显然 P Problem是NP problem的一个子集。

NP-hard Problem:对于这一类问题,用一句话概括他们的特征就是“at least as hard as the hardest problems in NP Problem”, 就是NP-hard问题至少和NP问题一样难。

NP-complete Problem:对于这一类问题,他们满足两个性质,一个就是在polynomial时间内可以验证一个candidate answer是不是真正的解,另一个性质就是我们可以把任何一个NP问题在polynomial的时间内把他的input转化,使之成为一个NP-complete问题。

所以对于NP-hard问题,我们可以把他们分成两个部分,一部分可以用polynomial的时间验证一个candidate answer是不是真正的answer,这一部分问题组成了NP-complete集合。

我们经常说的NP=P或者NP!=P,其实就是说目前而言,我们并不知道,是不是对于NP Problem集合里面的所有问题,都能够在Polynomial的时间内解决。当然只里面比较interesting的一点是,如果我们能把NP-complete集合中的任意一个问题在polynomial的时间内解决了,那么所有的NP问题都可以在polynomial的时间内解决。原因,看看上面说的NP-complete的性质就知道了,因为任何一个NP问题都可以在polynomial的时间内把他的input转化,使之成为一个NP-complete问题,所以….

介绍了上面说的一些定义,来举几个经典的NP-complete的问题。


Vertex Cover http://en.wikipedia.org/wiki/Vertex_Cover

Informally来说,就是对于一个图G(V,E),我们在V中选一个subset V’, 使得E中的所有边得两点中的一个点在V’中。 所谓Vertex Cover也就是说V’中的点cover了每一条边(因为每一条边至少有一端是在V’中的啦)给你一个G(V,E)和一个k,问你在整个G中,是否存在一个大小为k的Vertex Cover(Decision Problem)

Formally, a vertex cover of a graph G is a set C of vertices such that each edge of G is incident to at least one vertex in C. The set C is said to cover the edges of G. The following figure shows examples of vertex covers in two graphs (the set C is marked with red).

3-CNF-SAT http://en.wikipedia.org/wiki/3SAT#3-satisfiability

举个例子,

[latex]

E = (X_1 \lor \lnot X_2 \lor \lnot X_3) \wedge (X_1 \lor X_2 \lor X_4)

[/latex]

每一个括号包括的东西叫一个clause,里面的X1,X2,X3在离散数学里面叫做文字,取值True或者False。每个括号之间是合取,括号里面是析取,这个问题就是,对于这样的一个表达式,是不是能找到一组Xi的值,使得表达式为True。 Given the expression, is there some assignment of TRUE and FALSE values to the variables that will make the entire expression true?

Integer Linear Programming http://en.wikipedia.org/wiki/Linear_program#Integer_unknowns

当然这个最显而易见了,就是LP中的所有变量都要求是整数了。关于Linear Programming的问题,后面会专门有一篇文章来讲解。O(∩_∩)O~

下面来看看我们经常会遇到的一些证明问题。

证明一个问题是NP问题。证明给你一个结果,你能在polynomial的时间内验证他的正确性

证明一个问题是NP-hard的。对于证明一个问题是NP-hard,我们经常用到的一个technique是归约(reduction),通常用<=这个符号来表示,如P<=Q,这个就表示P is reducible to Q or Q is the reduction from P or P is reduced to Q. P问题可以归约到Q问题。可以把P归约到Q。这里的reduction的符号可以当成是 比较难易程度的小于等于号,意味着问题Q至少和问题P一样难。当我们要证明一个问题是NP-hard的时候,我们通常要做的是找到一个NPC问题(就用这个代替NP-complete问题),把这个NPC问题归约到NP-hard上去,即NPC<=NP-hard。

证明一个问题是NPC的。要证NPC,我们要分两步走,第一步证明这个问题属于NP,就是验证答案(感觉这句话我都说烂了)。第二步,证明这个问题是NP-hard的。当然这里面第二步是问题的关键,但是第一步也一定要在证明里面提到。

如何证明一个问题是NP-hard 是以上证明的关键,即如何归约。

这里我们归约要做的主要步骤就是,

1.把NPC的input转化到NP-hard的input,即每一个NPC的input,实际上都是一个NP-hard的input。

2.把NP-hard的output转化到NPC的output上来,说明给我一个NP-hard的output,我就能给你一个NPC的output。

注意:以上的两个转化都要在polynomial的时间内完成。

下面举几个例子来证明上面的归约的方法。


例 用3SAT 证明 Vertex Cover是NP-hard的。即 3SAT <= Vertex Cover

这个就是表明我们已知3SAT这个问题是NP-complete的,如何把3SAT问题归约到Vertex Cover上。

首先,我们要建立我们的通过input建立这两个问题的对应。假设我的3SAT是

[latex]

E = (X_1 \lor \lnot X_2 \lor \lnot X_3) \wedge (X_1 \lor X_2 \lor X_4)

[/latex]

我们按照下面的方法构造我们的Graph,对应每一个个变量Xi,我们构造点 Xi和~Xi,对于每一个clause,我们构造3个点,这3个点直接彼此有边,假设这三个点叫A,B,C。同时我们还要建立A,B,C这三个点和该clause的联系:假设我们的clause是 (X1 V ~X2 V ~X3) 我们就把X1和A连起来,~X2和B连起来,~X3和C连起来。注意,每一个clause有一个全连通的三角,他们共用那6个变量点(X1,~X1,X2,~X2,X3,~X3) 如下图所示。

要注意的一点是,对于E中的每一个clause,我们都对应图里面的一个三角形(也就是我用矩形圈住的那部分),同时所有的clause共享上面的六个点,也就是2*变量个数 那么多个点是共用的。

通过这个图,我们也就建立起了3SAT和Vertex Cover之间的联系。通常这个也是此类证明问题中最难和最creative的部分。

后面就是表述一下如何进行转换的。通常这个是很trival的部分。

1)假设我有一个解能满足3SAT,那么我就一定能找到相应的解满足Veterx Cover。 如上图,3SAT满足了,必然每一个clause满足,就拿 (X1 V ~X2 V ~X3) 为例,这个式子满足了,必有一个变量为true,它可以是X1或者~X2或者~X3,假设X1为true,这时对应的vertex cover中,我们就选上面6个点中的X1,同时对于下面的三角形中的3个点,我们选除了那个与X1相连的另外两个点。对于每一个clause,我们都可以这样做,同时,我们也cover了这个图中的所有边。也就是我们有了一个满足要求的vertex cover。

2)假设我有一个解能满足Vertex Cover,那么我就一定能找到相应的解满足3SAT。因为要cover这个图,所以三角形里面至少要cover两个点,上面的一对一对的pair里面也至少要cover一个,所以对于一个size为n+2m的vertex cover(n是变量个数,m是clause的个数),我们一定可以找到一个满足的3SAT,(显然啊,因为每个clause都有一个点和上面的一对一对pair的点相连) (说的好拗口,郁闷。还不清楚的可以看下这个链接http://users.eecs.northwestern.edu/~fortnow/classes/w08/EECS395/lecture11.pdf

然后,然后,。。。我们就证完了。

例 用3SAT证明ILP是NP-hard的。即 3SAT <= ILP

还是首先找映射,这个映射不涉及图的东西,应该比较容易构造和理解。

还是拿上面那个3SAT的例子说事。对于 每个clause,我们都对应于ILP中的一个constraint,比如 E中有4个变量,X1,X2,X3 和X4, 我们的ILP中也有同样的这4个变量,并且我们要求他们都是只能取0 或 1。对于一个clause,如(X1 V ~X2 V ~X3) ,我们对应的constraint是 “X1 + (1-X2)+(1-X3)>=1”,很显然了,ILP中的变量选0对应于3SAT中的变量选false,ILP中的变量选1对应于3SAT中的变量选true,这样我们就映射好了。

很显然,这两个问题的input/output的转换trival的不行了。如果一个clause满足了,对应的那个ILP中的constraint肯定也满足了;反之依然。偷个懒~O(∩_∩)O~

证毕。

这类NP的证明问题其实还是很有难度的,只能说很锻炼脑子,对于它有没有用,这要看你对“useful”的定义了,仁者见仁,智者见智吧。


先来看一个小故事:(转自:http://zhm2k.blog.163.com/blog/static/5981506820095233143571/

假如老板要你解决一个问题,你绞尽脑汁还是想不出来,叫天天不应,叫地地不灵,这时你走进老板办公室,可以采取3种策略:

1)图1:

一副倒霉像,神情猥琐,可怜巴巴的说:老板,我没做出来,我想我是太蠢了……
boss:蠢材!滚!
(失败……)

2)图2:

雄赳赳气昂昂跨进老板办公室,大吼一声:小样,你丫给我问题根本就无解,害我白想这么些天,我靠!
boss:我才靠,自己做不出来就说这个问题无解,要是人人都这样混,我这老板还当个屁阿,滚!
(做不出来还如此气概,不仅失败,而且欠扁……)

3)图3:

从容不迫的说:老板,我做不出来,但是,我敢肯定,那些大牛们也照样做不出来。
boss:原来是这样,那也难为你了。

 

以上三副图虽然是一个笑话,但也可以为我们的生活研究提供一些思路和指导。当你面对一个问题解决不了时,那么就试图去证明别人也解决不了,这的确是一个偷懒逃避的好借口。我觉得P、NP、NP-complete、NP-hard这些名称的出现,就是因为某些难问题,连大牛们都解决不了,无可奈何之下,只好定义一堆东西,为自己找个理由,免得说自己太笨了。其实这是给出一个面对难解问题的解决思路,如果无法得到最优解,那么先去尝试验证哪些解是不是最优解。

 

下面依次介绍

一、计算复杂性

    计算复杂性一般包括时间复杂度和空间复杂度,时间复杂度并不是某算法实际运行需要的时间,而是渐进时间复杂度,即当问题规模趋向于无穷大时,该算法时间复杂度的数量级。常见的时间复杂度,按数量级递增排列依次为:常数阶O(1)、对数阶O(log2n)、线性阶O(n)、线性对数阶O(nlog2n)、平方阶O(n^2)、立方阶O(n^3)、k次方阶O(n^k)、指数阶O(2^n)。这里用大O表示法来表述,给出的是算法的最坏情况的时间代价。

    复杂度关系:c < log2N < n < n * Log2N < n^2 < n^3 < 2^n < 3^n < n!
    其中c是一个常量,如果一个算法的复杂度为c 、 log2N 、n 、 n*log2N ,那么这个算法时间效率比较高,叫做多项式级的复杂度。如果是 2^n , 3^n ,n!,那么稍微大一些的n就会令这个算法不能动了,这些是非多项式级的,其复杂度计算机往往不能承受。当我们在解决一个问题时,我们选择的算法通常都需要是多项式级的复杂度,非多项式级的复杂度需要的时间太多,往往会超时,除非是数据规模非常小。

    空间复杂度是指算法在计算机内执行时所需存储空间的度量。这里不再细讲。

    自然地,人们会想到一个问题:会不会所有的问题都可以找到复杂度为多项式级的算法呢?很遗憾,答案是否定的。有些问题甚至根本不可能找到一个正确的算法来,这称之为“不可解问题”(Undecidable Decision Problem)。

二、P问题(Polynomial Solvable)

定义:那些可以在多项式( polynomial )时间内解决的问题,称为P问题。(或:如果一个问题可以找到一个能在多项式的时间里解决它的算法,那么这个问题就属于P问题。)

时间复杂度如(n^2, n^4,  n(log(n)))都是多项式时间的,指数级别的如(2^n,n^n)这些就不是多项式时间了。
三、NP问题(Non-determinstic Polynomial Solvable)

定义:给定一个解,我们可以在多项式时间内检查他正确与否的决策问题,为NP问题。
比如,我要找一个图的哈密顿路径,随便给我一个解,我都可以在多项式时间内检查它是不是哈密顿路径。只要形如定义的问题,就是NP问题。

之所以要定义NP问题,是因为通常只有NP问题才可能找到多项式的算法。我们不会指望一个连多项式地验证一个解都不行的问题存在一个解决它的多项式级的算法。相信读者很快明白,信息学中的号称最困难的问题——“NP问题”,实际上是在探讨NP问题与P类问题的关系。

很显然,所有的P类问题都是NP问题。也就是说,能多项式地解决一个问题,必然能多项式地验证一个问题的解——既然正解都出来了,验证任意给定的解也只需要比较一下就可以了。关键是,人们想知道,是否所有的NP问题都是P类问题。我们可以再用集合的观点来说明。如果把所有P类问题归为一个集合P中,把所有 NP问题划进另一个集合NP中,那么,显然有P属于NP。现在,所有对NP问题的研究都集中在一个问题上,即究竟是否有P=NP?通常所谓的“NP问题”,其实就一句话:证明或推翻P=NP。

目前为止这个问题还“啃不动”。但是,一个总的趋势、一个大方向是有的。人们普遍认为,P=NP不成立,也就是说,多数人相信,存在至少一个不可能有多项式级复杂度的算法的NP问题。人们如此坚信P≠NP是有原因的,就是在研究NP问题的过程中找出了一类非常特殊的NP问题叫做NP-complete问题,也即所谓的NPC问题。

四、归约

为了说明NPC问题,我们先引入一个概念——约化(Reducibility,有的资料上叫“归约”)。

简单地说,一个问题A可以约化为问题B的含义即是,可以用问题B的解法解决问题A,或者说,问题A可以“变成”问题B。

“问题A可约化为问题B”有一个重要的直观意义:B的时间复杂度高于或者等于A的时间复杂度。也就是说,问题A不比问题B难。这很容易理解。既然问题A能用问题B来解决,倘若B的时间复杂度比A的时间复杂度还低了,那A的算法就可以改进为B的算法,两者的时间复杂度还是相同。

从约化的定义中我们看到,一个问题约化为另一个问题,时间复杂度增加了,问题的应用范围也增大了。通过对某些问题的不断约化,我们能够不断寻找复杂度更高,但应用范围更广的算法来代替复杂度虽然低,但只能用于很小的一类问题的算法。再回想前面讲的P和NP问题,联想起约化的传递性,自然地,我们会想问,如果不断地约化上去,不断找到能“通吃”若干小NP问题的一个稍复杂的大NP问题,那么最后是否有可能找到一个时间复杂度最高,并且能“通吃”所有的 NP问题的这样一个超级NP问题?答案居然是肯定的。也就是说,存在这样一个NP问题,所有的NP问题都可以约化成它。换句话说,只要解决了这个问题,那么所有的NP问题都解决了。这种问题的存在难以置信,并且更加不可思议的是,这种问题不只一个,它有很多个,它是一类问题。这一类问题就是传说中的NPC 问题,也就是NP-完全问题。

五、NP-complete问题

定义:NP-c问题是这样的一类问题,首先他是属于NP的,而且他是NP问题里面最难解决的问题。难到什么程度?只要其中某个问题可以在P时间内解决,那么所有的NP问题就都可以在P时间内解决了。
既然所有的NP问题都能约化成NPC问题,那么只要任意一个NPC问题找到了一个多项式的算法,那么所有的NP问题都能用这个算法解决了,NP也就等于P 了。因此,给NPC找一个多项式算法太不可思议了。

“正是NPC问题的存在,使人们相信P≠NP”。我们可以就此直观地理解,NPC问题目前没有多项式的有效算法,只能用指数级甚至阶乘级复杂度的搜索。

NP-c问题的定义出来了,但是,它忽悠了半天,除了说明这类问题比较难之外,其他啥也没有。我们还是不知道到底什么问题是NP-c问题,如何判定一个问题是不是NP-c问题。
1970年,cook同志发明了cook定理,找到了第一个NP-c问题,SAT(Satisfiability)问题(逻辑电路问题)。他是这么说的,如果SAT问题可以在P时间解决,那么所有的NP问题都可以在P时间内解决。

有了第一个NPC问题后,一大堆NPC问题就出现了,因为再证明一个新的NPC问题只需要将一个已知的NPC问题约化到它就行了。后来,Hamilton 回路成了NPC问题,TSP问题也成了NPC问题,其他还有图染色问题、背包问题等。现在被证明是NPC问题的有很多,任何一个找到了多项式算法的话所有的NP问题都可以完美解决了。因此说,正是因为NPC问题的存在,P=NP变得难以置信。

六、NP-hard问题
定义:NP-hard问题是这样的问题,只要其中某个问题可以在P时间内解决,那么所有的NP问题就都可以在P时间内解决了。NP-c问题就是NP-hard问题。但注意NP-hard问题它不一定是NP问题,比如,下围棋就是NP-hard问题,但不是NP问题,我们要在一个残局上找一个必胜下法,告诉我们下一步下在哪里。显然,我们找不这个解,而且更难的是,就算有人给我了一个解,我们也无法在P时间内判断它是不是正确的。

 

更详细的,以下转自:http://blog.csdn.net/crfoxzl/article/details/2192957

NP问题就是指其解的正确性可以在多项式时间内被检查的一类问题。比如说数组求和,得到一个解,这个解对不对呢,显然是可以在多项式时间内验证的。再比如说SAT,如果得到一个解,也是能在多项式时间内验证正确性的。所以SAT和求和等等都是NP问题。然后呢,有一部分NP问题的解已经可以在多项式时间内找到,比如数组求和,这部分问题就是NP中比较简单的一部分,被命名为P类问题。那么P以外的NP问题,就是目前还不能够在多项式时间内求解的问题了。会不会将来某一天,有大牛发明了牛算法,把这些问题都在多项式时间内解决呢?也就是说,会不会所有的NP问题,其实都是P类问题呢,只是人类尚未发现呢?NP=P吗?

可想而知,证明NP=P的路途是艰难的,因为NP问题实在太多了,要一一找到多项式算法。这时Stephen A. Cook这位大牛出现了,写了一篇The Complexity of Theorem Proving Procedures,提出了一个NP-complete的概念。NPC指的是NP问题中最难的一部分问题,所有的NP问题都能在多项式时间内归约到NPC上。所谓归约是指,若A归约到B,B很容易解决,则A很容易解决。显然,如果有任何一道NPC问题在多项式时间内解决了,那么所有的NP问题就都成了P类问题,NP=P就得到证明了,这极大的简化了证明过程。那么怎样证明一个问题C是NP完全问题呢?首先,要证明C是NP问题,也就是C的解的正确性容易验证;然后要证明有一个NP完全问题B,能够在多项式时间内归约到C。这就要求必须先存在至少一个NPC问题。这时Cook大牛就在1971年证明了NP完全问题的祖先就是SAT。SAT问题是指给定一个包含n个布尔变量的逻辑式,问是否存在一个取值组合,使得该式被满足。Cook证明了SAT是一个NPC问题,如果SAT容易解决,那么所有NP都容易解决。Cook是怎样做到的呢?

他通过非确定性图灵机做到的。非确定性图灵机是一类特殊的图灵机,这种机器很会猜,只要问题有一个解,它就能够在多项式时间内猜到。Cook证明了,SAT总结了该机器在计算过程中必须满足的所有约束条件,任何一个NP问题在这种机器上的计算过程,都可以描述成一个SAT问题。所以,如果你能有一个解决SAT的好算法,你就能够解决非确定性图灵机的计算问题,因为NP问题在非图机上都是多项式解决的,所以你解决了SAT,就能解决所有NP,因此——SAT是一个NP完全问题。感谢Cook,我们已经有了一个NPC问题,剩下的就好办了,用归约来证明就可以了。目前人们已经发现了成千上万的NPC问题,解决一个,NP=P就得证,可以得千年大奖(我认为还能立刻获得图灵奖)。

那么肯定有人要问了,那么NP之外,还有一些连验证解都不能多项式解决的问题呢。这部分问题,就算是NP=P,都不一定能多项式解决,被命名为NP-hard问题。NP-hard太难了,怎样找到一个完美的女朋友就是NP-hard问题。一个NP-hard问题,可以被一个NP完全问题归约到,也就是说,如果有一个NP-hard得到解决,那么所有NP也就都得到解决了。



  • 29
    点赞
  • 98
    收藏
    觉得还不错? 一键收藏
  • 9
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值